void lowReOneEqEddy::correct(const tmp<volTensorField>& tgradU) { const volTensorField& gradU = tgradU(); GenEddyVisc::correct(gradU); volScalarField divU(fvc::div(phi()/fvc::interpolate(rho()))); volScalarField G(2*muSgs_*(gradU && dev(symm(gradU)))); tmp<fvScalarMatrix> kEqn ( fvm::ddt(rho(), k_) + fvm::div(phi(), k_) - fvm::laplacian(DkEff(), k_) == G - fvm::SuSp(2.0/3.0*rho()*divU, k_) - fvm::Sp(ce_*rho()*sqrt(k_)/delta(), k_) ); kEqn().relax(); kEqn().solve(); bound(k_, kMin_); updateSubGridScaleFields(); }
void dynamicKEqn<BasicTurbulenceModel>::correct() { if (!this->turbulence_) { return; } // Local references const alphaField& alpha = this->alpha_; const rhoField& rho = this->rho_; const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_; const volVectorField& U = this->U_; volScalarField& nut = this->nut_; fv::options& fvOptions(fv::options::New(this->mesh_)); LESeddyViscosity<BasicTurbulenceModel>::correct(); volScalarField divU(fvc::div(fvc::absolute(this->phi(), U))); tmp<volTensorField> tgradU(fvc::grad(U)); const volSymmTensorField D(dev(symm(tgradU()))); const volScalarField G(this->GName(), 2.0*nut*(tgradU() && D)); tgradU.clear(); volScalarField KK(0.5*(filter_(magSqr(U)) - magSqr(filter_(U)))); KK.max(dimensionedScalar("small", KK.dimensions(), SMALL)); tmp<fvScalarMatrix> kEqn ( fvm::ddt(alpha, rho, k_) + fvm::div(alphaRhoPhi, k_) - fvm::laplacian(alpha*rho*DkEff(), k_) == alpha*rho*G - fvm::SuSp((2.0/3.0)*alpha*rho*divU, k_) - fvm::Sp(Ce(D, KK)*alpha*rho*sqrt(k_)/this->delta(), k_) + kSource() + fvOptions(alpha, rho, k_) ); kEqn.ref().relax(); fvOptions.constrain(kEqn.ref()); solve(kEqn); fvOptions.correct(k_); bound(k_, this->kMin_); correctNut(D, KK); }
void tatunRNG::correct() { if (!turbulence_) { // Re-calculate viscosity mut_ = rho_*Cmu_*sqr(k_)/epsilon_; mut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity alphat_ = mut_/Prt_; alphat_.correctBoundaryConditions(); return; } RASModel::correct(); volScalarField divU(fvc::div(phi_/fvc::interpolate(rho_))); if (mesh_.moving()) { divU += fvc::div(mesh_.phi()); } tmp<volTensorField> tgradU = fvc::grad(U_); volScalarField S2((tgradU() && dev(twoSymm(tgradU())))); tgradU.clear(); //volScalarField G(type() + ".G", mut_*S2); volScalarField G(GName(), mut_*S2); // changed from 2.1.1 --> 2.2.2 volScalarField eta(sqrt(mag(S2))*k_/epsilon_); volScalarField eta3(eta*sqr(eta)); volScalarField R ( ((eta*(-eta/eta0_ + scalar(1)))/(beta_*eta3 + scalar(1))) ); // Update epsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( fvm::ddt(rho_, epsilon_) + fvm::div(phi_, epsilon_) - fvm::laplacian(DepsilonEff(), epsilon_) == (C1_ - R)*G*epsilon_/k_ - fvm::SuSp(((2.0/3.0)*C1_ + C3_)*rho_*divU, epsilon_) - fvm::Sp(C2_*rho_*epsilon_/k_, epsilon_) ); epsEqn().relax(); epsEqn().boundaryManipulate(epsilon_.boundaryField()); solve(epsEqn); bound(epsilon_, epsilonMin_); volScalarField YMperk = 2.0*rho_*epsilon_/(soundSpeed_*soundSpeed_); // Turbulent kinetic energy equation tmp<fvScalarMatrix> kEqn ( fvm::ddt(rho_, k_) + fvm::div(phi_, k_) - fvm::laplacian(DkEff(), k_) == G - fvm::SuSp(2.0/3.0*rho_*divU, k_) - fvm::Sp(rho_*epsilon_/k_, k_) - fvm::Sp(YMperk, k_) ); kEqn().relax(); solve(kEqn); bound(k_, kMin_); // Re-calculate viscosity mut_ = rho_*Cmu_*sqr(k_)/epsilon_; mut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity alphat_ = mut_/Prt_; alphat_.correctBoundaryConditions(); }
int main(int argc, char *argv[]) { #include "postProcess.H" #include "setRootCase.H" #include "createTime.H" #include "createDynamicFvMesh.H" #include "initContinuityErrs.H" #include "createControl.H" #include "createFields.H" #include "createUf.H" #include "createControls.H" #include "CourantNo.H" #include "setInitialDeltaT.H" volScalarField& p = mixture.p(); volScalarField& T = mixture.T(); const volScalarField& psi1 = mixture.thermo1().psi(); const volScalarField& psi2 = mixture.thermo2().psi(); turbulence->validate(); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.run()) { #include "readControls.H" { // Store divU from the previous mesh so that it can be mapped // and used in correctPhi to ensure the corrected phi has the // same divergence volScalarField divU("divU0", fvc::div(fvc::absolute(phi, U))); #include "CourantNo.H" #include "setDeltaT.H" runTime++; Info<< "Time = " << runTime.timeName() << nl << endl; scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime(); // Do any mesh changes mesh.update(); if (mesh.changing()) { Info<< "Execution time for mesh.update() = " << runTime.elapsedCpuTime() - timeBeforeMeshUpdate << " s" << endl; gh = (g & mesh.C()) - ghRef; ghf = (g & mesh.Cf()) - ghRef; } if (mesh.changing() && correctPhi) { // Calculate absolute flux from the mapped surface velocity phi = mesh.Sf() & Uf; #include "correctPhi.H" // Make the fluxes relative to the mesh motion fvc::makeRelative(phi, U); } } if (mesh.changing() && checkMeshCourantNo) { #include "meshCourantNo.H" } turbulence->correct(); // --- Pressure-velocity PIMPLE corrector loop while (pimple.loop()) { #include "alphaEqnsSubCycle.H" // correct interface on first PIMPLE corrector if (pimple.corr() == 1) { interface.correct(); } solve(fvm::ddt(rho) + fvc::div(rhoPhi)); #include "UEqn.H" #include "TEqn.H" // --- Pressure corrector loop while (pimple.correct()) { #include "pEqn.H" } } rho = alpha1*rho1 + alpha2*rho2; // Correct p_rgh for consistency with p and the updated densities p_rgh = p - rho*gh; p_rgh.correctBoundaryConditions(); runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s\n\n" << endl; } Info<< "End\n" << endl; return 0; }
void PDRkEpsilon::correct() { if (!turbulence_) { // Re-calculate viscosity nut_ = Cmu_*sqr(k_)/epsilon_; nut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity //***HGWalphat_ = mut_/Prt_; // alphat_.correctBoundaryConditions(); return; } RASModel::correct(); volScalarField divU(fvc::div(phi_/fvc::interpolate(rho_))); if (mesh_.moving()) { divU += fvc::div(mesh_.phi()); } tmp<volTensorField> tgradU = fvc::grad(U_); volScalarField G(GName(), rho_*nut_*(tgradU() && dev(twoSymm(tgradU())))); tgradU.clear(); // Update espsilon and G at the wall epsilon_.boundaryFieldRef().updateCoeffs(); // Add the blockage generation term so that it is included consistently // in both the k and epsilon equations const volScalarField& betav = U_.db().lookupObject<volScalarField>("betav"); const volScalarField& Lobs = U_.db().lookupObject<volScalarField>("Lobs"); const PDRDragModel& drag = U_.db().lookupObject<PDRDragModel>("PDRDragModel"); volScalarField GR(drag.Gk()); volScalarField LI (C4_*(Lobs + dimensionedScalar(dimLength, rootVSmall))); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( betav*fvm::ddt(rho_, epsilon_) + fvm::div(phi_, epsilon_) - fvm::laplacian(rho_*DepsilonEff(), epsilon_) == C1_*betav*G*epsilon_/k_ + 1.5*pow(Cmu_, 3.0/4.0)*GR*sqrt(k_)/LI - fvm::SuSp(((2.0/3.0)*C1_)*betav*rho_*divU, epsilon_) - fvm::Sp(C2_*betav*rho_*epsilon_/k_, epsilon_) ); epsEqn.ref().relax(); epsEqn.ref().boundaryManipulate(epsilon_.boundaryFieldRef()); solve(epsEqn); bound(epsilon_, epsilonMin_); // Turbulent kinetic energy equation tmp<fvScalarMatrix> kEqn ( betav*fvm::ddt(rho_, k_) + fvm::div(phi_, k_) - fvm::laplacian(rho_*DkEff(), k_) == betav*G + GR - fvm::SuSp((2.0/3.0)*betav*rho_*divU, k_) - fvm::Sp(betav*rho_*epsilon_/k_, k_) ); kEqn.ref().relax(); solve(kEqn); bound(k_, kMin_); // Re-calculate viscosity nut_ = Cmu_*sqr(k_)/epsilon_; nut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity //***HGWalphat_ = mut_/Prt_; // alphat_.correctBoundaryConditions(); }
void RNGkEpsilon<BasicTurbulenceModel>::correct() { if (!this->turbulence_) { return; } // Local references const alphaField& alpha = this->alpha_; const rhoField& rho = this->rho_; const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_; const volVectorField& U = this->U_; volScalarField& nut = this->nut_; eddyViscosity<RASModel<BasicTurbulenceModel> >::correct(); volScalarField divU(fvc::div(fvc::absolute(this->phi(), U))); tmp<volTensorField> tgradU = fvc::grad(U); volScalarField S2((tgradU() && dev(twoSymm(tgradU())))); tgradU.clear(); volScalarField G(this->GName(), nut*S2); volScalarField eta(sqrt(mag(S2))*k_/epsilon_); volScalarField eta3(eta*sqr(eta)); volScalarField R ( ((eta*(-eta/eta0_ + scalar(1)))/(beta_*eta3 + scalar(1))) ); // Update epsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( fvm::ddt(alpha, rho, epsilon_) + fvm::div(alphaRhoPhi, epsilon_) - fvm::laplacian(alpha*rho*DepsilonEff(), epsilon_) == (C1_ - R)*alpha*rho*G*epsilon_/k_ - fvm::SuSp(((2.0/3.0)*C1_ + C3_)*alpha*rho*divU, epsilon_) - fvm::Sp(C2_*alpha*rho*epsilon_/k_, epsilon_) + epsilonSource() ); epsEqn().relax(); epsEqn().boundaryManipulate(epsilon_.boundaryField()); solve(epsEqn); bound(epsilon_, this->epsilonMin_); // Turbulent kinetic energy equation tmp<fvScalarMatrix> kEqn ( fvm::ddt(alpha, rho, k_) + fvm::div(alphaRhoPhi, k_) - fvm::laplacian(alpha*rho*DkEff(), k_) == alpha*rho*G - fvm::SuSp((2.0/3.0)*alpha*rho*divU, k_) - fvm::Sp(alpha*rho*epsilon_/k_, k_) + kSource() ); kEqn().relax(); solve(kEqn); bound(k_, this->kMin_); correctNut(); }
//------------------------------------------------------------------------------ int main( int argc, char * argv[] ) { //-------------------------------------------------------------------------- const unsigned geomDeg = 1; const unsigned dim = 2; // degrees of lowest-order TH element const unsigned fieldDegU = 2; const unsigned fieldDegP = 1; const unsigned tiOrder = 1; typedef base::time::BDF<tiOrder> MSM; const base::Shape shape = base::SimplexShape<dim>::value; const base::Shape surfShape = base::SimplexShape<dim-1>::value; //-------------------------------------------------------------------------- if ( argc != 2 ) { std::cout << "Usage: " << argv[0] << " input.dat \n\n"; return -1; } const std::string inputFile = boost::lexical_cast<std::string>( argv[1] ); //-------------------------------------------------------------------------- std::string meshFile, surfFile; double viscosity, density, tolerance, penaltyFactor, stepSize; unsigned maxIter, numSteps; { //Feed properties parser with the variables to be read base::io::PropertiesParser prop; prop.registerPropertiesVar( "meshFile", meshFile ); prop.registerPropertiesVar( "surfFile", surfFile ); prop.registerPropertiesVar( "viscosity", viscosity ); prop.registerPropertiesVar( "density", density ); prop.registerPropertiesVar( "maxIter", maxIter ); prop.registerPropertiesVar( "tolerance", tolerance ); prop.registerPropertiesVar( "penaltyFactor", penaltyFactor ); prop.registerPropertiesVar( "stepSize", stepSize ); prop.registerPropertiesVar( "numSteps", numSteps ); // Read variables from the input file std::ifstream inp( inputFile.c_str() ); VERIFY_MSG( inp.is_open(), "Cannot open input file" ); prop.readValues( inp ); inp.close( ); // Make sure all variables have been found if ( not prop.isEverythingRead() ) { prop.writeUnread( std::cerr ); VERIFY_MSG( false, "Could not find above variables" ); } } const std::string baseName = base::io::baseName( meshFile, ".smf" ); //-------------------------------------------------------------------------- typedef base::Unstructured<shape,geomDeg> Mesh; Mesh mesh; { std::ifstream smf( meshFile.c_str() ); VERIFY_MSG( smf.is_open(), "Cannot open mesh file" ); base::io::smf::readMesh( smf, mesh ); smf.close(); } //-------------------------------------------------------------------------- // Surface mesh typedef base::Unstructured<surfShape,1,dim> SurfMesh; SurfMesh surfMesh; { std::ifstream smf( surfFile.c_str() ); base::io::smf::readMesh( smf, surfMesh ); smf.close(); } //-------------------------------------------------------------------------- // Compute the level set data typedef base::cut::LevelSet<dim> LevelSet; std::vector<LevelSet> levelSet; const bool isSigned = true; base::cut::bruteForce( mesh, surfMesh, isSigned, levelSet ); const unsigned kernelDegEstimate = 5; //-------------------------------------------------------------------------- // Make cut cell structure typedef base::cut::Cell<shape> Cell; std::vector<Cell> cells; base::cut::generateCutCells( mesh, levelSet, cells ); // Quadrature typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature; CutQuadrature quadrature( cells, true ); // for surface typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature; SurfaceQuadrature surfaceQuadrature; //------------------------------------------------------------------------------ // Finite element bases const unsigned nHist = MSM::numSteps; const unsigned doFSizeU = dim; typedef base::fe::Basis<shape,fieldDegU> FEBasisU; typedef base::cut::ScaledField<FEBasisU,doFSizeU,nHist> Velocity; Velocity velocity; base::dof::generate<FEBasisU>( mesh, velocity ); const unsigned doFSizeP = 1; typedef base::fe::Basis<shape,fieldDegP> FEBasisP; typedef base::cut::ScaledField<FEBasisP,doFSizeP,nHist> Pressure; Pressure pressure; base::dof::generate<FEBasisP>( mesh, pressure ); const unsigned doFSizeS = dim; typedef base::fe::Basis<surfShape,1> FEBasisS; typedef base::Field<FEBasisS,doFSizeS> SurfField; SurfField surfVelocity, surfForces; base::dof::generate<FEBasisS>( surfMesh, surfVelocity ); base::dof::generate<FEBasisS>( surfMesh, surfForces ); // set initial condition to the identity base::dof::setField( surfMesh, surfVelocity, boost::bind( &surfaceVelocity<dim, SurfField::DegreeOfFreedom>, _1, _2 ) ); // boundary datum base::cut::TransferSurfaceDatum<SurfMesh,SurfField,Mesh::Element> s2d( surfMesh, surfVelocity, levelSet ); //-------------------------------------------------------------------------- // surface mesh typedef base::mesh::BoundaryMeshBinder<Mesh>::Type BoundaryMesh; BoundaryMesh boundaryMesh, immersedMesh; // from boundary { // identify list of element boundary faces base::mesh::MeshBoundary meshBoundary; meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() ); // generate a mesh from that list (with a filter) base::mesh::generateBoundaryMesh( meshBoundary.begin(), meshBoundary.end(), mesh, boundaryMesh, boost::bind( &boundaryFilter<dim>, _1 ) ); // make a surface mesh from the implicit surface base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, immersedMesh ); } // the composite field with geometry, velocity and pressure typedef base::asmb::FieldBinder<Mesh,Velocity,Pressure> Field; Field field( mesh, velocity, pressure ); // define the system blocks (U,U), (U,P), and (P,U) typedef Field::TupleBinder<1,1,1>::Type TopLeft; typedef Field::TupleBinder<1,2>::Type TopRight; typedef Field::TupleBinder<2,1>::Type BotLeft; std::vector<double> supportsU, supportsP; std::size_t numDoFsU = std::distance( velocity.doFsBegin(), velocity.doFsEnd() ); supportsU.resize( numDoFsU ); std::size_t numDoFsP = std::distance( pressure.doFsBegin(), pressure.doFsEnd() ); supportsP.resize( numDoFsP ); base::cut::supportComputation( mesh, velocity, quadrature, supportsU ); base::cut::supportComputation( mesh, pressure, quadrature, supportsP ); velocity.scaleAndTagBasis( supportsU, 1.e-8 ); pressure.scaleAndTagBasis( supportsP, 1.e-8 ); //velocity.tagBasis( supportsU, 1.e-8 ); //pressure.tagBasis( supportsP, 1.e-8 ); // Fix one pressure dof // Pressure::DoFPtrIter pIter = pressure.doFsBegin(); // std::advance( pIter, std::distance( pressure.doFsBegin(), pressure.doFsEnd() )/5 ); // (*pIter) -> constrainValue( 0, 0.0 ); // Number of DoFs after constraint application! numDoFsU = base::dof::numberDoFsConsecutively( velocity.doFsBegin(), velocity.doFsEnd() ); std::cout << "# Number of velocity dofs " << numDoFsU << std::endl; numDoFsP = base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(), numDoFsU ); std::cout << "# Number of pressure dofs " << numDoFsP << std::endl; // kernels typedef fluid::StressDivergence< TopLeft::Tuple> StressDivergence; typedef fluid::Convection< TopLeft::Tuple> Convection; typedef fluid::PressureGradient< TopRight::Tuple> GradP; typedef fluid::VelocityDivergence<BotLeft::Tuple> DivU; StressDivergence stressDivergence( viscosity ); Convection convection( density ); GradP gradP; DivU divU( true ); // for surface fields typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Velocity,Pressure> SurfaceFieldBinder; typedef SurfaceFieldBinder::TupleBinder<1,1,1>::Type STBUU; typedef SurfaceFieldBinder::TupleBinder<1,2 >::Type STBUP; SurfaceFieldBinder boundaryFieldBinder( boundaryMesh, velocity, pressure ); SurfaceFieldBinder immersedFieldBinder( immersedMesh, velocity, pressure ); std::ofstream forces( "forces.dat" ); for ( unsigned step = 0; step < numSteps; step++ ) { const double time = step * stepSize; const double factor = ( time < 1.0 ? time : 1.0 ); std::cout << step << ": time=" << time << ", factor=" << factor << "\n"; //base::dof::clearDoFs( velocity ); //base::dof::clearDoFs( pressure ); //-------------------------------------------------------------------------- // Nonlinear iterations unsigned iter = 0; while( iter < maxIter ) { // Create a solver object typedef base::solver::Eigen3 Solver; Solver solver( numDoFsU + numDoFsP ); std::cout << "* Iteration " << iter << std::flush; // compute inertia terms, d/dt, due to time integration base::time::computeInertiaTerms<TopLeft,MSM>( quadrature, solver, field, stepSize, step, density ); // Compute system matrix base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver, field, stressDivergence ); base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver, field, convection ); base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver, field, gradP ); base::asmb::stiffnessMatrixComputation<BotLeft>( quadrature, solver, field, divU ); // compute residual forces base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field, stressDivergence ); base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field, convection ); base::asmb::computeResidualForces<TopRight>( quadrature, solver, field, gradP ); base::asmb::computeResidualForces<BotLeft >( quadrature, solver, field, divU ); // Parameter classes base::nitsche::OuterBoundary ob( viscosity ); base::nitsche::ImmersedBoundary<Cell> ib( viscosity, cells ); // Penalty method base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver, boundaryFieldBinder, ob, penaltyFactor ); base::nitsche::penaltyRHS<STBUU>( surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1, factor), ob, penaltyFactor ); base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver, immersedFieldBinder, ib, penaltyFactor ); base::nitsche::penaltyRHS2<STBUU>( surfaceQuadrature, solver, immersedFieldBinder, s2d, ib, penaltyFactor ); // Nitsche terms base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::energyRHS<STBUU>( stressDivergence, surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1, factor), ob ); base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::energyRHS<STBUP>( gradP, surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1, factor), ob ); base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver, boundaryFieldBinder, ob ); base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver, immersedFieldBinder, ib ); base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver, immersedFieldBinder, ib ); base::nitsche::energyRHS2<STBUU>( stressDivergence, surfaceQuadrature, solver, immersedFieldBinder, s2d, ib ); base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver, immersedFieldBinder, ib ); base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver, immersedFieldBinder, ib ); base::nitsche::energyRHS2<STBUP>( gradP, surfaceQuadrature, solver, immersedFieldBinder, s2d, ib ); base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver, immersedFieldBinder, ib ); base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver, immersedFieldBinder, ib ); // Finalise assembly solver.finishAssembly(); // check convergence via solver norms const double residualNorm = solver.norm(); std::cout << " |R| = " << residualNorm << std::flush; if ( residualNorm < tolerance * viscosity) { std::cout << std::endl; break; } // Solve solver.superLUSolve(); // distribute results back to dofs base::dof::addToDoFsFromSolver( solver, velocity ); base::dof::addToDoFsFromSolver( solver, pressure ); //base::dof::setDoFsFromSolver( solver, pressure ); // check convergence via solver norms const double incrementNorm = solver.norm(0, numDoFsU ); std::cout << " |dU| = " << incrementNorm << std::endl; // push history base::dof::pushHistory( velocity ); base::dof::pushHistory( pressure ); if ( incrementNorm < tolerance ) break; iter++; } writeVTKFile( baseName, step, mesh, velocity, pressure, levelSet, viscosity ); { base::Vector<dim>::Type sumOfForces = base::constantVector<dim>( 0. ); typedef Field::TupleBinder<1,2>::Type UP; //typedef fluid::Stress<UP::Tuple> Stress; //Stress stress( viscosity ); typedef fluid::Traction<UP::Tuple> Traction; Traction traction( viscosity ); base::cut::ComputeSurfaceForces<SurfMesh,SurfField, SurfaceQuadrature,STBUP::Tuple,Traction> computeSurfaceForces( surfMesh, surfForces, surfaceQuadrature, levelSet, traction ); SurfaceFieldBinder::FieldIterator first = immersedFieldBinder.elementsBegin(); SurfaceFieldBinder::FieldIterator last = immersedFieldBinder.elementsEnd(); for ( ; first != last; ++first ) { sumOfForces += computeSurfaceForces( STBUP::makeTuple( *first ) ); } writeSurfaceVTKFile( baseName, step, surfMesh, surfVelocity, surfForces ); std::cout << " F= " << sumOfForces.transpose() << " \n"; forces << time << " " << sumOfForces.transpose() << std::endl;; } } forces.close(); return 0; }
void kEpsilon::correct() { if (!turbulence_) { // Re-calculate viscosity mut_ = rho_*Cmu_*sqr(k_)/epsilon_; mut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity alphat_ = mut_/Prt_; alphat_.correctBoundaryConditions(); return; } RASModel::correct(); volScalarField divU(fvc::div(phi_/fvc::interpolate(rho_))); if (mesh_.moving()) { divU += fvc::div(mesh_.phi()); } tmp<volTensorField> tgradU = fvc::grad(U_); volScalarField G(GName(), mut_*(tgradU() && dev(twoSymm(tgradU())))); tgradU.clear(); // Update epsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( fvm::ddt(rho_, epsilon_) + fvm::div(phi_, epsilon_) - fvm::laplacian(DepsilonEff(), epsilon_) == C1_*G*epsilon_/k_ - fvm::SuSp(((2.0/3.0)*C1_ + C3_)*rho_*divU, epsilon_) - fvm::Sp(C2_*rho_*epsilon_/k_, epsilon_) ); epsEqn().relax(); epsEqn().boundaryManipulate(epsilon_.boundaryField()); solve(epsEqn); bound(epsilon_, epsilonMin_); // Turbulent kinetic energy equation tmp<fvScalarMatrix> kEqn ( fvm::ddt(rho_, k_) + fvm::div(phi_, k_) - fvm::laplacian(DkEff(), k_) == G - fvm::SuSp((2.0/3.0)*rho_*divU, k_) - fvm::Sp(rho_*epsilon_/k_, k_) ); kEqn().relax(); solve(kEqn); bound(k_, kMin_); // Re-calculate viscosity mut_ = rho_*Cmu_*sqr(k_)/epsilon_; mut_.correctBoundaryConditions(); // Re-calculate thermal diffusivity alphat_ = mut_/Prt_; alphat_.correctBoundaryConditions(); }
int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createDynamicFvMesh.H" pimpleControl pimple(mesh); #include "../interFoam/interDyMFoam/createControls.H" #include "initContinuityErrs.H" #include "createFields.H" #include "createFvOptions.H" volScalarField rAU ( IOobject ( "rAU", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, dimensionedScalar("rAUf", dimTime/rho.dimensions(), 1.0) ); #include "createUf.H" #include "CourantNo.H" #include "setInitialDeltaT.H" turbulence->validate(); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.run()) { #include "../interFoam/interDyMFoam/readControls.H" // Store divU from the previous mesh so that it can be mapped // and used in correctPhi to ensure the corrected phi has the // same divergence volScalarField divU("divU0", fvc::div(fvc::absolute(phi, U))); #include "CourantNo.H" #include "setDeltaT.H" runTime++; Info<< "Time = " << runTime.timeName() << nl << endl; // --- Pressure-velocity PIMPLE corrector loop while (pimple.loop()) { if (pimple.firstIter() || moveMeshOuterCorrectors) { scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime(); mesh.update(); if (mesh.changing()) { Info<< "Execution time for mesh.update() = " << runTime.elapsedCpuTime() - timeBeforeMeshUpdate << " s" << endl; gh = (g & mesh.C()) - ghRef; ghf = (g & mesh.Cf()) - ghRef; } if (mesh.changing() && correctPhi) { // Calculate absolute flux from the mapped surface velocity phi = mesh.Sf() & Uf; #include "correctPhi.H" // Make the flux relative to the mesh motion fvc::makeRelative(phi, U); } if (mesh.changing() && checkMeshCourantNo) { #include "meshCourantNo.H" } } #include "alphaControls.H" surfaceScalarField rhoPhi ( IOobject ( "rhoPhi", runTime.timeName(), mesh ), mesh, dimensionedScalar("0", dimMass/dimTime, 0) ); mixture->correct(); #include "alphaEqnSubCycle.H" interface.correct(); #include "UEqn.H" // --- Pressure corrector loop while (pimple.correct()) { #include "pEqn.H" } if (pimple.turbCorr()) { turbulence->correct(); } } runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Info<< "End\n" << endl; return 0; }
//------------------------------------------------------------------------------ int main( int argc, char * argv[] ) { // basic attributes of the computation const unsigned geomDeg = 1; const unsigned fieldDegU = 2; const unsigned fieldDegP = 1; const unsigned tiOrder = 2; // order of time integrator const base::Shape shape = base::QUAD; //typedef base::time::BDF<tiOrder> MSM; typedef base::time::AdamsMoulton<tiOrder> MSM; // time stepping method determines the history size const unsigned nHist = MSM::numSteps; const std::string inputFile = "terz.inp"; double E, nu, alpha, c0, k, H, F, tMax; unsigned numSteps, numIntervals; { base::io::PropertiesParser pp; pp.registerPropertiesVar( "E", E ); pp.registerPropertiesVar( "nu", nu ); pp.registerPropertiesVar( "alpha", alpha ); pp.registerPropertiesVar( "c0", c0 ); pp.registerPropertiesVar( "k", k ); pp.registerPropertiesVar( "H", H ); pp.registerPropertiesVar( "F", F ); pp.registerPropertiesVar( "tMax", tMax ); pp.registerPropertiesVar( "numSteps", numSteps ); pp.registerPropertiesVar( "numIntervals", numIntervals ); // Read variables from the input file std::ifstream inp( inputFile.c_str() ); VERIFY_MSG( inp.is_open(), "Cannot open input file" ); pp.readValues( inp ); inp.close( ); } const double deltaT = tMax / static_cast<double>( numSteps ); // usage message if ( argc != 2 ) { std::cout << "Usage: " << argv[0] << " mesh.smf \n"; return 0; } const std::string meshFile = boost::lexical_cast<std::string>( argv[1] ); // Analytic solution Terzaghi terzaghi( E, nu, alpha, c0, k, H, F ); //-------------------------------------------------------------------------- // define a mesh typedef base::Unstructured<shape,geomDeg> Mesh; const unsigned dim = Mesh::Node::dim; // create a mesh and read from input Mesh mesh; { std::ifstream smf( meshFile.c_str() ); base::io::smf::readMesh( smf, mesh ); smf.close(); } // quadrature objects for volume and surface const unsigned kernelDegEstimate = 3; typedef base::Quadrature<kernelDegEstimate,shape> Quadrature; Quadrature quadrature; typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature; SurfaceQuadrature surfaceQuadrature; // Create a displacement field const unsigned doFSizeU = dim; typedef base::fe::Basis<shape,fieldDegU> FEBasisU; typedef base::Field<FEBasisU,doFSizeU,nHist> Displacement; typedef Displacement::DegreeOfFreedom DoFU; Displacement displacement; // Create a pressure field const unsigned doFSizeP = 1; typedef base::fe::Basis<shape,fieldDegP> FEBasisP; typedef base::Field<FEBasisP,doFSizeP,nHist> Pressure; typedef Pressure::DegreeOfFreedom DoFP; Pressure pressure; // generate DoFs from mesh base::dof::generate<FEBasisU>( mesh, displacement ); base::dof::generate<FEBasisP>( mesh, pressure ); // Creates a list of <Element,faceNo> pairs along the boundary base::mesh::MeshBoundary meshBoundary; meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() ); // Create a boundary mesh from this list typedef base::mesh::CreateBoundaryMesh<Mesh::Element> CreateBoundaryMesh; typedef CreateBoundaryMesh::BoundaryMesh BoundaryMesh; BoundaryMesh boundaryMesh; { CreateBoundaryMesh::apply( meshBoundary.begin(), meshBoundary.end(), mesh, boundaryMesh ); } // material object typedef mat::hypel::StVenant Material; Material material( mat::Lame::lambda( E, nu), mat::Lame::mu( E, nu ) ); typedef base::asmb::FieldBinder<Mesh,Displacement,Pressure> Field; Field field( mesh, displacement, pressure ); typedef Field::TupleBinder<1,1>::Type TopLeft; typedef Field::TupleBinder<1,2>::Type TopRight; typedef Field::TupleBinder<2,1>::Type BotLeft; typedef Field::TupleBinder<2,2>::Type BotRight; // surface displacement field typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Displacement> SurfaceFieldBinder; SurfaceFieldBinder surfaceFieldBinder( boundaryMesh, displacement ); typedef SurfaceFieldBinder::TupleBinder<1>::Type SFTB; // kernel objects typedef solid::HyperElastic<Material,TopLeft::Tuple> HyperElastic; HyperElastic hyperElastic( material ); typedef fluid::PressureGradient<TopRight::Tuple> GradP; GradP gradP; //typedef fluid::VelocityDivergence<FieldPUUTuple> DivU; //DivU divU( true ); // * alpha typedef PoroDivU<BotLeft::Tuple> DivU; DivU divU( alpha ); typedef heat::Laplace<BotRight::Tuple> Laplace; Laplace laplace( k ); // constrain the boundary base::dof::constrainBoundary<FEBasisU>( meshBoundary.begin(), meshBoundary.end(), mesh, displacement, boost::bind( &dirichletU<dim,DoFU>, _1, _2, 1.0 ) ); base::dof::constrainBoundary<FEBasisP>( meshBoundary.begin(), meshBoundary.end(), mesh, pressure, boost::bind( &dirichletP<dim,DoFP>, _1, _2, H ) ); // Number the degrees of freedom const std::size_t numDoFsU = base::dof::numberDoFsConsecutively( displacement.doFsBegin(), displacement.doFsEnd() ); std::cout << "# Number of displacement dofs " << numDoFsU << std::endl; const std::size_t numDoFsP = base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(), numDoFsU ); std::cout << "# Number of pressure dofs " << numDoFsP << std::endl; // write VTK file writeVTK( mesh, displacement, pressure, meshFile, 0 ); for ( unsigned n = 0; n < numSteps; n++ ) { const double time = (n+1) * deltaT; std::cout << time << " "; // initialise current displacement to zero (linear elasticity) std::for_each( displacement.doFsBegin(), displacement.doFsEnd(), boost::bind( &DoFU::clearValue, _1 ) ); // Create a solver object typedef base::solver::Eigen3 Solver; Solver solver( numDoFsU + numDoFsP ); //------------------------------------------------------------------ base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver, field, hyperElastic ); base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver, field, gradP ); base::asmb::stiffnessMatrixComputation<BotRight>( quadrature, solver, field, laplace); // time integration terms base::time::computeReactionTerms<BotLeft,MSM>( divU, quadrature, solver, field, deltaT, n ); base::time::computeInertiaTerms<BotRight,MSM>( quadrature, solver, field, deltaT, n, c0 ); base::time::computeResidualForceHistory<BotRight,MSM>( laplace, quadrature, solver, field, n ); // Neumann boundary condition base::asmb::neumannForceComputation<SFTB>( surfaceQuadrature, solver, surfaceFieldBinder, boost::bind( &neumannBC<dim>, _1, _2, H, F ) ); // Finalise assembly solver.finishAssembly(); // Solve solver.superLUSolve(); // distribute results back to dofs base::dof::setDoFsFromSolver( solver, displacement ); base::dof::setDoFsFromSolver( solver, pressure ); // push history std::for_each( displacement.doFsBegin(), displacement.doFsEnd(), boost::bind( &DoFU::pushHistory, _1 ) ); std::for_each( pressure.doFsBegin(), pressure.doFsEnd(), boost::bind( &DoFP::pushHistory, _1 ) ); // write VTK file writeVTK( mesh, displacement, pressure, meshFile, n+1 ); // Finished time steps //-------------------------------------------------------------------------- const std::pair<double,double> approx = probe( mesh, displacement, pressure ); const double p = terzaghi.pressure( H/2., time ); const double u = terzaghi.displacement( H/2., time ); std::cout << u << " " << approx.first << " " << p << " " << approx.second << '\n'; } return 0; }
void v2f<BasicTurbulenceModel>::correct() { if (!this->turbulence_) { return; } // Local references const alphaField& alpha = this->alpha_; const rhoField& rho = this->rho_; const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_; const volVectorField& U = this->U_; volScalarField& nut = this->nut_; fv::options& fvOptions(fv::options::New(this->mesh_)); eddyViscosity<RASModel<BasicTurbulenceModel>>::correct(); volScalarField divU(fvc::div(fvc::absolute(this->phi(), U))); // Use N=6 so that f=0 at walls const dimensionedScalar N("N", dimless, 6.0); const volTensorField gradU(fvc::grad(U)); const volScalarField S2(2*magSqr(dev(symm(gradU)))); const volScalarField G(this->GName(), nut*S2); const volScalarField Ts(this->Ts()); const volScalarField L2(type() + ":L2", sqr(Ls())); const volScalarField v2fAlpha ( type() + ":alpha", 1.0/Ts*((C1_ - N)*v2_ - 2.0/3.0*k_*(C1_ - 1.0)) ); const volScalarField Ceps1 ( "Ceps1", 1.4*(1.0 + 0.05*min(sqrt(k_/v2_), scalar(100.0))) ); // Update epsilon (and possibly G) at the wall epsilon_.boundaryFieldRef().updateCoeffs(); // Dissipation equation tmp<fvScalarMatrix> epsEqn ( fvm::ddt(alpha, rho, epsilon_) + fvm::div(alphaRhoPhi, epsilon_) - fvm::laplacian(alpha*rho*DepsilonEff(), epsilon_) == Ceps1*alpha*rho*G/Ts - fvm::SuSp(((2.0/3.0)*Ceps1 + Ceps3_)*alpha*rho*divU, epsilon_) - fvm::Sp(Ceps2_*alpha*rho/Ts, epsilon_) + fvOptions(alpha, rho, epsilon_) ); epsEqn.ref().relax(); fvOptions.constrain(epsEqn.ref()); epsEqn.ref().boundaryManipulate(epsilon_.boundaryFieldRef()); solve(epsEqn); fvOptions.correct(epsilon_); bound(epsilon_, this->epsilonMin_); // Turbulent kinetic energy equation tmp<fvScalarMatrix> kEqn ( fvm::ddt(alpha, rho, k_) + fvm::div(alphaRhoPhi, k_) - fvm::laplacian(alpha*rho*DkEff(), k_) == alpha*rho*G - fvm::SuSp((2.0/3.0)*alpha*rho*divU, k_) - fvm::Sp(alpha*rho*epsilon_/k_, k_) + fvOptions(alpha, rho, k_) ); kEqn.ref().relax(); fvOptions.constrain(kEqn.ref()); solve(kEqn); fvOptions.correct(k_); bound(k_, this->kMin_); // Relaxation function equation tmp<fvScalarMatrix> fEqn ( - fvm::laplacian(f_) == - fvm::Sp(1.0/L2, f_) - 1.0/L2/k_*(v2fAlpha - C2_*G) ); fEqn.ref().relax(); fvOptions.constrain(fEqn.ref()); solve(fEqn); fvOptions.correct(f_); bound(f_, fMin_); // Turbulence stress normal to streamlines equation tmp<fvScalarMatrix> v2Eqn ( fvm::ddt(alpha, rho, v2_) + fvm::div(alphaRhoPhi, v2_) - fvm::laplacian(alpha*rho*DkEff(), v2_) == alpha*rho*min(k_*f_, C2_*G - v2fAlpha) - fvm::Sp(N*alpha*rho*epsilon_/k_, v2_) + fvOptions(alpha, rho, v2_) ); v2Eqn.ref().relax(); fvOptions.constrain(v2Eqn.ref()); solve(v2Eqn); fvOptions.correct(v2_); bound(v2_, v2Min_); correctNut(); }
int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createDynamicFvMesh.H" #include "readGravitationalAcceleration.H" pimpleControl pimple(mesh); #include "readControls.H" #include "initContinuityErrs.H" #include "createFields.H" #include "createPcorrTypes.H" #include "CourantNo.H" #include "setInitialDeltaT.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.run()) { #include "readControls.H" #include "alphaCourantNo.H" #include "CourantNo.H" // Make the fluxes absolute fvc::makeAbsolute(phi, U); #include "setDeltaT.H" runTime++; Info<< "Time = " << runTime.timeName() << nl << endl; { // Store divU from the previous mesh for the correctPhi volScalarField divU(fvc::div(phi)); scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime(); // Do any mesh changes mesh.update(); if (mesh.changing()) { Info<< "Execution time for mesh.update() = " << runTime.elapsedCpuTime() - timeBeforeMeshUpdate << " s" << endl; gh = g & mesh.C(); ghf = g & mesh.Cf(); } if (mesh.changing() && correctPhi) { #include "correctPhi.H" } } // Make the fluxes relative to the mesh motion fvc::makeRelative(phi, U); if (mesh.changing() && checkMeshCourantNo) { #include "meshCourantNo.H" } turbulence->correct(); // --- Pressure-velocity PIMPLE corrector loop while (pimple.loop()) { #include "alphaEqnsSubCycle.H" // correct interface on first PIMPLE corrector if (pimple.corr() == 1) { interface.correct(); } solve(fvm::ddt(rho) + fvc::div(rhoPhi)); #include "UEqn.H" #include "TEqn.H" // --- Pressure corrector loop while (pimple.correct()) { #include "pEqn.H" // Make the fluxes relative to the mesh motion fvc::makeRelative(phi, U); } } rho = alpha1*rho1 + alpha2*rho2; runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Info<< "End\n" << endl; return 0; }
int checkCorrection(const Box& a_domain) { int eekflag = 0; const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance(); CH_assert(ebisPtr->isDefined()); //create a dbl of split up into 2^D boxes Vector<Box> vbox; Vector<int> proc; domainSplit(a_domain, vbox, a_domain.size(0)/2); LoadBalance(proc, vbox); DisjointBoxLayout dbl(vbox, proc); LayoutData<bool> map1d(dbl); int ibox = 0; //make every other map 1d for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit) { map1d[dit()] = (ibox%2 == 0); ibox++; } LevelData< BaseFab<int> > intmap(dbl, 1 , IntVect::Unit); Correct1D2D::makeIntMap(intmap, map1d, dbl); //this defines an ebisl with 2 ghost cells EBLevelGrid eblg(dbl, ProblemDomain(a_domain), 2, Chombo_EBIS::instance()) ; RealVect fluxVal = RealVect::Unit; Real dx = 1.0/a_domain.size(0); EBCellFactory fact(eblg.getEBISL()); LevelData<EBCellFAB> divU(dbl, 1, IntVect::Zero, fact); Correct1D2D correctinator(eblg, map1d, 1); correctinator.setToZero(); //this is important for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit) { //make a flux that is borked on the 1d side of box boundaries EBFluxFAB fluxFunc( eblg.getEBISL()[dit()], dbl[dit()], 1); setBorkedFlux(fluxFunc, eblg.getEBISL()[dit()], dbl[dit()], fluxVal, intmap[dit()]); //increment 1d buffers in corrector for (int idir = 0; idir < SpaceDim; idir++) { correctinator.increment1D(fluxFunc[idir], 1./dx, dit()); correctinator.increment2D(fluxFunc[idir], 1./dx, dit()); } //now take the divergence of the flux. it should be zero except //at box boundaries on the 1d side divergence(divU[dit()], fluxFunc, eblg.getEBISL()[dit()], dbl[dit()], fluxVal, dx); } //find max value of divergence before corrections Real max, min; EBLevelDataOps::getMaxMin(max, min, divU, 0); pout() << "before correction max divU = " << max << ", min divU = " << min << endl; //correct solution due to mismatch at 1d-2d boundaries correctinator.correctSolution(divU); //recalc max min EBLevelDataOps::getMaxMin(max, min, divU, 0); pout() << "after correction max divU = " << max << ", min divU = " << min << endl; if (Abs(max-min) > 1.0e-3) { pout() << "corrector did not seem to correct" << endl; return -7; } return eekflag; }
void gammaSST<BasicTurbulenceModel>::correct() { if (!this->turbulence_) { return; } // Local references const alphaField& alpha = this->alpha_; const rhoField& rho = this->rho_; const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_; const volVectorField& U = this->U_; volScalarField& nut = this->nut_; volScalarField& omega_ = this->omega_; volScalarField& k_ = this->k_; eddyViscosity<RASModel<BasicTurbulenceModel> >::correct(); volScalarField divU(fvc::div(fvc::absolute(this->phi(), U))); tmp<volTensorField> tgradU = fvc::grad(U); const volScalarField S2(2*magSqr(symm(tgradU()))); const volScalarField S("S", sqrt(S2)); const volScalarField W("Omega", sqrt(2*magSqr(skew(tgradU())))); volScalarField G(this->GName(), nut*S*W); tgradU.clear(); // Update omega and G at the wall omega_.boundaryFieldRef().updateCoeffs(); const volScalarField CDkOmega ( "CD", (2*this->alphaOmega2_)*(fvc::grad(k_) & fvc::grad(omega_))/omega_ ); const volScalarField F1("F1", this->F1(CDkOmega)); { volScalarField gamma(this->gamma(F1)); volScalarField beta(this->beta(F1)); // Turbulent frequency equation tmp<fvScalarMatrix> omegaEqn ( fvm::ddt(alpha, rho, omega_) + fvm::div(alphaRhoPhi, omega_) - fvm::laplacian(alpha*rho*this->DomegaEff(F1), omega_) == alpha*rho*gamma*S*W - fvm::Sp(alpha*rho*beta*omega_, omega_) - fvm::SuSp ( alpha*rho*(F1 - scalar(1))*CDkOmega/omega_, omega_ ) ); omegaEqn.ref().relax(); omegaEqn.ref().boundaryManipulate(omega_.boundaryFieldRef()); solve(omegaEqn); bound(omega_, this->omegaMin_); } // Turbulent kinetic energy equation const volScalarField FonLim( "FonLim", min( max(sqr(this->y_)*S/this->nu() / ( 2.2*ReThetacLim_) - 1., 0.), 3.) ); const volScalarField PkLim( "PkLim", 5*Ck_ * max(gammaInt()-0.2,0.) * (1-gammaInt()) * FonLim * max(3*CSEP_*this->nu() - this->nut_, 0.*this->nut_) * S * W ); tmp<fvScalarMatrix> kEqn ( fvm::ddt(alpha, rho, k_) + fvm::div(alphaRhoPhi, k_) - fvm::laplacian(alpha*rho*this->DkEff(F1), k_) == alpha*rho*(G*gammaInt() + PkLim) - fvm::Sp(max(gammaInt(),scalar(0.1)) * alpha*rho*this->betaStar_*omega_, k_) ); kEqn.ref().relax(); solve(kEqn); bound(k_, this->kMin_); this->correctNut(S2, this->F23()); // Intermittency equation (2) volScalarField Pgamma1 = Flength_ * S * gammaInt_ * Fonset(S); volScalarField Pgamma2 = ca2_ * W * gammaInt_ * Fturb(); tmp<fvScalarMatrix> gammaEqn ( fvm::ddt(alpha, rho, gammaInt_) + fvm::div(alphaRhoPhi, gammaInt_) - fvm::laplacian(alpha*rho*this->DgammaEff(), gammaInt_) == alpha*rho*Pgamma1 - fvm::Sp(alpha*rho*Pgamma1, gammaInt_) + alpha*rho*Pgamma2 - fvm::Sp(alpha*rho*ce2_*Pgamma2, gammaInt_) ); gammaEqn.ref().relax(); solve(gammaEqn); bound(gammaInt_,scalar(0)); if (debug && this->runTime_.outputTime()) { S.write(); W.write(); F1.write(); CDkOmega.write(); const volScalarField Pgamma("Pgamma", Pgamma1*(scalar(1)-gammaInt_)); Pgamma.write(); const volScalarField Egamma("Egamma", Pgamma2*(scalar(1)-ce2_*gammaInt_)); Egamma.write(); FonLim.write(); PkLim.write(); Fonset(S)().write(); FPG()().write(); } }