Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::linearUpwind<Type>::correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( "linearUpwind::correction(" + vf.name() + ')', mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr(); const surfaceScalarField& faceFlux = this->faceFlux_; const labelList& owner = mesh.owner(); const labelList& neighbour = mesh.neighbour(); const volVectorField& C = mesh.C(); const surfaceVectorField& Cf = mesh.Cf(); tmp < GeometricField < typename outerProduct<vector, Type>::type, fvPatchField, volMesh > > tgradVf = gradScheme_().grad(vf, gradSchemeName_); const GeometricField < typename outerProduct<vector, Type>::type, fvPatchField, volMesh >& gradVf = tgradVf(); forAll(faceFlux, facei) { label celli = (faceFlux[facei] > 0) ? owner[facei] : neighbour[facei]; sfCorr[facei] = (Cf[facei] - C[celli]) & gradVf[celli]; }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::extendedUpwindCellToFaceStencil::weightedSum ( const surfaceScalarField& phi, const GeometricField<Type, fvPatchField, volMesh>& fld, const List<List<scalar> >& ownWeights, const List<List<scalar> >& neiWeights ) const { const fvMesh& mesh = fld.mesh(); // Collect internal and boundary values List<List<Type> > ownFld; collectData(ownMap(), ownStencil(), fld, ownFld); List<List<Type> > neiFld; collectData(neiMap(), neiStencil(), fld, neiFld); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( fld.name(), mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimensioned<Type> ( fld.name(), fld.dimensions(), pTraits<Type>::zero ) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsfCorr(); // Internal faces for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) { if (phi[faceI] > 0) { // Flux out of owner. Use upwind (= owner side) stencil. const List<Type>& stField = ownFld[faceI]; const List<scalar>& stWeight = ownWeights[faceI]; forAll(stField, i) { sf[faceI] += stField[i]*stWeight[i]; } } else {
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::CLUST<Type>::correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( "CLUST::correction(" + vf.name() + ')', mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr(); const surfaceVectorField& Uf = this->Uf_; //const GeometricField<Type,fvsPatchField,surfaceMesh> gradf=fvc::snGrad(vf); const GeometricField < typename outerProduct<vector, Type>::type, fvPatchField, volMesh > Grad = fvc::grad(vf); forAll(sfCorr, facei) { const scalar un = (Uf[facei] & mesh.Sf()[facei])/mesh.magSf()[facei]; const scalar ub = mag(un)/max(SMALL, mag(Uf[facei])); label celli = un > 0 ? mesh.owner()[facei] : mesh.neighbour()[facei]; label cellj = celli == mesh.owner()[facei] ? mesh.neighbour()[facei] : mesh.owner()[facei]; sfCorr[facei] = 0.5*b_*ub* ( ((mesh.C()[cellj] - mesh.C()[celli]) & Grad[celli]) + vf[celli] - vf[cellj] ); } return tsfCorr; }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::APVM<Type>::correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( "APVM::correction(" + vf.name() + ')', mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr.ref(); const dimensionedScalar& dt = mesh.time().deltaT(); const surfaceVectorField& Uf = this->Uf_; const GeometricField<Type, fvsPatchField, surfaceMesh> gradf = fvc::snGrad(vf); const GeometricField < typename outerProduct<vector, Type>::type, fvsPatchField, surfaceMesh > GradF = fvc::interpolate(fvc::reconstruct(gradf*mesh.magSf())); sfCorr = -0.5*dt*(Uf & GradF); return tsfCorr; }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::linearUpwindV<Type>::correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( vf.name(), mesh.time().timeName(), mesh ), mesh, dimensioned<Type> ( vf.name(), vf.dimensions(), pTraits<Type>::zero ) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr(); const surfaceScalarField& faceFlux = this->faceFlux_; const surfaceScalarField& w = mesh.weights(); const labelList& own = mesh.owner(); const labelList& nei = mesh.neighbour(); const vectorField& C = mesh.C(); const vectorField& Cf = mesh.Cf(); GeometricField <typename outerProduct<vector, Type>::type, fvPatchField, volMesh> gradVf = gradScheme_().grad(vf); forAll(faceFlux, facei) { vector maxCorr; if (faceFlux[facei] > 0.0) { maxCorr = (1.0 - w[facei]) *(vf[nei[facei]] - vf[own[facei]]); sfCorr[facei] = (Cf[facei] - C[own[facei]]) & gradVf[own[facei]]; } else { maxCorr = w[facei]*(vf[own[facei]] - vf[nei[facei]]); sfCorr[facei] = (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]]; } scalar sfCorrs = magSqr(sfCorr[facei]); scalar maxCorrs = sfCorr[facei] & maxCorr; if (sfCorrs > 0) { if (maxCorrs < 0) { sfCorr[facei] = vector::zero; } else if (sfCorrs > maxCorrs) { sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL); } } else if (sfCorrs < 0) { if (maxCorrs > 0) { sfCorr[facei] = vector::zero; } else if (sfCorrs < maxCorrs) { sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL); } } }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::pointLinear<Type>:: correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); GeometricField<Type, pointPatchField, pointMesh> pvf ( volPointInterpolation::New(mesh).interpolate(vf) ); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr = linearInterpolate(vf); Field<Type>& sfCorr = tsfCorr().internalField(); const pointField& points = mesh.points(); const pointField& C = mesh.C().internalField(); const faceList& faces = mesh.faces(); const scalarField& w = mesh.weights().internalField(); const labelList& owner = mesh.owner(); const labelList& neighbour = mesh.neighbour(); forAll(sfCorr, facei) { point pi = w[owner[facei]]*C[owner[facei]] + (1.0 - w[owner[facei]])*C[neighbour[facei]]; scalar at = triangle<point, const point&> ( pi, points[faces[facei][0]], points[faces[facei][faces[facei].size()-1]] ).mag(); scalar sumAt = at; Type sumPsip = at*(1.0/3.0)* ( sfCorr[facei] + pvf[faces[facei][0]] + pvf[faces[facei][faces[facei].size()-1]] ); for (label pointi=1; pointi<faces[facei].size(); pointi++) { at = triangle<point, const point&> ( pi, points[faces[facei][pointi]], points[faces[facei][pointi-1]] ).mag(); sumAt += at; sumPsip += at*(1.0/3.0)* ( sfCorr[facei] + pvf[faces[facei][pointi]] + pvf[faces[facei][pointi-1]] ); } sfCorr[facei] = sumPsip/sumAt - sfCorr[facei]; }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>> Foam::fv::faceCorrectedSnGrad<Type>::fullGradCorrection ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); GeometricField<Type, pointPatchField, pointMesh> pvf ( volPointInterpolation::New(mesh).interpolate(vf) ); // construct GeometricField<Type, fvsPatchField, surfaceMesh> tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( "snGradCorr("+vf.name()+')', vf.instance(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, vf.dimensions()*mesh.nonOrthDeltaCoeffs().dimensions() ) ); Field<Type>& sfCorr = tsfCorr.ref().internalField(); const pointField& points = mesh.points(); const faceList& faces = mesh.faces(); const vectorField& Sf = mesh.Sf().internalField(); const vectorField& C = mesh.C().internalField(); const scalarField& magSf = mesh.magSf().internalField(); const labelList& owner = mesh.owner(); const labelList& neighbour = mesh.neighbour(); forAll(sfCorr, facei) { typename outerProduct<vector, Type>::type fgrad ( outerProduct<vector, Type>::type::zero ); const face& fi = faces[facei]; vector nf(Sf[facei]/magSf[facei]); for (label pi=0; pi<fi.size(); pi++) { // Next point index label pj = (pi+1)%fi.size(); // Edge normal in plane of face vector edgen(nf^(points[fi[pj]] - points[fi[pi]])); // Edge centre field value Type pvfe(0.5*(pvf[fi[pj]] + pvf[fi[pi]])); // Integrate face gradient fgrad += edgen*pvfe; } // Finalize face-gradient by dividing by face area fgrad /= magSf[facei]; // Calculate correction vector vector dCorr(C[neighbour[facei]] - C[owner[facei]]); dCorr /= (nf & dCorr); // if (mag(dCorr) > 2) dCorr *= 2/mag(dCorr); sfCorr[facei] = dCorr&fgrad; }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::linearUpwindV<Type>::correction ( const GeometricField<Type, fvPatchField, volMesh>& vf ) const { const fvMesh& mesh = this->mesh(); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( new GeometricField<Type, fvsPatchField, surfaceMesh> ( IOobject ( "linearUpwindCorrection(" + vf.name() + ')', mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero) ) ); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr(); const surfaceScalarField& faceFlux = this->faceFlux_; const surfaceScalarField& w = mesh.weights(); const labelList& own = mesh.owner(); const labelList& nei = mesh.neighbour(); const volVectorField& C = mesh.C(); const surfaceVectorField& Cf = mesh.Cf(); GeometricField <typename outerProduct<vector, Type>::type, fvPatchField, volMesh> gradVf = gradScheme_().grad(vf); // Note: in order for the patchNeighbourField to be correct on coupled // boundaries, correctBoundaryConditions needs to be called. // The call shall be moved into the library fvc operators gradVf.correctBoundaryConditions(); forAll(faceFlux, facei) { vector maxCorr; if (faceFlux[facei] > 0) { maxCorr = (1 - w[facei])*(vf[nei[facei]] - vf[own[facei]]); sfCorr[facei] = (Cf[facei] - C[own[facei]]) & gradVf[own[facei]]; } else { maxCorr = w[facei]*(vf[own[facei]] - vf[nei[facei]]); sfCorr[facei] = (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]]; } scalar sfCorrs = magSqr(sfCorr[facei]); scalar maxCorrs = sfCorr[facei] & maxCorr; if (sfCorrs > 0) { if (maxCorrs < 0) { sfCorr[facei] = vector::zero; } else if (sfCorrs > maxCorrs) { sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL); } } else if (sfCorrs < 0) { if (maxCorrs > 0) { sfCorr[facei] = vector::zero; } else if (sfCorrs < maxCorrs) { sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL); } } }