void Foam::mulesWithDiffusionImplicitLimiter ( const volScalarField& rho, volScalarField& Y, const surfaceScalarField& phiPos, const surfaceScalarField& phiNeg, scalarField& lambdaFace, surfaceScalarField& rhoPhif, surfaceScalarField& diffFlux, const surfaceScalarField& Dmi, const fvScalarMatrix& SuSp ) { const fvMesh& mesh = rho.mesh(); const dictionary& MULEScontrols = mesh.solverDict("Yi"); label nLimiterIter ( readLabel(MULEScontrols.lookup("nLimiterIter")) ); upwind<scalar> UDsPos(mesh, phiPos); upwind<scalar> UDsNeg(mesh, phiNeg); fvScalarMatrix YConvection ( fv::gaussConvectionScheme<scalar>(mesh, phiPos, UDsPos).fvmDiv(phiPos, Y) + fv::gaussConvectionScheme<scalar>(mesh, phiNeg, UDsPos).fvmDiv(phiNeg, Y) ); surfaceScalarField rhoPhifBD = YConvection.flux(); surfaceScalarField& rhoPhifCorr = rhoPhif; rhoPhifCorr -= rhoPhifBD; volScalarField Su ( "Su", SuSp & Y ); MULES::limiter ( lambdaFace, 1.0/mesh.time().deltaTValue(), rho, Y, rhoPhifBD, rhoPhifCorr, zeroField(), Su, 1.0, //psiMax, 0.0, //psiMin, nLimiterIter ); }
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::implicitSolve ( const RhoType& rho, volScalarField& psi, const surfaceScalarField& phi, surfaceScalarField& phiPsi, const SpType& Sp, const SuType& Su, const scalar psiMax, const scalar psiMin ) { const fvMesh& mesh = psi.mesh(); const dictionary& MULEScontrols = mesh.solverDict(psi.name()); label maxIter ( readLabel(MULEScontrols.lookup("maxIter")) ); label nLimiterIter ( readLabel(MULEScontrols.lookup("nLimiterIter")) ); scalar maxUnboundedness ( readScalar(MULEScontrols.lookup("maxUnboundedness")) ); scalar CoCoeff ( readScalar(MULEScontrols.lookup("CoCoeff")) ); scalarField allCoLambda(mesh.nFaces()); { tmp<surfaceScalarField> Cof = mesh.time().deltaT()*mesh.surfaceInterpolation::deltaCoeffs() *mag(phi)/mesh.magSf(); slicedSurfaceScalarField CoLambda ( IOobject ( "CoLambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allCoLambda, false // Use slices for the couples ); CoLambda == 1.0/max(CoCoeff*Cof, scalar(1)); } scalarField allLambda(allCoLambda); //scalarField allLambda(mesh.nFaces(), 1.0); slicedSurfaceScalarField lambda ( IOobject ( "lambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allLambda, false // Use slices for the couples ); linear<scalar> CDs(mesh); upwind<scalar> UDs(mesh, phi); //fv::uncorrectedSnGrad<scalar> snGrads(mesh); fvScalarMatrix psiConvectionDiffusion ( fvm::ddt(rho, psi) + fv::gaussConvectionScheme<scalar>(mesh, phi, UDs).fvmDiv(phi, psi) //- fv::gaussLaplacianScheme<scalar, scalar>(mesh, CDs, snGrads) //.fvmLaplacian(Dpsif, psi) - fvm::Sp(Sp, psi) - Su ); surfaceScalarField phiBD(psiConvectionDiffusion.flux()); surfaceScalarField& phiCorr = phiPsi; phiCorr -= phiBD; for (label i=0; i<maxIter; i++) { if (i != 0 && i < 4) { allLambda = allCoLambda; } limiter ( allLambda, rho, psi, phiBD, phiCorr, Sp, Su, psiMax, psiMin, nLimiterIter ); solve ( psiConvectionDiffusion + fvc::div(lambda*phiCorr), MULEScontrols ); scalar maxPsiM1 = gMax(psi.internalField()) - 1.0; scalar minPsi = gMin(psi.internalField()); scalar unboundedness = max(max(maxPsiM1, 0.0), -min(minPsi, 0.0)); if (unboundedness < maxUnboundedness) { break; } else { Info<< "MULES: max(" << psi.name() << " - 1) = " << maxPsiM1 << " min(" << psi.name() << ") = " << minPsi << endl; phiBD = psiConvectionDiffusion.flux(); /* word gammaScheme("div(phi,gamma)"); word gammarScheme("div(phirb,gamma)"); const surfaceScalarField& phir = mesh.lookupObject<surfaceScalarField>("phir"); phiCorr = fvc::flux ( phi, psi, gammaScheme ) + fvc::flux ( -fvc::flux(-phir, scalar(1) - psi, gammarScheme), psi, gammarScheme ) - phiBD; */ } } phiPsi = psiConvectionDiffusion.flux() + lambda*phiCorr; }