void mixtureKEpsilon<BasicTurbulenceModel>::correctInletOutlet ( volScalarField& vsf, const volScalarField& refVsf ) const { volScalarField::GeometricBoundaryField& bf = vsf.boundaryField(); const volScalarField::GeometricBoundaryField& refBf = refVsf.boundaryField(); forAll(bf, patchi) { if ( isA<inletOutletFvPatchScalarField>(bf[patchi]) && isA<inletOutletFvPatchScalarField>(refBf[patchi]) ) { refCast<inletOutletFvPatchScalarField> (bf[patchi]).refValue() = refCast<const inletOutletFvPatchScalarField> (refBf[patchi]).refValue(); } } }
void Foam::bound(volScalarField& vsf, const dimensionedScalar& vsf0) { scalar minVsf = min(vsf).value(); if (minVsf < vsf0.value()) { Info<< "bounding " << vsf.name() << ", min: " << gMin(vsf.internalField()) << " max: " << gMax(vsf.internalField()) << " average: " << gAverage(vsf.internalField()) << endl; vsf.internalField() = max ( max ( vsf.internalField(), fvc::average(max(vsf, vsf0))().internalField() // Bug fix: was assuming bound on zero. HJ, 25/Nov/2008 *pos(vsf0.value() - vsf.internalField()) ), vsf0.value() ); vsf.correctBoundaryConditions(); vsf.boundaryField() = max(vsf.boundaryField(), vsf0.value()); } }
void calcYPlus ( const TurbulenceModel& turbulenceModel, const fvMesh& mesh, const volVectorField& U, volScalarField& yPlus ) { volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); const volScalarField::GeometricBoundaryField nutBf = turbulenceModel->nut()().boundaryField(); const volScalarField::GeometricBoundaryField nuEffBf = turbulenceModel->nuEff()().boundaryField(); const volScalarField::GeometricBoundaryField nuBf = turbulenceModel->nu()().boundaryField(); const fvPatchList& patches = mesh.boundary(); forAll(patches, patchi) { const fvPatch& patch = patches[patchi]; if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi])) { const nutWallFunctionFvPatchScalarField& nutPf = dynamic_cast<const nutWallFunctionFvPatchScalarField&> ( nutBf[patchi] ); yPlus.boundaryField()[patchi] = nutPf.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << nutPf.patch().name() << ", wall-function " << nutPf.type() << ", y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } else if (isA<wallFvPatch>(patch)) { yPlus.boundaryField()[patchi] = d[patchi] *sqrt ( nuEffBf[patchi] *mag(U.boundaryField()[patchi].snGrad()) )/nuBf[patchi]; const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << patch.name() << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } } }
void Foam::boundMinMax ( volScalarField& vsf, const dimensionedScalar& vsf0, const dimensionedScalar& vsf1 ) { scalar minVsf = min(vsf).value(); scalar maxVsf = max(vsf).value(); if (minVsf < vsf0.value() || maxVsf > vsf1.value()) { Info<< "bounding " << vsf.name() << ", min: " << gMin(vsf.internalField()) << " max: " << gMax(vsf.internalField()) << " average: " << gAverage(vsf.internalField()) << endl; } if (minVsf < vsf0.value()) { vsf.internalField() = max ( max ( vsf.internalField(), fvc::average(max(vsf, vsf0))().internalField() *pos(vsf0.value() - vsf.internalField()) ), vsf0.value() ); vsf.correctBoundaryConditions(); vsf.boundaryField() = max(vsf.boundaryField(), vsf0.value()); } if (maxVsf > vsf1.value()) { vsf.internalField() = min ( min ( vsf.internalField(), fvc::average(min(vsf, vsf1))().internalField() *neg(vsf1.value() - vsf.internalField()) // This is needed when all values are above max // HJ, 18/Apr/2009 + pos(vsf1.value() - vsf.internalField())*vsf1.value() ), vsf1.value() ); vsf.correctBoundaryConditions(); vsf.boundaryField() = min(vsf.boundaryField(), vsf1.value()); } }
void Foam::yPlusRAS::calcIncompressibleYPlus ( const fvMesh& mesh, volScalarField& yPlus ) { typedef incompressible::nutWallFunctionFvPatchScalarField wallFunctionPatchField; const incompressible::RASModel& model = mesh.lookupObject<incompressible::RASModel>("RASProperties"); const volScalarField nut(model.nut()); const volScalarField::GeometricBoundaryField& nutPatches = nut.boundaryField(); bool foundPatch = false; forAll(nutPatches, patchI) { if (isA<wallFunctionPatchField>(nutPatches[patchI])) { foundPatch = true; const wallFunctionPatchField& nutPw = dynamic_cast<const wallFunctionPatchField&>(nutPatches[patchI]); yPlus.boundaryField()[patchI] = nutPw.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchI]; scalar minYp = gMin(Yp); scalar maxYp = gMax(Yp); scalar avgYp = gAverage(Yp); if (log_) { Info<< " patch " << nutPw.patch().name() << " y+ : min = " << minYp << ", max = " << maxYp << ", average = " << avgYp << nl; } if (Pstream::master()) { file() << obr_.time().value() << token::TAB << nutPw.patch().name() << token::TAB << minYp << token::TAB << maxYp << token::TAB << avgYp << endl; } } } if (log_ && !foundPatch) { Info<< " no " << wallFunctionPatchField::typeName << " patches" << endl; } }
void calcIncompressibleYPlus ( const fvMesh& mesh, const Time& runTime, const volVectorField& U, volScalarField& yPlus ) { typedef incompressible::RASModels::nutWallFunctionFvPatchScalarField wallFunctionPatchField; #include "createPhi.H" singlePhaseTransportModel laminarTransport(U, phi); autoPtr<incompressible::RASModel> RASModel ( incompressible::RASModel::New(U, phi, laminarTransport) ); const volScalarField::GeometricBoundaryField nutPatches = RASModel->nut()().boundaryField(); bool foundNutPatch = false; forAll(nutPatches, patchi) { if (isA<wallFunctionPatchField>(nutPatches[patchi])) { foundNutPatch = true; const wallFunctionPatchField& nutPw = dynamic_cast<const wallFunctionPatchField&> (nutPatches[patchi]); yPlus.boundaryField()[patchi] = nutPw.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << nutPw.patch().name() << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } } if (!foundNutPatch) { Info<< " no " << wallFunctionPatchField::typeName << " patches" << endl; } }
vectorField fieldOperations:: getWallPointMotion ( const fvMesh& mesh, const volScalarField& C, const label movingPatchID ) { // interpolate the concentration from cells to wall faces coupledPatchInterpolation patchInterpolator ( mesh.boundaryMesh()[movingPatchID], mesh ); // concentration and normals on the faces scalarField pointCface = -C.boundaryField()[movingPatchID].snGrad(); vectorField pointNface = mesh.boundaryMesh()[movingPatchID].faceNormals(); scalarField motionC = patchInterpolator.faceToPointInterpolate(pointCface); vectorField motionN = patchInterpolator.faceToPointInterpolate(pointNface); // normalize point normals to 1 forAll(motionN, ii) motionN[ii]/=mag(motionN[ii]); return motionC*motionN; }
Foam::tmp<Foam::volScalarField> Foam::laminarModels::generalizedNewtonianViscosityModels::strainRateFunction:: nu ( const volScalarField& nu0, const volScalarField& strainRate ) const { tmp<volScalarField> tnu ( volScalarField::New ( IOobject::groupName(type() + ":nu", nu0.group()), nu0.mesh(), dimensionedScalar(dimViscosity, 0) ) ); tnu.ref().primitiveFieldRef() = strainRateFunction_->value(strainRate); volScalarField::Boundary& nuBf = tnu.ref().boundaryFieldRef(); const volScalarField::Boundary& sigmaBf = strainRate.boundaryField(); forAll(nuBf, patchi) { nuBf[patchi] = strainRateFunction_->value(sigmaBf[patchi]); }
tmp<GeometricField<Type, fvPatchField, volMesh> > EulerLocalDdtScheme<Type>::fvcDdt ( const volScalarField& rho, const GeometricField<Type, fvPatchField, volMesh>& vf ) { const objectRegistry& registry = this->mesh(); // get access to the scalar beta[i] const scalarField& beta = registry.lookupObject<scalarField>(deltaTName_); volScalarField rDeltaT = 1.0/(beta[0]*registry.lookupObject<volScalarField>(deltaTauName_)); IOobject ddtIOobject ( "ddt("+rho.name()+','+vf.name()+')', mesh().time().timeName(), mesh() ); if (mesh().moving()) { return tmp<GeometricField<Type, fvPatchField, volMesh> > ( new GeometricField<Type, fvPatchField, volMesh> ( ddtIOobject, mesh(), rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(), rDeltaT.internalField()* ( rho.internalField()*vf.internalField() - rho.oldTime().internalField() *vf.oldTime().internalField()*mesh().V0()/mesh().V() ), rDeltaT.boundaryField()* ( rho.boundaryField()*vf.boundaryField() - rho.oldTime().boundaryField() *vf.oldTime().boundaryField() ) ) ); } else { return tmp<GeometricField<Type, fvPatchField, volMesh> > ( new GeometricField<Type, fvPatchField, volMesh> ( ddtIOobject, rDeltaT*(rho*vf - rho.oldTime()*vf.oldTime()) ) ); } }
void Foam::compressibleTwoPhaseMixtureThermo::heBoundaryCorrection(volScalarField& h) { volScalarField::GeometricBoundaryField& hbf = h.boundaryField(); forAll(hbf, patchi) { if (isA<gradientEnergyFvPatchScalarField>(hbf[patchi])) { refCast<gradientEnergyFvPatchScalarField>(hbf[patchi]).gradient() = hbf[patchi].fvPatchField::snGrad(); } else if (isA<mixedEnergyFvPatchScalarField>(hbf[patchi])) { refCast<mixedEnergyFvPatchScalarField>(hbf[patchi]).refGrad() = hbf[patchi].fvPatchField::snGrad(); } } }
void Foam::basicThermo::eBoundaryCorrection(volScalarField& e) { volScalarField::GeometricBoundaryField& ebf = e.boundaryField(); forAll(ebf, patchi) { if (isA<gradientInternalEnergyFvPatchScalarField>(ebf[patchi])) { refCast<gradientInternalEnergyFvPatchScalarField>(ebf[patchi]) .gradient() = ebf[patchi].fvPatchField::snGrad(); } else if (isA<mixedInternalEnergyFvPatchScalarField>(ebf[patchi])) { refCast<mixedInternalEnergyFvPatchScalarField>(ebf[patchi]) .refGrad() = ebf[patchi].fvPatchField::snGrad(); } } }
void Foam::basicThermo::hBoundaryCorrection(volScalarField& h) { volScalarField::GeometricBoundaryField& hbf = h.boundaryField(); forAll(hbf, patchi) { if (isA<gradientEnthalpyFvPatchScalarField>(hbf[patchi])) { refCast<gradientEnthalpyFvPatchScalarField>(hbf[patchi]).gradient() = hbf[patchi].fvPatchField::snGrad(); } else if (isA<mixedEnthalpyFvPatchScalarField>(hbf[patchi])) { refCast<mixedEnthalpyFvPatchScalarField>(hbf[patchi]).refGrad() = hbf[patchi].fvPatchField::snGrad(); } } }
wordList mixtureKEpsilon<BasicTurbulenceModel>::epsilonBoundaryTypes ( const volScalarField& epsilon ) const { const volScalarField::GeometricBoundaryField& ebf = epsilon.boundaryField(); wordList ebt = ebf.types(); forAll(ebf, patchi) { if (isA<fixedValueFvPatchScalarField>(ebf[patchi])) { ebt[patchi] = fixedValueFvPatchScalarField::typeName; } } return ebt; }
void calcCompressibleYPlus ( const fvMesh& mesh, const Time& runTime, const volVectorField& U, volScalarField& yPlus ) { typedef compressible::RASModels::mutkWallFunctionFvPatchScalarField wallFunctionPatchField; IOobject rhoHeader ( "rho", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ); if (!rhoHeader.headerOk()) { Info<< " no rho field" << endl; return; } Info<< "Reading field rho\n" << endl; volScalarField rho(rhoHeader, mesh); #include "compressibleCreatePhi.H" autoPtr<basicThermo> pThermo ( basicThermo::New(mesh) ); basicThermo& thermo = pThermo(); autoPtr<compressible::RASModel> RASModel ( compressible::RASModel::New ( rho, U, phi, thermo ) ); const volScalarField::GeometricBoundaryField mutPatches = RASModel->mut()().boundaryField(); bool foundMutPatch = false; forAll(mutPatches, patchi) { if (isA<wallFunctionPatchField>(mutPatches[patchi])) { foundMutPatch = true; const wallFunctionPatchField& mutPw = dynamic_cast<const wallFunctionPatchField&> (mutPatches[patchi]); yPlus.boundaryField()[patchi] = mutPw.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << mutPw.patch().name() << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } } if (!foundMutPatch) { Info<< " no " << wallFunctionPatchField::typeName << " patches" << endl; } }
void Foam::yPlus::calcYPlus ( const TurbulenceModel& turbulenceModel, const fvMesh& mesh, volScalarField& yPlus ) { volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); const volScalarField::GeometricBoundaryField nutBf = turbulenceModel.nut()().boundaryField(); const volScalarField::GeometricBoundaryField nuEffBf = turbulenceModel.nuEff()().boundaryField(); const volScalarField::GeometricBoundaryField nuBf = turbulenceModel.nu()().boundaryField(); const fvPatchList& patches = mesh.boundary(); forAll(patches, patchi) { const fvPatch& patch = patches[patchi]; if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi])) { const nutWallFunctionFvPatchScalarField& nutPf = dynamic_cast<const nutWallFunctionFvPatchScalarField&> ( nutBf[patchi] ); yPlus.boundaryField()[patchi] = nutPf.yPlus(); const scalarField& yPlusp = yPlus.boundaryField()[patchi]; const scalar minYplus = gMin(yPlusp); const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); if (Pstream::master()) { if (log_) Info << " patch " << patch.name() << " y+ : min = " << minYplus << ", max = " << maxYplus << ", average = " << avgYplus << nl; file() << obr_.time().value() << token::TAB << patch.name() << token::TAB << minYplus << token::TAB << maxYplus << token::TAB << avgYplus << endl; } } else if (isA<wallFvPatch>(patch)) { yPlus.boundaryField()[patchi] = d[patchi] *sqrt ( nuEffBf[patchi] *mag(turbulenceModel.U().boundaryField()[patchi].snGrad()) )/nuBf[patchi]; const scalarField& yPlusp = yPlus.boundaryField()[patchi]; const scalar minYplus = gMin(yPlusp); const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); if (Pstream::master()) { if (log_) Info << " patch " << patch.name() << " y+ : min = " << minYplus << ", max = " << maxYplus << ", average = " << avgYplus << nl; file() << obr_.time().value() << token::TAB << patch.name() << token::TAB << minYplus << token::TAB << maxYplus << token::TAB << avgYplus << endl; } } } }
void Foam::yPlusLES::calcIncompressibleYPlus ( const fvMesh& mesh, const volVectorField& U, volScalarField& yPlus ) { const incompressible::LESModel& model = mesh.lookupObject<incompressible::LESModel>("LESProperties"); volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); volScalarField nuEff(model.nuEff()); const fvPatchList& patches = mesh.boundary(); const volScalarField nuLam(model.nu()); bool foundPatch = false; forAll(patches, patchI) { const fvPatch& currPatch = patches[patchI]; if (isA<wallFvPatch>(currPatch)) { foundPatch = true; yPlus.boundaryField()[patchI] = d[patchI] *sqrt ( nuEff.boundaryField()[patchI] *mag(U.boundaryField()[patchI].snGrad()) ) /nuLam.boundaryField()[patchI]; const scalarField& Yp = yPlus.boundaryField()[patchI]; scalar minYp = gMin(Yp); scalar maxYp = gMax(Yp); scalar avgYp = gAverage(Yp); if (log_) { Info<< " patch " << currPatch.name() << " y+ : min = " << minYp << ", max = " << maxYp << ", average = " << avgYp << nl; } if (Pstream::master()) { file() << obr_.time().value() << token::TAB << currPatch.name() << token::TAB << minYp << token::TAB << maxYp << token::TAB << avgYp << endl; } } } if (log_ && !foundPatch) { Info<< " no " << wallFvPatch::typeName << " patches" << endl; } }
tmp<GeometricField<Type, fvPatchField, volMesh>> EulerD2dt2Scheme<Type>::fvcD2dt2 ( const volScalarField& rho, const GeometricField<Type, fvPatchField, volMesh>& vf ) { dimensionedScalar rDeltaT2 = 4.0/sqr(mesh().time().deltaT() + mesh().time().deltaT0()); IOobject d2dt2IOobject ( "d2dt2("+rho.name()+','+vf.name()+')', mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE ); scalar deltaT = mesh().time().deltaTValue(); scalar deltaT0 = mesh().time().deltaT0Value(); scalar coefft = (deltaT + deltaT0)/(2*deltaT); scalar coefft00 = (deltaT + deltaT0)/(2*deltaT0); if (mesh().moving()) { scalar halfRdeltaT2 = 0.5*rDeltaT2.value(); scalar quarterRdeltaT2 = 0.25*rDeltaT2.value(); const scalarField VV0rhoRho0 ( (mesh().V() + mesh().V0()) * (rho.primitiveField() + rho.oldTime().primitiveField()) ); const scalarField V0V00rho0Rho00 ( (mesh().V0() + mesh().V00()) * ( rho.oldTime().primitiveField() + rho.oldTime().oldTime().primitiveField() ) ); return tmp<GeometricField<Type, fvPatchField, volMesh>> ( new GeometricField<Type, fvPatchField, volMesh> ( d2dt2IOobject, mesh(), rDeltaT2.dimensions()*rho.dimensions()*vf.dimensions(), quarterRdeltaT2* ( coefft*VV0rhoRho0*vf.primitiveField() - (coefft*VV0rhoRho0 + coefft00*V0V00rho0Rho00) *vf.oldTime().primitiveField() + (coefft00*V0V00rho0Rho00) *vf.oldTime().oldTime().primitiveField() )/mesh().V(), halfRdeltaT2* ( coefft *(rho.boundaryField() + rho.oldTime().boundaryField()) *vf.boundaryField() - ( coefft *( rho.boundaryField() + rho.oldTime().boundaryField() ) + coefft00 *( rho.oldTime().boundaryField() + rho.oldTime().oldTime().boundaryField() ) )*vf.oldTime().boundaryField() + coefft00 *( rho.oldTime().boundaryField() + rho.oldTime().oldTime().boundaryField() )*vf.oldTime().oldTime().boundaryField() ) ) ); } else { dimensionedScalar halfRdeltaT2 = 0.5*rDeltaT2; const volScalarField rhoRho0(rho + rho.oldTime()); const volScalarField rho0Rho00(rho.oldTime() +rho.oldTime().oldTime()); return tmp<GeometricField<Type, fvPatchField, volMesh>> ( new GeometricField<Type, fvPatchField, volMesh> ( d2dt2IOobject, halfRdeltaT2* ( coefft*rhoRho0*vf - (coefft*rhoRho0 + coefft00*rho0Rho00)*vf.oldTime() + coefft00*rho0Rho00*vf.oldTime().oldTime() ) ) ); } }
int main(int argc, char *argv[]) { timeSelector::addOptions(); #include "setRootCase.H" #include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); #include "createMesh.H" #include "createFields.H" forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); Info<< "Time = " << runTime.timeName() << endl; // Cache the turbulence fields Info<< "\nRetrieving field k from turbulence model" << endl; const volScalarField k = RASModel->k(); Info<< "\nRetrieving field epsilon from turbulence model" << endl; const volScalarField epsilon = RASModel->epsilon(); Info<< "\nRetrieving field R from turbulence model" << endl; const volSymmTensorField R = RASModel->R(); // Check availability of tubulence fields if (!IOobject("k", runTime.timeName(), mesh).headerOk()) { Info<< "\nWriting turbulence field k" << endl; k.write(); } else { Info<< "\nTurbulence k field already exists" << endl; } if (!IOobject("epsilon", runTime.timeName(), mesh).headerOk()) { Info<< "\nWriting turbulence field epsilon" << endl; epsilon.write(); } else { Info<< "\nTurbulence epsilon field already exists" << endl; } if (!IOobject("R", runTime.timeName(), mesh).headerOk()) { Info<< "\nWriting turbulence field R" << endl; R.write(); } else { Info<< "\nTurbulence R field already exists" << endl; } if (!IOobject("omega", runTime.timeName(), mesh).headerOk()) { const scalar Cmu = 0.09; Info<< "creating omega" << endl; volScalarField omega ( IOobject ( "omega", runTime.timeName(), mesh ), epsilon/(Cmu*k), epsilon.boundaryField().types() ); Info<< "\nWriting turbulence field omega" << endl; omega.write(); } else { Info<< "\nTurbulence omega field already exists" << endl; } }
void Foam::MULES::limiter ( scalarField& allLambda, const RdeltaTType& rDeltaT, const RhoType& rho, const volScalarField& psi, const surfaceScalarField& phiBD, const surfaceScalarField& phiCorr, const SpType& Sp, const SuType& Su, const scalar psiMax, const scalar psiMin ) { const scalarField& psiIf = psi; const volScalarField::GeometricBoundaryField& psiBf = psi.boundaryField(); const fvMesh& mesh = psi.mesh(); const dictionary& MULEScontrols = mesh.solverDict(psi.name()); label nLimiterIter ( MULEScontrols.lookupOrDefault<label>("nLimiterIter", 3) ); scalar smoothLimiter ( MULEScontrols.lookupOrDefault<scalar>("smoothLimiter", 0) ); const scalarField& psi0 = psi.oldTime(); const labelUList& owner = mesh.owner(); const labelUList& neighb = mesh.neighbour(); tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc(); const scalarField& V = tVsc(); const scalarField& phiBDIf = phiBD; const surfaceScalarField::GeometricBoundaryField& phiBDBf = phiBD.boundaryField(); const scalarField& phiCorrIf = phiCorr; const surfaceScalarField::GeometricBoundaryField& phiCorrBf = phiCorr.boundaryField(); slicedSurfaceScalarField lambda ( IOobject ( "lambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allLambda, false // Use slices for the couples ); scalarField& lambdaIf = lambda; surfaceScalarField::GeometricBoundaryField& lambdaBf = lambda.boundaryField(); scalarField psiMaxn(psiIf.size(), psiMin); scalarField psiMinn(psiIf.size(), psiMax); scalarField sumPhiBD(psiIf.size(), 0.0); scalarField sumPhip(psiIf.size(), VSMALL); scalarField mSumPhim(psiIf.size(), VSMALL); forAll(phiCorrIf, facei) { label own = owner[facei]; label nei = neighb[facei]; psiMaxn[own] = max(psiMaxn[own], psiIf[nei]); psiMinn[own] = min(psiMinn[own], psiIf[nei]); psiMaxn[nei] = max(psiMaxn[nei], psiIf[own]); psiMinn[nei] = min(psiMinn[nei], psiIf[own]); sumPhiBD[own] += phiBDIf[facei]; sumPhiBD[nei] -= phiBDIf[facei]; scalar phiCorrf = phiCorrIf[facei]; if (phiCorrf > 0.0) { sumPhip[own] += phiCorrf; mSumPhim[nei] += phiCorrf; } else { mSumPhim[own] -= phiCorrf; sumPhip[nei] -= phiCorrf; } }
void Foam::MULES::limiter ( scalargpuField& allLambda, const RdeltaTType& rDeltaT, const RhoType& rho, const volScalarField& psi, const surfaceScalarField& phiBD, const surfaceScalarField& phiCorr, const SpType& Sp, const SuType& Su, const scalar psiMax, const scalar psiMin, const label nLimiterIter ) { const scalargpuField& psiIf = psi.getField(); const volScalarField::GeometricBoundaryField& psiBf = psi.boundaryField(); const scalargpuField& psi0 = psi.oldTime(); const fvMesh& mesh = psi.mesh(); const labelgpuList& owner = mesh.owner(); const labelgpuList& neighb = mesh.neighbour(); const labelgpuList& losort = mesh.lduAddr().losortAddr(); const labelgpuList& ownStart = mesh.lduAddr().ownerStartAddr(); const labelgpuList& losortStart = mesh.lduAddr().losortStartAddr(); tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc(); const scalargpuField& V = tVsc().getField(); const scalargpuField& phiBDIf = phiBD; const surfaceScalarField::GeometricBoundaryField& phiBDBf = phiBD.boundaryField(); const scalargpuField& phiCorrIf = phiCorr; const surfaceScalarField::GeometricBoundaryField& phiCorrBf = phiCorr.boundaryField(); slicedSurfaceScalarField lambda ( IOobject ( "lambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allLambda, false // Use slices for the couples ); scalargpuField& lambdaIf = lambda; surfaceScalarField::GeometricBoundaryField& lambdaBf = lambda.boundaryField(); scalargpuField psiMaxn(psiIf.size(), psiMin); scalargpuField psiMinn(psiIf.size(), psiMax); scalargpuField sumPhiBD(psiIf.size(), 0.0); scalargpuField sumPhip(psiIf.size(), VSMALL); scalargpuField mSumPhim(psiIf.size(), VSMALL); thrust::for_each ( thrust::make_counting_iterator(0), thrust::make_counting_iterator(0)+psiIf.size(), limiterMULESFunctor ( owner.data(), neighb.data(), ownStart.data(), losortStart.data(), losort.data(), psiIf.data(), phiBDIf.data(), phiCorrIf.data(), psiMaxn.data(), psiMinn.data(), sumPhiBD.data(), sumPhip.data(), mSumPhim.data() ) ); forAll(phiCorrBf, patchi) { const fvPatchScalarField& psiPf = psiBf[patchi]; const scalargpuField& phiBDPf = phiBDBf[patchi]; const scalargpuField& phiCorrPf = phiCorrBf[patchi]; const labelgpuList& pcells = mesh.lduAddr().patchSortCells(patchi); const labelgpuList& losort = mesh.lduAddr().patchSortAddr(patchi); const labelgpuList& losortStart = mesh.lduAddr().patchSortStartAddr(patchi); thrust::for_each ( thrust::make_counting_iterator(0), thrust::make_counting_iterator(0)+pcells.size(), patchMinMaxMULESFunctor ( losortStart.data(), losort.data(), pcells.data(), psiPf.coupled()?psiPf.patchNeighbourField()().data():psiPf.data(), phiBDPf.data(), phiCorrPf.data(), psiMaxn.data(), psiMinn.data(), sumPhiBD.data(), sumPhip.data(), mSumPhim.data() ) ); } psiMaxn = min(psiMaxn, psiMax); psiMinn = max(psiMinn, psiMin); //scalar smooth = 0.5; //psiMaxn = min((1.0 - smooth)*psiIf + smooth*psiMaxn, psiMax); //psiMinn = max((1.0 - smooth)*psiIf + smooth*psiMinn, psiMin); if (mesh.moving()) { tmp<volScalarField::DimensionedInternalField> V0 = mesh.Vsc0(); psiMaxn = V *( (rho.getField()*rDeltaT - Sp.getField())*psiMaxn - Su.getField() ) - (V0().getField()*rDeltaT)*rho.oldTime().getField()*psi0 + sumPhiBD; psiMinn = V *( Su.getField() - (rho.getField()*rDeltaT - Sp.getField())*psiMinn ) + (V0().getField()*rDeltaT)*rho.oldTime().getField()*psi0 - sumPhiBD; } else { psiMaxn = V *( (rho.getField()*rDeltaT - Sp.getField())*psiMaxn - Su.getField() - (rho.oldTime().getField()*rDeltaT)*psi0 ) + sumPhiBD; psiMinn = V *( Su.getField() - (rho.getField()*rDeltaT - Sp.getField())*psiMinn + (rho.oldTime().getField()*rDeltaT)*psi0 ) - sumPhiBD; } scalargpuField sumlPhip(psiIf.size()); scalargpuField mSumlPhim(psiIf.size()); for (int j=0; j<nLimiterIter; j++) { sumlPhip = 0.0; mSumlPhim = 0.0; thrust::for_each ( thrust::make_counting_iterator(0), thrust::make_counting_iterator(0)+sumlPhip.size(), sumlPhiMULESFunctor ( owner.data(), neighb.data(), ownStart.data(), losortStart.data(), losort.data(), lambdaIf.data(), phiCorrIf.data(), sumlPhip.data(), mSumlPhim.data() ) ); forAll(lambdaBf, patchi) { scalargpuField& lambdaPf = lambdaBf[patchi]; const scalargpuField& phiCorrfPf = phiCorrBf[patchi]; const labelgpuList& pcells = mesh.lduAddr().patchSortCells(patchi); const labelgpuList& losort = mesh.lduAddr().patchSortAddr(patchi); const labelgpuList& losortStart = mesh.lduAddr().patchSortStartAddr(patchi); thrust::for_each ( thrust::make_counting_iterator(0), thrust::make_counting_iterator(0)+pcells.size(), patchSumlPhiMULESFunctor ( losortStart.data(), losort.data(), pcells.data(), lambdaPf.data(), phiCorrfPf.data(), sumlPhip.data(), mSumlPhim.data() ) ); } thrust::transform ( sumlPhip.begin(), sumlPhip.end(), thrust::make_zip_iterator(thrust::make_tuple ( psiMaxn.begin(), mSumPhim.begin() )), sumlPhip.begin(), sumlPhipFinalMULESFunctor<false>() ); thrust::transform ( mSumlPhim.begin(), mSumlPhim.end(), thrust::make_zip_iterator(thrust::make_tuple ( psiMinn.begin(), sumPhip.begin() )), mSumlPhim.begin(), sumlPhipFinalMULESFunctor<true>() ); const scalargpuField& lambdam = sumlPhip; const scalargpuField& lambdap = mSumlPhim; thrust::transform ( phiCorrIf.begin(), phiCorrIf.end(), thrust::make_zip_iterator(thrust::make_tuple ( lambdaIf.begin(), thrust::make_permutation_iterator ( lambdap.begin(), owner.begin() ), thrust::make_permutation_iterator ( lambdam.begin(), neighb.begin() ), thrust::make_permutation_iterator ( lambdam.begin(), owner.begin() ), thrust::make_permutation_iterator ( lambdap.begin(), neighb.begin() ) )), lambdaIf.begin(), lambdaIfMULESFunctor() ); forAll(lambdaBf, patchi) { fvsPatchScalarField& lambdaPf = lambdaBf[patchi]; const scalargpuField& phiCorrfPf = phiCorrBf[patchi]; const fvPatchScalarField& psiPf = psiBf[patchi]; if (isA<wedgeFvPatch>(mesh.boundary()[patchi])) { lambdaPf = 0; } else if (psiPf.coupled()) { const labelgpuList& pFaceCells = mesh.boundary()[patchi].faceCells(); thrust::transform ( phiCorrfPf.begin(), phiCorrfPf.end(), thrust::make_zip_iterator(thrust::make_tuple ( lambdaPf.begin(), thrust::make_permutation_iterator ( lambdap.begin(), pFaceCells.begin() ), thrust::make_permutation_iterator ( lambdam.begin(), pFaceCells.begin() ) )), lambdaPf.begin(), coupledPatchLambdaPfMULESFunctor() ); } else { const labelgpuList& pFaceCells = mesh.boundary()[patchi].faceCells(); const scalargpuField& phiBDPf = phiBDBf[patchi]; const scalargpuField& phiCorrPf = phiCorrBf[patchi]; thrust::transform ( phiCorrfPf.begin(), phiCorrfPf.end(), thrust::make_zip_iterator(thrust::make_tuple ( lambdaPf.begin(), phiBDPf.begin(), phiCorrPf.begin(), thrust::make_permutation_iterator ( lambdap.begin(), pFaceCells.begin() ), thrust::make_permutation_iterator ( lambdam.begin(), pFaceCells.begin() ) )), lambdaPf.begin(), patchLambdaPfMULESFunctor() ); } }