//-----------------------------------------------------------------------------
// NastNavierStokesParameter.cpp
//-----------------------------------------------------------------------------
//
//  Copyright (C) 1998 Technische Universitaet Muenchen, Germany
//  written by Bernhard Brueck
//
//  This file is part of Nast++
//
//-----------------------------------------------------------------------------
// CNastNavierStokesParameter enthaelt alle Daten ueber das Fluid, die 
// fuer eine Simulation notwenidg sind. Es werden dabei nur diejenigen
// Paramter betrachtet, die fuer alle von CNastNavierStokes2d/CNastNavierStokes3d
// abgeleiten Klassen wichtig sind.
// Die Groessen sind alle dimensionslos. Die Klasse ist auch fuer die 
// Umrechnung von dimensionslosen Groessen in dimensionsbehafte Groessen
// verantwortlich
//-----------------------------------------------------------------------------
//  Changes:
//

#include "NastNavierStokesParameter.h"
#include "NastDebug.h"

//-----------------------------------------------------------------------------
//                    Konstruktor + Destruktor
//-----------------------------------------------------------------------------

//  tau     Sicherheitsfaktor fur Zeitschrittweite
//  gx      Volumenkraefte X-Richtung
//  gy      Volumenkraefte Y-Richtung
//  mu      dynamische Viskositaet
//  L       Vergroesserungsfaktor der Geometrie
//  refU    Referenzgeschwindigkeit
//  refP    Referenzdruck
//  refRho  Referenzdichte

CNastNavierStokesParameter::CNastNavierStokesParameter( double gx,
        						double gy,
        						double mu,
        						double L,
        						double refU,
        						double refP,
        						double refRho )
    :m_L(L),
     m_refU(refU),
     m_refP(refP),
     m_refRho(refRho),
     m_prandtl(0)
{
    NAST_ASSERT( L > 0 );
    NAST_ASSERT( refU > 0 );
    NAST_ASSERT( refP > 0 );
    NAST_ASSERT( refRho > 0 );
    
    // Reynoldszahl berechnen
    m_reynolds = (refRho * refU * L) / mu;

    m_gx = convertRealToSimVolForce( gx );
    m_gy = convertRealToSimVolForce( gy );

    NAST_ASSERT_WARNING( false, "Der Code ist nicht getestet");
    NAST_DUMP_VARIABLE( this );
}

CNastNavierStokesParameter::CNastNavierStokesParameter(double gx,
        					       double gy,
        					       double Reynolds )
    :m_gx(gx),
     m_gy(gy),
     m_reynolds(Reynolds),
     m_refU(1),
     m_refP(1),
     m_refRho(1)
{
    // momentan wird nur gx,gy und die Reynoldszahl benutzt
}

//  Destruktor
CNastNavierStokesParameter::~CNastNavierStokesParameter()
{
    NAST_ASSERT_VALID( this );
}


// ----------------------------------------------------------------------------
//                            Memberfunktionen
// ----------------------------------------------------------------------------


double CNastNavierStokesParameter::prandtl() const
{
    NAST_ASSERT_VALID(this);
    return m_prandtl;
}

//-------------------------------------------------------------------------    
//                             Umrechung  
//-------------------------------------------------------------------------
// Umrechnungen zwischen den dimensionslosen und den dimensionsbehafteten
// Groessen.
//
//-------------------------------------------------------------------------
//                           sim -> real
//-------------------------------------------------------------------------

// dimensionslos t   -> dimensionbehaftet t
double 
CNastNavierStokesParameter::convertSimToRealTime( double t ) const
{
    NAST_ASSERT_VALID(this);
    return t * (m_L / m_refU);
}

// dimensionslos x   -> dimensionbehaftet x
double 
CNastNavierStokesParameter::convertSimToRealGeometry( double x ) const
{
    NAST_ASSERT_VALID(this);
    return x * m_L;    
}

// dimensionslos P   -> dimensionbehaftet P
double 
CNastNavierStokesParameter::convertSimToRealPressure( double p ) const
{
    NAST_ASSERT_VALID(this);
    return p * m_refRho * m_refU * m_refU - m_refP;
}

// dimensionslos u,v -> dimensionbehaftet u,v
double 
CNastNavierStokesParameter::convertSimToRealVelocity( double v ) const
{
    NAST_ASSERT_VALID(this);
    return v * m_L;
}

//  dimensionslos u,v -> dimensionbehaftet u,v
CNastVector2d 
CNastNavierStokesParameter::convertSimToRealVelocity( CNastVector2d &vec) const
{
    NAST_ASSERT_VALID(this);
    return m_L * vec;
}

// dimensionslos g   -> dimensionbehaftet g
double 
CNastNavierStokesParameter::convertSimToRealVolForce( double g ) const
{
    NAST_ASSERT_VALID(this);
    return g * ((m_refU * m_refU) / m_L);    
}

//-------------------------------------------------------------------------
//                             real -> sim
//-------------------------------------------------------------------------
//

// dimensionbehaftet t   -> dimensionslos t
double CNastNavierStokesParameter::convertRealToSimTime( double t ) const
{
    NAST_ASSERT_VALID(this);
    return t * (m_refU / m_L);
}

// dimensionbehaftet x   -> dimensionslos x
 double 
CNastNavierStokesParameter::convertRealToSimGeometry( double x ) const
{
    NAST_ASSERT_VALID(this);
    return x / m_L;
}

// dimensionbehaftet P   -> dimensionslos P
double 
CNastNavierStokesParameter::convertRealToSimPressure( double p ) const
{
    NAST_ASSERT_VALID(this);
    return (p - m_refP) / (m_refRho * m_refU * m_refU);
}

// dimensionbehaftet u,v -> dimensionslos u,v
double 
CNastNavierStokesParameter::convertRealToSimVelocity( double v ) const
{
    NAST_ASSERT_VALID(this);
    return v / m_L;
}

// dimensionbehaftet u,v -> dimensionslos u,v
CNastVector2d 
CNastNavierStokesParameter::convertRealToSimVelocity( CNastVector2d &vec ) const
{
    NAST_ASSERT_VALID(this);
    return vec / m_L;
}

// dimensionbehaftet g   -> dimensionslos g
double 
CNastNavierStokesParameter::convertRealToSimVolForce( double g ) const
{
    NAST_ASSERT_VALID(this);
    return g * (m_L / (m_refU * m_refU));
}

// ----------------------------------------------------------------------------
//                                    Debug
// ----------------------------------------------------------------------------
void 
CNastNavierStokesParameter::debugDump( CNastDumpContext &dumpContext ) const
{
    CNastObject::debugDump( dumpContext );
    dumpContext << "CNastNavierStokesParameter"   << "\n";
    dumpContext << "\tm_L       = " << m_L        << "\n";
    dumpContext << "\tm_refU    = " << m_refU     << "\n";
    dumpContext << "\tm_refP    = " << m_refP     << "\n";
    dumpContext << "\tm_refRho  = " << m_refRho   << "\n";
    dumpContext << "\tm_reynolds= " << m_reynolds << "\n";
    dumpContext << "\tm_gx      = " << m_gx       << "\n";
    dumpContext << "\tm_gy      = " << m_gy       << "\n";
    dumpContext << "\tm_prandtl = " << m_prandtl  << "\n";
}

void 
CNastNavierStokesParameter::assertValid() const
{
    // zuerst einmal AssertValid der Basisklasse aufrufen
    CNastObject::assertValid(); 
    NAST_ASSERT( m_reynolds> 0 );
    NAST_ASSERT( m_refU    > 0);
    NAST_ASSERT( m_refP    > 0);    
    NAST_ASSERT( m_refRho  > 0);
}


