CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Questions regarding mappedVelocityFluxFidedValue boundary condition (https://www.cfd-online.com/Forums/openfoam-programming-development/126358-questions-regarding-mappedvelocityfluxfidedvalue-boundary-condition.html)

lixx November 14, 2013 22:05

Questions regarding mappedVelocityFluxFidedValue boundary condition
 
Hi Foamers,

I have a question regarding the implementation of mappedVelocityFluxFixedValueFvPatchField::updateCo effs(). The code is listed below:

Code:

  162 void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
  163 {
  164    if (updated())
  165    {
  166        return;
  167    }
  168
  169    // Since we're inside initEvaluate/evaluate there might be processor
  170    // comms underway. Change the tag we use.
  171    int oldTag = UPstream::msgType();
  172    UPstream::msgType() = oldTag+1;
  173
  174    // Get the mappedPatchBase
  175    const mappedPatchBase& mpp = refCast<const mappedPatchBase>
  176    (
  177        mappedVelocityFluxFixedValueFvPatchField::patch().patch()
  178    );
  179    const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
  180    const word& fieldName = dimensionedInternalField().name();
  181    const volVectorField& UField =
  182        nbrMesh.lookupObject<volVectorField>(fieldName);
  183
  184    surfaceScalarField& phiField = const_cast<surfaceScalarField&>
  185    (
  186        nbrMesh.lookupObject<surfaceScalarField>(phiName_)
  187    );
  188
  189    vectorField newUValues;
  190    scalarField newPhiValues;
  191
  192    switch (mpp.mode())
  193    {
  194        case mappedPolyPatch::NEARESTFACE:
  195        {
  196            vectorField allUValues(nbrMesh.nFaces(), vector::zero);
  197            scalarField allPhiValues(nbrMesh.nFaces(), 0.0);
  198
  199            forAll(UField.boundaryField(), patchI)
  200            {
  201                const fvPatchVectorField& Upf = UField.boundaryField()[patchI];
  202                const scalarField& phipf = phiField.boundaryField()[patchI];
  203
  204                label faceStart = Upf.patch().start();
  205
  206                forAll(Upf, faceI)
  207                {
  208                    allUValues[faceStart + faceI] = Upf[faceI];
  209                    allPhiValues[faceStart + faceI] = phipf[faceI];
  210                }
  211            }
  212
  213            mpp.distribute(allUValues);
  214            newUValues.transfer(allUValues);
  215
  216            mpp.distribute(allPhiValues);
  217            newPhiValues.transfer(allPhiValues);
  218
  219            break;
  220        }
  221        case mappedPolyPatch::NEARESTPATCHFACE:
  222        case mappedPolyPatch::NEARESTPATCHFACEAMI:
  223        {
  224            const label nbrPatchID =
  225                nbrMesh.boundaryMesh().findPatchID(mpp.samplePatch());
  226
  227            newUValues = UField.boundaryField()[nbrPatchID];
  228            mpp.distribute(newUValues);
  229
  230            newPhiValues = phiField.boundaryField()[nbrPatchID];
  231            mpp.distribute(newPhiValues);
  232
  233            break;
  234        }
  235        default:
  236        {
  237            FatalErrorIn
  238            (
  239                "mappedVelocityFluxFixedValueFvPatchField::"
  240                "updateCoeffs()"
  241            )  << "patch can only be used in NEARESTPATCHFACE, "
  242                << "NEARESTPATCHFACEAMI or NEARESTFACE mode" << nl
  243                << abort(FatalError);
  244        }
  245    }
  246
  247    operator==(newUValues);
  248    phiField.boundaryField()[patch().index()] == newPhiValues;
  249
  250    // Restore tag
  251    UPstream::msgType() = oldTag;
  252
  253    fixedValueFvPatchVectorField::updateCoeffs();
  254 }

When the sampleMode is set to "nearestFace" (line 194-220), why there is a loop

Code:

199            forAll(UField.boundaryField(), patchI)
  200            {
  201                const fvPatchVectorField& Upf = UField.boundaryField()[patchI];

and why not just directly pass the U and phi on the sampled patch to *this patch?

And Upf here is the boundary field (U field at boundary patches) rather than the U field of the sampled, internal patch (given by the keyword "offset" in file constant/polyMesh/boundary). But later

Code:

206                forAll(Upf, faceI)
  207                {
  208                    allUValues[faceStart + faceI] = Upf[faceI];
  209                    allPhiValues[faceStart + faceI] = phipf[faceI];
  210                }

the value on the boundary (Upf) is stored in allUValues and passed to *this patch. My question is where the sampled patch comes in? I suspect it is the following lines

Code:

  174    // Get the mappedPatchBase
  175    const mappedPatchBase& mpp = refCast<const mappedPatchBase>
  176    (
  177        mappedVelocityFluxFixedValueFvPatchField::patch().patch()
  178    );

but after checking the constructor of class mappedPatchBase, I did not see how it is achieved.

Can anybody give me a hint? Sorry if this is a silly question. I am now trying to implement a new boundary condition based on this one, but still have some problems.

When using pisoFoam, this updateCoeffs() will be called three times during each time step. Is this right? If I want to keep a running average of the sampled patch, should I do it during each call or do it only once during one time step? If latter, how can I do it? By comparing curTimeIndex with db().time().timeIndex()?


All times are GMT -4. The time now is 05:56.