Exemplo n.º 1
0
 void Camera::update(GMInput *input, double deltaTime){
     GMVector2D p_pos(SKBaseAreaScene::convertMat2Draw(m_parent->getCharMan()->getPlayer()->getPos())-SCREEN_SIZE/2);
     m_eye.x = p_pos.x;
     m_eye.y = p_pos.y;
     m_tar.x = p_pos.x;
     m_tar.y = p_pos.y;
 }
Exemplo n.º 2
0
 Camera::Camera(SKBaseAreaScene* parent):
 m_parent(parent),
 m_eye(0, 0, 1),
 m_tar(0, 0, 0),
 m_up(0, 1, 0){
     GMVector2D p_pos(SKBaseAreaScene::convertMat2Draw(m_parent->getCharMan()->getPlayer()->getPos())-SCREEN_SIZE/2);
     m_eye.x = p_pos.x;
     m_eye.y = p_pos.y;
     m_tar.x = p_pos.x;
     m_tar.y = p_pos.y;
 }
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
    #include "setRootCase.H"

    #include "createTime.H"
    #include "createMesh.H"
    #include "createFields.H"
    #include "createTimeControls.H"
    #include "createRDeltaT.H"

    turbulence->validate();

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    #include "readFluxScheme.H"

    dimensionedScalar v_zero("v_zero", dimVolume/dimTime, 0.0);

    // Courant numbers used to adjust the time-step
    scalar CoNum = 0.0;
    scalar meanCoNum = 0.0;

    Info<< "\nStarting time loop\n" << endl;

    while (runTime.run())
    {
        // --- Directed interpolation of primitive fields onto faces

        surfaceScalarField rho_pos(interpolate(rho, pos));
        surfaceScalarField rho_neg(interpolate(rho, neg));

        surfaceVectorField rhoU_pos(interpolate(rhoU, pos, U.name()));
        surfaceVectorField rhoU_neg(interpolate(rhoU, neg, U.name()));

        volScalarField rPsi("rPsi", 1.0/psi);
        surfaceScalarField rPsi_pos(interpolate(rPsi, pos, T.name()));
        surfaceScalarField rPsi_neg(interpolate(rPsi, neg, T.name()));

        surfaceScalarField e_pos(interpolate(e, pos, T.name()));
        surfaceScalarField e_neg(interpolate(e, neg, T.name()));

        surfaceVectorField U_pos("U_pos", rhoU_pos/rho_pos);
        surfaceVectorField U_neg("U_neg", rhoU_neg/rho_neg);

        surfaceScalarField p_pos("p_pos", rho_pos*rPsi_pos);
        surfaceScalarField p_neg("p_neg", rho_neg*rPsi_neg);

        surfaceScalarField phiv_pos("phiv_pos", U_pos & mesh.Sf());
        surfaceScalarField phiv_neg("phiv_neg", U_neg & mesh.Sf());

        volScalarField c("c", sqrt(thermo.Cp()/thermo.Cv()*rPsi));
        surfaceScalarField cSf_pos
        (
            "cSf_pos",
            interpolate(c, pos, T.name())*mesh.magSf()
        );
        surfaceScalarField cSf_neg
        (
            "cSf_neg",
            interpolate(c, neg, T.name())*mesh.magSf()
        );

        surfaceScalarField ap
        (
            "ap",
            max(max(phiv_pos + cSf_pos, phiv_neg + cSf_neg), v_zero)
        );
        surfaceScalarField am
        (
            "am",
            min(min(phiv_pos - cSf_pos, phiv_neg - cSf_neg), v_zero)
        );

        surfaceScalarField a_pos("a_pos", ap/(ap - am));

        surfaceScalarField amaxSf("amaxSf", max(mag(am), mag(ap)));

        surfaceScalarField aSf("aSf", am*a_pos);

        if (fluxScheme == "Tadmor")
        {
            aSf = -0.5*amaxSf;
            a_pos = 0.5;
        }

        surfaceScalarField a_neg("a_neg", 1.0 - a_pos);

        phiv_pos *= a_pos;
        phiv_neg *= a_neg;

        surfaceScalarField aphiv_pos("aphiv_pos", phiv_pos - aSf);
        surfaceScalarField aphiv_neg("aphiv_neg", phiv_neg + aSf);

        // Reuse amaxSf for the maximum positive and negative fluxes
        // estimated by the central scheme
        amaxSf = max(mag(aphiv_pos), mag(aphiv_neg));

        #include "centralCourantNo.H"
        #include "readTimeControls.H"

        if (LTS)
        {
            #include "setRDeltaT.H"
        }
        else
        {
            #include "setDeltaT.H"
        }

        runTime++;

        Info<< "Time = " << runTime.timeName() << nl << endl;

        phi = aphiv_pos*rho_pos + aphiv_neg*rho_neg;

        surfaceVectorField phiUp
        (
            (aphiv_pos*rhoU_pos + aphiv_neg*rhoU_neg)
          + (a_pos*p_pos + a_neg*p_neg)*mesh.Sf()
        );

        surfaceScalarField phiEp
        (
            "phiEp",
            aphiv_pos*(rho_pos*(e_pos + 0.5*magSqr(U_pos)) + p_pos)
          + aphiv_neg*(rho_neg*(e_neg + 0.5*magSqr(U_neg)) + p_neg)
          + aSf*p_pos - aSf*p_neg
        );

        volScalarField muEff("muEff", turbulence->muEff());
        volTensorField tauMC("tauMC", muEff*dev2(Foam::T(fvc::grad(U))));

        // --- Solve density
        solve(fvm::ddt(rho) + fvc::div(phi));

        // --- Solve momentum
        solve(fvm::ddt(rhoU) + fvc::div(phiUp));

        U.dimensionedInternalField() =
            rhoU.dimensionedInternalField()
           /rho.dimensionedInternalField();
        U.correctBoundaryConditions();
        rhoU.boundaryField() == rho.boundaryField()*U.boundaryField();

        if (!inviscid)
        {
            solve
            (
                fvm::ddt(rho, U) - fvc::ddt(rho, U)
              - fvm::laplacian(muEff, U)
              - fvc::div(tauMC)
            );
            rhoU = rho*U;
        }

        // --- Solve energy
        surfaceScalarField sigmaDotU
        (
            "sigmaDotU",
            (
                fvc::interpolate(muEff)*mesh.magSf()*fvc::snGrad(U)
              + (mesh.Sf() & fvc::interpolate(tauMC))
            )
            & (a_pos*U_pos + a_neg*U_neg)
        );

        solve
        (
            fvm::ddt(rhoE)
          + fvc::div(phiEp)
          - fvc::div(sigmaDotU)
        );

        e = rhoE/rho - 0.5*magSqr(U);
        e.correctBoundaryConditions();
        thermo.correct();
        rhoE.boundaryField() ==
            rho.boundaryField()*
            (
                e.boundaryField() + 0.5*magSqr(U.boundaryField())
            );

        if (!inviscid)
        {
            solve
            (
                fvm::ddt(rho, e) - fvc::ddt(rho, e)
              - fvm::laplacian(turbulence->alphaEff(), e)
            );
            thermo.correct();
            rhoE = rho*(e + 0.5*magSqr(U));
        }

        p.dimensionedInternalField() =
            rho.dimensionedInternalField()
           /psi.dimensionedInternalField();
        p.correctBoundaryConditions();
        rho.boundaryField() == psi.boundaryField()*p.boundaryField();

        turbulence->correct();

        runTime.write();

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;
    }

    Info<< "End\n" << endl;

    return 0;
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    #include "createTime.H"
    #include "createMesh.H"
    #include "createFields.H"
    #include "readThermophysicalProperties.H"
    #include "readTimeControls.H"
    #include "readLocalEuler.H"

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    #include "readFluxScheme.H"

    dimensionedScalar v_zero("v_zero", dimVolume/dimTime, 0.0);

    Info<< "\nStarting time loop\n" << endl;

    while (runTime.run())
    {
        // --- upwind interpolation of primitive fields on faces

        surfaceScalarField rho_pos
        (
            fvc::interpolate(rho, pos, "reconstruct(rho)")
        );
        surfaceScalarField rho_neg
        (
            fvc::interpolate(rho, neg, "reconstruct(rho)")
        );

        surfaceVectorField rhoU_pos
        (
            fvc::interpolate(rhoU, pos, "reconstruct(U)")
        );
        surfaceVectorField rhoU_neg
        (
            fvc::interpolate(rhoU, neg, "reconstruct(U)")
        );

        volScalarField rPsi(1.0/psi);
        surfaceScalarField rPsi_pos
        (
            fvc::interpolate(rPsi, pos, "reconstruct(T)")
        );
        surfaceScalarField rPsi_neg
        (
            fvc::interpolate(rPsi, neg, "reconstruct(T)")
        );
// tatu start: internal energy e --> sensible enthalpy hs = e + p
/*        surfaceScalarField e_pos
        (
            fvc::interpolate(e, pos, "reconstruct(T)")
        );
        surfaceScalarField e_neg
        (
            fvc::interpolate(e, neg, "reconstruct(T)")
        );*/

        surfaceScalarField hs_pos
        (
            fvc::interpolate(hs, pos, "reconstruct(T)")
        );
        surfaceScalarField hs_neg
        (
            fvc::interpolate(hs, neg, "reconstruct(T)")
        );
// tatu end
        surfaceVectorField U_pos(rhoU_pos/rho_pos);
        surfaceVectorField U_neg(rhoU_neg/rho_neg);

        surfaceScalarField p_pos(rho_pos*rPsi_pos);
        surfaceScalarField p_neg(rho_neg*rPsi_neg);

        surfaceScalarField phiv_pos(U_pos & mesh.Sf());
        surfaceScalarField phiv_neg(U_neg & mesh.Sf());

        //volScalarField c(sqrt(thermo.Cp()/(thermo.Cp()-R)*rPsi));
	volScalarField c(sqrt(thermo.Cp()/(thermo.Cp()-rPsi/T)*rPsi));

	soundSpeed = c;
	Mach = mag(rhoU)/(c*rho);

        surfaceScalarField cSf_pos
        (
            fvc::interpolate(c, pos, "reconstruct(T)")*mesh.magSf()
        );
        surfaceScalarField cSf_neg
        (
            fvc::interpolate(c, neg, "reconstruct(T)")*mesh.magSf()
        );

        surfaceScalarField ap
        (
            max(max(phiv_pos + cSf_pos, phiv_neg + cSf_neg), v_zero)
        );
        surfaceScalarField am
        (
            min(min(phiv_pos - cSf_pos, phiv_neg - cSf_neg), v_zero)
        );

        surfaceScalarField a_pos(ap/(ap - am));

        surfaceScalarField amaxSf("amaxSf", max(mag(am), mag(ap)));

        surfaceScalarField aSf(am*a_pos);

        if (fluxScheme == "Tadmor")
        {
            aSf = -0.5*amaxSf;
            a_pos = 0.5;
        }

        surfaceScalarField a_neg(1.0 - a_pos);

        phiv_pos *= a_pos;
        phiv_neg *= a_neg;

        surfaceScalarField aphiv_pos(phiv_pos - aSf);
        surfaceScalarField aphiv_neg(phiv_neg + aSf);

        // Reuse amaxSf for the maximum positive and negative fluxes
        // estimated by the central scheme
        amaxSf = max(mag(aphiv_pos), mag(aphiv_neg));

        #include "compressibleCourantNo.H"
        #include "readTimeControls.H"
	if (useLocalEuler)
	{
		#include "setrDeltaT.H"
	} 
	else
	{
        	#include "setDeltaT.H"
	}

        runTime++;

        Info<< "Time = " << runTime.timeName() << nl << endl;

        phi = aphiv_pos*rho_pos + aphiv_neg*rho_neg;

        surfaceVectorField phiUp
        (
            (aphiv_pos*rhoU_pos + aphiv_neg*rhoU_neg)
          + (a_pos*p_pos + a_neg*p_neg)*mesh.Sf()
        );
// tatu start: e --> hs (change internal energy to sensible enthalpy, to handle reactions)
        /*surfaceScalarField phiEp
        (
            aphiv_pos*(rho_pos*(e_pos + 0.5*magSqr(U_pos)) + p_pos)
          + aphiv_neg*(rho_neg*(e_neg + 0.5*magSqr(U_neg)) + p_neg)
          + aSf*p_pos - aSf*p_neg
        );*/

	surfaceScalarField phiHp
        (
            aphiv_pos*(rho_pos*(hs_pos + 0.5*magSqr(U_pos))) //+ p_pos)
          + aphiv_neg*(rho_neg*(hs_neg + 0.5*magSqr(U_neg))) //+ p_neg)
          + aSf*p_pos - aSf*p_neg
        );
// tatu end
        volScalarField muEff(turbulence->muEff());
	volScalarField mut(turbulence->mut());
        volTensorField tauMC("tauMC", muEff*dev2(Foam::T(fvc::grad(U))));

        // --- Solve density
        solve(fvm::ddt(rho) + fvc::div(phi));

        // --- Solve momentum
        solve(fvm::ddt(rhoU) + fvc::div(phiUp));

        U.dimensionedInternalField() =
            rhoU.dimensionedInternalField()
           /rho.dimensionedInternalField();
        U.correctBoundaryConditions();
        rhoU.boundaryField() = rho.boundaryField()*U.boundaryField();

        volScalarField rhoBydt(rho/runTime.deltaT());


	
        if (!inviscid)
        {
            //solve
	    tmp<fvVectorMatrix> UEqn
            (
                fvm::ddt(rho, U) - fvc::ddt(rho, U)
              - fvm::laplacian(muEff, U)
              - fvc::div(tauMC)
            );
	    rUA = 1.0/UEqn().A();  // store A matrix for fixedFluxPressure BC
	    solve(UEqn());
            rhoU = rho*U;
        }
// tatu start: add specie transport equation, replace rhoE --> rhoH and e --> hs

	phiHbyA =
        fvc::interpolate(rho)
       *(
            (fvc::interpolate(U) & mesh.Sf()) //*(fvc::interpolate(asd) & mesh.Sf())
        );
	#include "YEqn.H" //nakul

        // --- Solve energy
        surfaceScalarField sigmaDotU
        (
            (
                fvc::interpolate(muEff)*mesh.magSf()*fvc::snGrad(U)
              + (mesh.Sf() & fvc::interpolate(tauMC))
            )
            & (a_pos*U_pos + a_neg*U_neg)
        );

	volScalarField dpdt = fvc::ddt(p);

	volScalarField shPredi = combustion->Sh(); // predictor value for heat of formation
	scalar Prt = 0.85;
        volScalarField alphaEff = muEff/Prt;
        solve
        (
	    fvm::ddt(rhoH)
          + fvc::div(phiHp)
          - fvc::div(sigmaDotU)
	  - dpdt // rhoE = rhoH - p
	  == 
	     shPredi // include enthalpy calculation in the inviscid predictor equation?
	  + fvc::laplacian(alphaEff,p/rho)
        );

        //e = rhoE/rho - 0.5*magSqr(U);
	hs = rhoH/rho - 0.5*magSqr(U);
        hs.correctBoundaryConditions();//e.correctBoundaryConditions();
        thermo.correct();
        rhoH.boundaryField() = // rhoE
            rho.boundaryField()*
            (
                hs.boundaryField() + 0.5*magSqr(U.boundaryField())
            );

	//volScalarField shDiff = combustion->Sh() - shPredi;
        //Info << min(shDiff).value() << " < shDiff < " << max(shDiff).value() << endl;
	//volScalarField TrPsi = T+rPsi;
        if (!inviscid)
        {
            volScalarField k("k", thermo.Cp()*muEff/Prt);//thermo.Cp()*muEff/Pr);
            solve
            (
                fvm::ddt(rho, hs) - fvc::ddt(rho, hs)//fvm::ddt(rho, e) - fvc::ddt(rho, e)
              - fvm::laplacian(alphaEff, hs) // alphaEff = alpha + alphat 
	      //+ fvc::laplacian(turbulence->alphaEff(), hs)  // "remove" the contribution from the inviscid predictor
              //- fvc::laplacian(k, T)   // originally minus sign!
	      //- fvc::laplacian(k, TrPsi)
	      //== combustion->Sh()// - shPredi
            );
            thermo.correct();
            rhoH = rho*(hs + 0.5*magSqr(U));
        }


        p.dimensionedInternalField() =
            rho.dimensionedInternalField()
           /psi.dimensionedInternalField();
        p.correctBoundaryConditions();
        rho.boundaryField() = psi.boundaryField()*p.boundaryField();

        turbulence->correct();

	K = 0.5*magSqr(U);
	h = thermo.Cp()*T + K;
	kPerEpsilon = turbulence->k()/turbulence->epsilon();

        runTime.write();


	Info<< min(rho).value() <<" < rho < " << max(rho).value() << endl; // for debugging
	Info<< min(T).value() <<" < T < " << max(T).value() << endl;	   // for debugging

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;
    }

    Info<< "End\n" << endl;

    return 0;
}
Exemplo n.º 5
0
// cone is pushed along Fiber f into contact with edge p1-p2
bool ConeCutter::generalEdgePush(const Fiber& f, Interval& i,  const Point& p1, const Point& p2) const {
    bool result = false;
    
    if ( isZero_tol(p2.z-p1.z) ) // guard agains horizontal edge
        return result;
    assert( (p2.z-p1.z) != 0.0 );
    // idea: as the ITO-cone slides along the edge it will pierce a z-plane at the height of the fiber
    // the shaped of the pierced area is either a circle if the edge is steep
    // or a 'half-circle' + cone shape if the edge is shallow (ice-cream cone...)
    // we can now intersect this 2D shape with the fiber and get the CL-points.
    // how to get the CC-point? (point on edge closest to z-axis of cutter? closest to CL?)


    
    // this is where the ITO cone pierces the plane
    // edge-line: p1+t*(p2-p1) = zheight
    // => t = (zheight - p1)/ (p2-p1)  
    double t_tip = (f.p1.z - p1.z) / (p2.z-p1.z);
    if (t_tip < 0.0 )
        t_tip = 0.0;
    Point p_tip = p1 + t_tip*(p2-p1);
    assert( isZero_tol( abs(p_tip.z-f.p1.z) ) ); // p_tip should be in plane of fiber
    
    // this is where the ITO cone base exits the plane
    double t_base = (f.p1.z+center_height - p1.z) / (p2.z-p1.z);
    Point p_base = p1 + t_base*(p2-p1);
    p_base.z = f.p1.z; // project to plane of fiber
    //std::cout << "(t0, t1) (" << t0 << " , " << t1 << ") \n";
    double L = (p_base-p_tip).xyNorm(); 
    
    if ( L <= radius ) { // this is where the ITO-slice is a circle
        // find intersection points, if any, between the fiber and the circle
        // fiber is f.p1 - f.p2
        // circle is centered at p_base and radius
        double d = p_base.xyDistanceToLine(f.p1, f.p2);
        if ( d <= radius ) {
            // we know there is an intersection point.
            // http://mathworld.wolfram.com/Circle-LineIntersection.html
            
            // subtract circle center, math is for circle centered at (0,0)
            double dx = f.p2.x - f.p1.x;
            double dy = f.p2.y - f.p1.y;
            double dr = sqrt( square(dx) + square(dy) );
            double det = (f.p1.x-p_base.x) * (f.p2.y-p_base.y) - (f.p2.x-p_base.x) * (f.p1.y-p_base.y);
            
            // intersection given by:
            //  x = det*dy +/- sign(dy) * dx * sqrt( r^2 dr^2 - det^2 )   / dr^2
            //  y = -det*dx +/- abs(dy)  * sqrt( r^2 dr^2 - det^2 )   / dr^2
            
            double discr = square(radius) * square(dr) - square(det);
            assert( discr > 0.0 ); // this means we have an intersection
            if ( discr == 0.0 ) { // tangent case
                double x_tang =  ( det*dy  )/ square(dr);
                double y_tang = -( det*dx  )/ square(dr);
                Point p_tang(x_tang+p_base.x, y_tang+p_base.y); // translate back from (0,0) system!
                double t_tang = f.tval( p_tang );
                if ( circle_CC( t_tang, p1, p2, f, i) )
                    result = true;
            } else {
                // two intersection points
                double x_pos = (  det*dy + sign(dy)* dx * sqrt( discr ) ) / square(dr);
                double y_pos = ( -det*dx + abs(dy)  * sqrt( discr ) ) / square(dr); 
                Point p_pos(x_pos+p_base.x, y_pos+p_base.y);
                double t_pos = f.tval( p_pos );
                // the same with "-" sign:
                double x_neg = (  det*dy - sign(dy) * dx * sqrt( discr ) ) / square(dr);
                double y_neg = ( -det*dx - abs(dy)  * sqrt( discr ) ) / square(dr); 
                Point p_neg(x_neg+p_base.x, y_neg+p_base.y);
                double t_neg = f.tval( p_neg );
                if ( circle_CC( t_pos, p1, p2, f, i) ) 
                    result = true;
                if ( circle_CC( t_neg, p1, p2, f, i) ) 
                    result = true;
            }
        }
        return result;
    } else {
        // ITO-slice is cone + half-circle        
        // lines from p_tip to tangent points
        assert( L > radius );
        // http://mathworld.wolfram.com/CircleTangentLine.html
        // circle centered at x0, y0, radius a
        // tangent through (0,0)
        // t = +/- acos(  -a*x0 +/- y0*sqrt(x0^2+y0^2-a^2) / (x0^2+y0^2) )
        // translate so p_mid is at (0,0)
        //Point c = p_base - p_mid;
        //double cos1 = (-radius*c.x + c.y*sqrt(square(c.x)+square(c.y)+square(radius)) )/ (square(c.x) + square(c.y) );
        //double cos2 = (-radius*c.x - c.y*sqrt(square(c.x)+square(c.y)+square(radius)) )/ (square(c.x) + square(c.y) );
        
        
        return result;
    }
}
Exemplo n.º 6
0
int main(int argc, char *argv[])
{
    #include "setRootCase.H"

    #include "createTime.H"
    #include "createMesh.H"
    #include "createFields.H"
    #include "readThermophysicalProperties.H"
    #include "readTimeControls.H"

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    #include "readFluxScheme.H"

    dimensionedScalar v_zero("v_zero", dimVolume/dimTime, 0.0);

    Info<< "\nStarting time loop\n" << endl;

    while (runTime.run())
    {
        // --- upwind interpolation of primitive fields on faces

        surfaceScalarField rho_pos
        (
            fvc::interpolate(rho, pos, "reconstruct(rho)")
        );
        surfaceScalarField rho_neg
        (
            fvc::interpolate(rho, neg, "reconstruct(rho)")
        );

        surfaceVectorField rhoU_pos
        (
            fvc::interpolate(rhoU, pos, "reconstruct(U)")
        );
        surfaceVectorField rhoU_neg
        (
            fvc::interpolate(rhoU, neg, "reconstruct(U)")
        );

        volScalarField rPsi(1.0/psi);
        surfaceScalarField rPsi_pos
        (
            fvc::interpolate(rPsi, pos, "reconstruct(T)")
        );
        surfaceScalarField rPsi_neg
        (
            fvc::interpolate(rPsi, neg, "reconstruct(T)")
        );

        surfaceScalarField e_pos
        (
            fvc::interpolate(e, pos, "reconstruct(T)")
        );
        surfaceScalarField e_neg
        (
            fvc::interpolate(e, neg, "reconstruct(T)")
        );

        surfaceVectorField U_pos(rhoU_pos/rho_pos);
        surfaceVectorField U_neg(rhoU_neg/rho_neg);

        surfaceScalarField p_pos(rho_pos*rPsi_pos);
        surfaceScalarField p_neg(rho_neg*rPsi_neg);

        surfaceScalarField phiv_pos(U_pos & mesh.Sf());
        surfaceScalarField phiv_neg(U_neg & mesh.Sf());

        volScalarField c(sqrt(thermo.Cp()/thermo.Cv()*rPsi));
        surfaceScalarField cSf_pos
        (
            fvc::interpolate(c, pos, "reconstruct(T)")*mesh.magSf()
        );
        surfaceScalarField cSf_neg
        (
            fvc::interpolate(c, neg, "reconstruct(T)")*mesh.magSf()
        );

        surfaceScalarField ap
        (
            max(max(phiv_pos + cSf_pos, phiv_neg + cSf_neg), v_zero)
        );
        surfaceScalarField am
        (
            min(min(phiv_pos - cSf_pos, phiv_neg - cSf_neg), v_zero)
        );

        surfaceScalarField a_pos(ap/(ap - am));

        surfaceScalarField amaxSf("amaxSf", max(mag(am), mag(ap)));

        surfaceScalarField aSf(am*a_pos);

        if (fluxScheme == "Tadmor")
        {
            aSf = -0.5*amaxSf;
            a_pos = 0.5;
        }

        surfaceScalarField a_neg(1.0 - a_pos);

        phiv_pos *= a_pos;
        phiv_neg *= a_neg;

        surfaceScalarField aphiv_pos(phiv_pos - aSf);
        surfaceScalarField aphiv_neg(phiv_neg + aSf);

        // Reuse amaxSf for the maximum positive and negative fluxes
        // estimated by the central scheme
        amaxSf = max(mag(aphiv_pos), mag(aphiv_neg));

        #include "compressibleCourantNo.H"
        #include "readTimeControls.H"
        #include "setDeltaT.H"

        runTime++;

        Info<< "Time = " << runTime.timeName() << nl << endl;

        phi = aphiv_pos*rho_pos + aphiv_neg*rho_neg;

        surfaceVectorField phiUp
        (
            (aphiv_pos*rhoU_pos + aphiv_neg*rhoU_neg)
          + (a_pos*p_pos + a_neg*p_neg)*mesh.Sf()
        );

        surfaceScalarField phiEp
        (
            aphiv_pos*(rho_pos*(e_pos + 0.5*magSqr(U_pos)) + p_pos)
          + aphiv_neg*(rho_neg*(e_neg + 0.5*magSqr(U_neg)) + p_neg)
          + aSf*p_pos - aSf*p_neg
        );

        volScalarField muEff(turbulence->muEff());
        volTensorField tauMC("tauMC", muEff*dev2(Foam::T(fvc::grad(U))));

        // --- Solve density
        solve(fvm::ddt(rho) + fvc::div(phi));

        // --- Solve momentum
        solve(fvm::ddt(rhoU) + fvc::div(phiUp));

        U.dimensionedInternalField() =
            rhoU.dimensionedInternalField()
           /rho.dimensionedInternalField();
        U.correctBoundaryConditions();
        rhoU.boundaryField() = rho.boundaryField()*U.boundaryField();

        volScalarField rhoBydt(rho/runTime.deltaT());

        if (!inviscid)
        {
            solve
            (
                fvm::ddt(rho, U) - fvc::ddt(rho, U)
              - fvm::laplacian(muEff, U)
              - fvc::div(tauMC)
            );
            rhoU = rho*U;
        }

        // --- Solve energy
        surfaceScalarField sigmaDotU
        (
            (
                fvc::interpolate(muEff)*mesh.magSf()*fvc::snGrad(U)
              + (mesh.Sf() & fvc::interpolate(tauMC))
            )
            & (a_pos*U_pos + a_neg*U_neg)
        );

        solve
        (
            fvm::ddt(rhoE)
          + fvc::div(phiEp)
          - fvc::div(sigmaDotU)
        );

        e = rhoE/rho - 0.5*magSqr(U);
        e.correctBoundaryConditions();
        thermo.correct();
        rhoE.boundaryField() =
            rho.boundaryField()*
            (
                e.boundaryField() + 0.5*magSqr(U.boundaryField())
            );

        if (!inviscid)
        {
            volScalarField k("k", thermo.Cp()*muEff/Pr);
            solve
            (
                fvm::ddt(rho, e) - fvc::ddt(rho, e)
              - fvm::laplacian(turbulence->alphaEff(), e)
              + fvc::laplacian(turbulence->alpha(), e)
              - fvc::laplacian(k, T)
            );
            thermo.correct();
            rhoE = rho*(e + 0.5*magSqr(U));
        }

        p.dimensionedInternalField() =
            rho.dimensionedInternalField()
           /psi.dimensionedInternalField();
        p.correctBoundaryConditions();
        rho.boundaryField() = psi.boundaryField()*p.boundaryField();

        turbulence->correct();

        runTime.write();

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;
    }

    Info<< "End\n" << endl;

    return 0;
}