View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002057 | OpenFOAM | Bug | public | 2016-04-20 16:14 | 2018-12-31 10:51 |
Reporter | LIGA | Assigned To | henry | ||
Priority | normal | Severity | feature | Reproducibility | always |
Status | resolved | Resolution | reopened | ||
Platform | GNU/Linux | OS | Ubuntu | OS Version | 14.04 |
Product Version | dev | ||||
Fixed in Version | dev | ||||
Summary | 0002057: ACMI incompatible with velocityComponentLaplacian | ||||
Description | A sliding interface between two domains is defined using ACMI. As long as the shape of the two domains remain constant but move with a relative velocity to each other, the ACMI works fine - as seen in the oscillating inlet tutorial. However, when the relative velocity is not obtained from the movement of the entire domain, but by surface mesh changes at the interface, the ACMI doesn't work as expected. Such a situation comes up, when the interface surface mesh is moved/changed as a result of velocityComponentLaplacian-solver. One would expect, that the surface mesh slides along the interface as calculated by the solver. Instead, it sticks at the position where the ACMI is defined. Please feel free to have a look at the attached mp4 file for better understanding. | ||||
Additional Information | If needed, it is possible to provide the whole case with the current settings. | ||||
Tags | ACMI | ||||
|
|
|
It would indeed be useful if you could provide a test-case which demonstrates the issue. |
|
|
|
|
|
Sample case is uploaded. Simply move points file to polyMesh. Thanks |
|
ACMI_conservative.patch (37,275 bytes)
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMesh.C index f15e2b2..28e8ee9 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.C @@ -997,7 +997,7 @@ bool Foam::polyMesh::upToDatePoints(const regIOobject& io) const void Foam::polyMesh::setUpToDatePoints(regIOobject& io) const { - io.eventNo() = points_.eventNo(); + io.eventNo() = points_.eventNo()+1; } diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C index bb8608d..f516b2a 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C @@ -137,22 +137,15 @@ Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const { const Field<Type>& iField = this->primitiveField(); - const labelUList& nbrFaceCellsCoupled = - cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); - const labelUList& faceCellsNonOverlap = - cyclicACMIPatch_.cyclicACMIPatch().nonOverlapPatch().faceCells(); - - Field<Type> pnfCoupled(iField, nbrFaceCellsCoupled); - Field<Type> pfNonOverlap(iField, faceCellsNonOverlap); - + const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch(); tmp<Field<Type>> tpnf ( - new Field<Type> + cyclicACMIPatch_.interpolate ( - cyclicACMIPatch_.interpolate + Field<Type> ( - pnfCoupled, - pfNonOverlap + iField, + cpp.neighbPatch().faceCells() ) ) ); @@ -207,10 +200,12 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix const Pstream::commsTypes ) const { + const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch(); + // note: only applying coupled contribution const labelUList& nbrFaceCellsCoupled = - cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); + cpp.neighbPatch().faceCells(); scalarField pnf(psiInternal, nbrFaceCellsCoupled); @@ -237,10 +232,11 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix const Pstream::commsTypes ) const { + const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch(); + // note: only applying coupled contribution - const labelUList& nbrFaceCellsCoupled = - cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); + const labelUList& nbrFaceCellsCoupled = cpp.neighbPatch().faceCells(); Field<Type> pnf(psiInternal, nbrFaceCellsCoupled); @@ -259,149 +255,6 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix template<class Type> -Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIFvPatchField<Type>::snGrad -( - const scalarField& deltaCoeffs -) const -{ - // note: only applying coupled contribution - return coupledFvPatchField<Type>::snGrad(deltaCoeffs); -} - - -template<class Type> -void Foam::cyclicACMIFvPatchField<Type>::updateCoeffs() -{ - // update non-overlap patch - some will implement updateCoeffs, and - // others will implement evaluate - - // scale neighbour field by (1 - mask) - - const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); - const fvPatchField<Type>& npf = nonOverlapPatchField(); - const_cast<fvPatchField<Type>&>(npf).updateCoeffs(1.0 - mask); -} - - -template<class Type> -void Foam::cyclicACMIFvPatchField<Type>::initEvaluate -( - const Pstream::commsTypes comms -) -{ - // update non-overlap patch (if not already updated by updateCoeffs) - - // scale neighbour field by (1 - mask) - - fvPatchField<Type>& npf = - const_cast<fvPatchField<Type>&>(nonOverlapPatchField()); - - if (!npf.updated()) - { - const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); - - npf.evaluate(comms); - - npf *= 1.0 - mask; - } -} - - -template<class Type> -void Foam::cyclicACMIFvPatchField<Type>::evaluate -( - const Pstream::commsTypes comms -) -{ - // blend contributions from the coupled and non-overlap patches - - // neighbour patch field is updated via updateCoeffs or initEvaluate - // and is already scaled by (1 - mask) - const fvPatchField<Type>& npf = nonOverlapPatchField(); - - coupledFvPatchField<Type>::evaluate(comms); - const Field<Type>& cpf = *this; - - const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); - Field<Type>::operator=(mask*cpf + npf); - - fvPatchField<Type>::evaluate(); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::valueInternalCoeffs -( - const tmp<scalarField>& w -) const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::valueInternalCoeffs(w); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::valueBoundaryCoeffs -( - const tmp<scalarField>& w -) const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::valueBoundaryCoeffs(w); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs -( - const scalarField& deltaCoeffs -) const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::gradientInternalCoeffs(deltaCoeffs); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs() const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::gradientInternalCoeffs(); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs -( - const scalarField& deltaCoeffs -) const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::gradientBoundaryCoeffs(deltaCoeffs); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs() const -{ - // note: do not blend based on mask field - // - when applied this is scaled by the areas which are already scaled - return coupledFvPatchField<Type>::gradientBoundaryCoeffs(); -} - - -template<class Type> void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix ( fvMatrix<Type>& matrix diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H index b17c933..33a6d69 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H @@ -218,63 +218,6 @@ public: const Pstream::commsTypes commsType ) const; - //- Return patch-normal gradient - virtual tmp<Field<Type>> snGrad - ( - const scalarField& deltaCoeffs - ) const; - - //- Update the coefficients associated with the patch field - void updateCoeffs(); - - //- Initialise the evaluation of the patch field - virtual void initEvaluate - ( - const Pstream::commsTypes commsType - ); - - //- Evaluate the patch field - virtual void evaluate - ( - const Pstream::commsTypes commsType - ); - - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueInternalCoeffs - ( - const tmp<scalarField>& - ) const; - - //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueBoundaryCoeffs - ( - const tmp<scalarField>& - ) const; - - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField - virtual tmp<Field<Type>> gradientInternalCoeffs - ( - const scalarField& deltaCoeffs - ) const; - - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField - virtual tmp<Field<Type>> gradientInternalCoeffs() const; - - //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField - virtual tmp<Field<Type>> gradientBoundaryCoeffs - ( - const scalarField& deltaCoeffs - ) const; - - //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField - virtual tmp<Field<Type>> gradientBoundaryCoeffs() const; - //- Manipulate matrix virtual void manipulateMatrix(fvMatrix<Type>& matrix); diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C index 8812cd7..58c23a5 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C @@ -43,7 +43,12 @@ void Foam::cyclicACMIFvPatch::updateAreas() const { if (cyclicACMIPolyPatch_.updated()) { - // Set Sf and magSf for both sides' coupled and non-overlapping patches + if (debug) + { + Pout<< "cyclicACMIFvPatch::updateAreas() : updating fv areas for " + << name() << " and " << this->nonOverlapPatch().name() + << endl; + } // owner couple const_cast<vectorField&>(Sf()) = patch().faceAreas(); @@ -81,25 +86,37 @@ void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const if (coupled()) { const cyclicACMIFvPatch& nbrPatch = neighbFvPatch(); - const fvPatch& nbrPatchNonOverlap = nonOverlapPatch(); - const scalarField deltas(nf() & coupledFvPatch::delta()); - const scalarField nbrDeltas + // These deltas are of the cyclic part alone - they are + // not affected by the amount of overlap with the nonOverlapPatch + scalarField nbrDeltas ( interpolate ( - nbrPatch.nf() & nbrPatch.coupledFvPatch::delta(), - nbrPatchNonOverlap.nf() & nbrPatchNonOverlap.delta() + nbrPatch.nf() & nbrPatch.coupledFvPatch::delta() ) ); + scalar tol = cyclicACMIPolyPatch::tolerance(); + + forAll(deltas, facei) { scalar di = deltas[facei]; scalar dni = nbrDeltas[facei]; - w[facei] = dni/(di + dni); + if (dni < tol) + { + // Avoid zero weights on disconnected faces. This value + // will be weighted with the (zero) face area so will not + // influence calculations. + w[facei] = 1.0; + } + else + { + w[facei] = dni/(di + dni); + } } } else @@ -122,30 +139,12 @@ Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const { if (coupled()) { - const cyclicACMIFvPatch& nbrPatchCoupled = neighbFvPatch(); - const fvPatch& nbrPatchNonOverlap = nonOverlapPatch(); + const cyclicACMIFvPatch& nbrPatch = neighbFvPatch(); const vectorField patchD(coupledFvPatch::delta()); - vectorField nbrPatchD - ( - interpolate - ( - nbrPatchCoupled.coupledFvPatch::delta(), - nbrPatchNonOverlap.delta() - ) - ); - - const vectorField nbrPatchD0 - ( - interpolate - ( - vectorField(nbrPatchCoupled.size(), Zero), - nbrPatchNonOverlap.delta()() - ) - ); + vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta())); - nbrPatchD -= nbrPatchD0; tmp<vectorField> tpdv(new vectorField(patchD.size())); vectorField& pdv = tpdv.ref(); diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index f4bfb00..048ee61 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -174,10 +174,11 @@ public: //- Return delta (P to N) vectors across coupled patch virtual tmp<vectorField> delta() const; + //- Interpolate (make sure to have uptodate areas) template<class Type> tmp<Field<Type>> interpolate ( - const Field<Type>& fldCoupled + const Field<Type>& fld ) const { updateAreas(); @@ -185,57 +186,18 @@ public: return cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate ( - fldCoupled + fld ); } + //- Interpolate (make sure to have uptodate areas) template<class Type> tmp<Field<Type>> interpolate ( - const tmp<Field<Type>>& tfldCoupled + const tmp<Field<Type>>& tfld ) const { - updateAreas(); - - return - cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate - ( - tfldCoupled - ); - } - - template<class Type> - tmp<Field<Type>> interpolate - ( - const Field<Type>& fldCoupled, - const Field<Type>& fldNonOverlap - ) const - { - updateAreas(); - - return - cyclicACMIPolyPatch_.interpolate - ( - fldCoupled, - fldNonOverlap - ); - } - - template<class Type> - tmp<Field<Type>> interpolate - ( - const tmp<Field<Type>>& tFldCoupled, - const tmp<Field<Type>>& tFldNonOverlap - ) const - { - updateAreas(); - - return - cyclicACMIPolyPatch_.interpolate - ( - tFldCoupled, - tFldNonOverlap - ); + return interpolate(tfld()); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H index 8de6e4f..a2a1449 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H @@ -378,10 +378,17 @@ public: //- Return const access to source patch weights inline const scalarListList& srcWeights() const; + //- Return access to source patch weights + inline scalarListList& srcWeights(); + //- Return const access to normalisation factor of source // patch weights (i.e. the sum before normalisation) inline const scalarField& srcWeightsSum() const; + //- Return access to normalisation factor of source + // patch weights (i.e. the sum before normalisation) + inline scalarField& srcWeightsSum(); + //- Source map pointer - valid only if singlePatchProc = -1 // This gets source data into a form to be consumed by // tgtAddress, tgtWeights @@ -399,10 +406,17 @@ public: //- Return const access to target patch weights inline const scalarListList& tgtWeights() const; + //- Return access to target patch weights + inline scalarListList& tgtWeights(); + //- Return const access to normalisation factor of target // patch weights (i.e. the sum before normalisation) inline const scalarField& tgtWeightsSum() const; + //- Return access to normalisation factor of target + // patch weights (i.e. the sum before normalisation) + inline scalarField& tgtWeightsSum(); + //- Target map pointer - valid only if singlePatchProc=-1. // This gets target data into a form to be consumed by // srcAddress, srcWeights diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H index 9c59cb6..5e74e7b 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H @@ -73,6 +73,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const template<class SourcePatch, class TargetPatch> +inline Foam::scalarListList& +Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() +{ + return srcWeights_; +} + + +template<class SourcePatch, class TargetPatch> inline const Foam::scalarField& Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const { @@ -81,6 +89,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const template<class SourcePatch, class TargetPatch> +inline Foam::scalarField& +Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() +{ + return srcWeightsSum_; +} + + +template<class SourcePatch, class TargetPatch> inline const Foam::mapDistribute& Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const { @@ -113,6 +129,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const template<class SourcePatch, class TargetPatch> +inline Foam::scalarListList& +Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() +{ + return tgtWeights_; +} + + +template<class SourcePatch, class TargetPatch> inline const Foam::scalarField& Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const { @@ -121,6 +145,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const template<class SourcePatch, class TargetPatch> +inline Foam::scalarField& +Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() +{ + return tgtWeightsSum_; +} + + +template<class SourcePatch, class TargetPatch> inline const Foam::mapDistribute& Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const { diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C index 382faaf..2c0af3c 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C @@ -38,35 +38,10 @@ namespace Foam addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, dictionary); } -const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-6; +const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-10; // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::cyclicACMIPolyPatch::initPatchFaceAreas() const -{ - if - ( - !empty() - && (faceAreas0_.empty() || boundaryMesh().mesh().moving()) - ) - { - faceAreas0_ = faceAreas(); - } - - const cyclicACMIPolyPatch& nbrACMI = - refCast<const cyclicACMIPolyPatch>(this->neighbPatch()); - - if - ( - !nbrACMI.empty() - && (nbrACMI.faceAreas0().empty() || boundaryMesh().mesh().moving()) - ) - { - nbrACMI.faceAreas0_ = nbrACMI.faceAreas(); - } -} - - void Foam::cyclicACMIPolyPatch::resetAMI ( const AMIPatchToPatchInterpolation::interpolationMethod& @@ -76,74 +51,116 @@ void Foam::cyclicACMIPolyPatch::resetAMI { const polyPatch& nonOverlapPatch = this->nonOverlapPatch(); - initPatchFaceAreas(); - - // Reset patch face areas based on original patch for AMI calculation - vectorField::subField Sf = faceAreas(); - vectorField::subField noSf = nonOverlapPatch.faceAreas(); - - forAll(Sf, facei) + if (debug) { - Sf[facei] = faceAreas0_[facei]; - noSf[facei] = faceAreas0_[facei]; + Pout<< "cyclicACMIPolyPatch::resetAMI : recalculating weights" + << " for " << name() << " and " << nonOverlapPatch.name() + << endl; } - // Calculate the AMI using partial face-area-weighted + // Trigger re-building of faceAreas + (void)boundaryMesh().mesh().faceAreas(); + + + // Calculate the AMI using partial face-area-weighted. This leaves + // the weights as fractions of local areas (sum(weights) = 1 means + // face is fully covered) cyclicAMIPolyPatch::resetAMI ( AMIPatchToPatchInterpolation::imPartialFaceAreaWeight ); + AMIPatchToPatchInterpolation& AMI = + const_cast<AMIPatchToPatchInterpolation&>(this->AMI()); + srcMask_ = - min(scalar(1) - tolerance_, max(tolerance_, AMI().srcWeightsSum())); + min(scalar(1) - tolerance_, max(tolerance_, AMI.srcWeightsSum())); tgtMask_ = - min(scalar(1) - tolerance_, max(tolerance_, AMI().tgtWeightsSum())); - - forAll(Sf, facei) - { - Sf[facei] *= srcMask_[facei]; - noSf[facei] *= 1.0 - srcMask_[facei]; - } + min(scalar(1) - tolerance_, max(tolerance_, AMI.tgtWeightsSum())); - setNeighbourFaceAreas(); - // Set the updated flag - updated_ = true; - } -} + // Adapt owner side areas. Note that in uncoupled situations (e.g. + // decomposePar) srcMask, tgtMask can be zero size. + if (srcMask_.size()) + { + vectorField::subField Sf = faceAreas(); + vectorField::subField noSf = nonOverlapPatch.faceAreas(); + forAll(Sf, facei) + { + Sf[facei] *= srcMask_[facei]; + noSf[facei] *= 1.0 - srcMask_[facei]; + } + } + // Adapt slave side areas + if (tgtMask_.size()) + { + const cyclicACMIPolyPatch& cp = + refCast<const cyclicACMIPolyPatch>(this->neighbPatch()); + const polyPatch& pp = cp.nonOverlapPatch(); -void Foam::cyclicACMIPolyPatch::setNeighbourFaceAreas() const -{ - const cyclicACMIPolyPatch& cp = - refCast<const cyclicACMIPolyPatch>(this->neighbPatch()); - const polyPatch& pp = cp.nonOverlapPatch(); + vectorField::subField Sf = cp.faceAreas(); + vectorField::subField noSf = pp.faceAreas(); - const vectorField& faceAreas0 = cp.faceAreas0(); + forAll(Sf, facei) + { + Sf[facei] *= tgtMask_[facei]; + noSf[facei] *= 1.0 - tgtMask_[facei]; + } + } - if (tgtMask_.size() == cp.size()) - { - vectorField::subField Sf = cp.faceAreas(); - vectorField::subField noSf = pp.faceAreas(); + // Re-normalise the weights since the effect of overlap is already + // accounted for in the area. + { + scalarListList& srcWeights = AMI.srcWeights(); + scalarField& srcWeightsSum = AMI.srcWeightsSum(); + forAll(srcWeights, i) + { + scalarList& wghts = srcWeights[i]; + if (wghts.size()) + { + scalar& sum = srcWeightsSum[i]; - forAll(Sf, facei) + forAll(wghts, j) + { + wghts[j] /= sum; + } + sum = 1.0; + } + } + } { - Sf[facei] = tgtMask_[facei]*faceAreas0[facei]; - noSf[facei] = (1.0 - tgtMask_[facei])*faceAreas0[facei]; + scalarListList& tgtWeights = AMI.tgtWeights(); + scalarField& tgtWeightsSum = AMI.tgtWeightsSum(); + forAll(tgtWeights, i) + { + scalarList& wghts = tgtWeights[i]; + if (wghts.size()) + { + scalar& sum = tgtWeightsSum[i]; + forAll(wghts, j) + { + wghts[j] /= sum; + } + sum = 1.0; + } + } } - } - else - { - WarningInFunction - << "Target mask size differs to that of the neighbour patch\n" - << " May occur when decomposing." << endl; + + // Set the updated flag + updated_ = true; } } void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::initGeometry : " << name() << endl; + } + cyclicAMIPolyPatch::initGeometry(pBufs); // Initialise the AMI @@ -153,6 +170,10 @@ void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs) void Foam::cyclicACMIPolyPatch::calcGeometry(PstreamBuffers& pBufs) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::calcGeometry : " << name() << endl; + } cyclicAMIPolyPatch::calcGeometry(pBufs); } @@ -163,6 +184,10 @@ void Foam::cyclicACMIPolyPatch::initMovePoints const pointField& p ) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::initMovePoints : " << name() << endl; + } cyclicAMIPolyPatch::initMovePoints(pBufs, p); // Initialise the AMI @@ -176,24 +201,40 @@ void Foam::cyclicACMIPolyPatch::movePoints const pointField& p ) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::movePoints : " << name() << endl; + } cyclicAMIPolyPatch::movePoints(pBufs, p); } void Foam::cyclicACMIPolyPatch::initUpdateMesh(PstreamBuffers& pBufs) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::initUpdateMesh : " << name() << endl; + } cyclicAMIPolyPatch::initUpdateMesh(pBufs); } void Foam::cyclicACMIPolyPatch::updateMesh(PstreamBuffers& pBufs) { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::updateMesh : " << name() << endl; + } cyclicAMIPolyPatch::updateMesh(pBufs); } void Foam::cyclicACMIPolyPatch::clearGeom() { + if (debug) + { + Pout<< "cyclicACMIPolyPatch::clearGeom : " << name() << endl; + } cyclicAMIPolyPatch::clearGeom(); } @@ -224,7 +265,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch ) : cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform), - faceAreas0_(), nonOverlapPatchName_(word::null), nonOverlapPatchID_(-1), srcMask_(), @@ -248,7 +288,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch ) : cyclicAMIPolyPatch(name, dict, index, bm, patchType), - faceAreas0_(), nonOverlapPatchName_(dict.lookup("nonOverlapPatch")), nonOverlapPatchID_(-1), srcMask_(), @@ -279,7 +318,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch ) : cyclicAMIPolyPatch(pp, bm), - faceAreas0_(), nonOverlapPatchName_(pp.nonOverlapPatchName_), nonOverlapPatchID_(-1), srcMask_(), @@ -305,7 +343,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch ) : cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName), - faceAreas0_(), nonOverlapPatchName_(nonOverlapPatchName), nonOverlapPatchID_(-1), srcMask_(), @@ -337,7 +374,6 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch ) : cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart), - faceAreas0_(), nonOverlapPatchName_(pp.nonOverlapPatchName_), nonOverlapPatchID_(-1), srcMask_(), diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H index 987adc4..5e21fb5 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H @@ -57,8 +57,8 @@ private: // Private data - //- Copy of the original patch face areas - mutable vectorField faceAreas0_; + //- Fraction of face area below which face is considered disconnected + static const scalar tolerance_; //- Name of non-overlapping patch const word nonOverlapPatchName_; @@ -78,14 +78,8 @@ private: protected: - static const scalar tolerance_; - - // Protected Member Functions - //- Initialise patch face areas - virtual void initPatchFaceAreas() const; - //- Reset the AMI interpolator virtual void resetAMI ( @@ -93,9 +87,6 @@ protected: AMIPatchToPatchInterpolation::imFaceAreaWeight ) const; - //- Set neighbour ACMI patch areas - virtual void setNeighbourFaceAreas() const; - //- Initialise the calculation of the patch geometry virtual void initGeometry(PstreamBuffers&); @@ -254,9 +245,6 @@ public: //- Return access to the updated flag inline bool updated() const; - //- Return access to the original patch face areas - inline const vectorField& faceAreas0() const; - //- Return a reference to the neighbour patch virtual const cyclicACMIPolyPatch& neighbPatch() const; @@ -275,34 +263,8 @@ public: //- Mask field where 1 = overlap, 0 = no-overlap inline const scalarField& mask() const; - - // Interpolations - - //- Interpolate field - template<class Type> - tmp<Field<Type>> interpolate - ( - const Field<Type>& fldCouple, - const Field<Type>& fldNonOverlap - ) const; - - //- Interpolate tmp field - template<class Type> - tmp<Field<Type>> interpolate - ( - const tmp<Field<Type>>& tFldCouple, - const tmp<Field<Type>>& tFldNonOverlap - ) const; - - //- Low-level interpolate List - template<class Type, class CombineOp> - void interpolate - ( - const UList<Type>& fldCouple, - const UList<Type>& fldNonOverlap, - const CombineOp& cop, - List<Type>& result - ) const; + //- Overlap tolerance + inline static scalar tolerance(); //- Calculate the patch geometry @@ -353,12 +315,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "cyclicACMIPolyPatchTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H index 07f6b07..6efbb7b 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,12 +37,6 @@ inline bool Foam::cyclicACMIPolyPatch::updated() const } -inline const Foam::vectorField& Foam::cyclicACMIPolyPatch::faceAreas0() const -{ - return faceAreas0_; -} - - inline const Foam::word& Foam::cyclicACMIPolyPatch::nonOverlapPatchName() const { return nonOverlapPatchName_; @@ -80,4 +74,10 @@ inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const } +inline Foam::scalar Foam::cyclicACMIPolyPatch::tolerance() +{ + return tolerance_; +} + + // ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C deleted file mode 100644 index 336e8ca..0000000 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C +++ /dev/null @@ -1,87 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -template<class Type> -Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIPolyPatch::interpolate -( - const Field<Type>& fldCouple, - const Field<Type>& fldNonOverlap -) const -{ - // Note: do not scale AMI field as face areas have already been taken into - // account - - if (owner()) - { - return - AMI().interpolateToSource(fldCouple) - + (1.0 - AMI().srcWeightsSum())*fldNonOverlap; - } - else - { - return - neighbPatch().AMI().interpolateToTarget(fldCouple) - + (1.0 - neighbPatch().AMI().tgtWeightsSum())*fldNonOverlap; - } -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> Foam::cyclicACMIPolyPatch::interpolate -( - const tmp<Field<Type>>& tFldCouple, - const tmp<Field<Type>>& tFldNonOverlap -) const -{ - return interpolate(tFldCouple(), tFldNonOverlap()); -} - - -template<class Type, class CombineOp> -void Foam::cyclicACMIPolyPatch::interpolate -( - const UList<Type>& fldCouple, - const UList<Type>& fldNonOverlap, - const CombineOp& cop, - List<Type>& result -) const -{ - // Note: do not scale AMI field as face areas have already been taken into - // account - - if (owner()) - { - AMI().interpolateToSource(fldCouple, cop, result); - result += (1.0 - AMI().srcWeightsSum())*fldNonOverlap; - } - else - { - neighbPatch().AMI().interpolateToTarget(fldCouple, cop, result); - result += (1.0 - neighbPatch().AMI().tgtWeightsSum())*fldNonOverlap; - } -} - - -// ************************************************************************* // |
|
I've uploaded a patch (on today's dev) which fixes a non-conservation issue with ACMI. On the oscillatingACMI tutorial I can e.g. get outflow of 0.0399359 (with inflow 0.04) by just lowering the solver tolerance. Could you try this on your mesh motion case? Changes: - the only effect of the partial overlap is on the face areas - all other properties (value, snGrad, etc) of the ACMI part are just like AMI so behave as if fully covered; there is no more interpolation of the value between ACMI part and non-overlap part |
|
Ran #2057 with this and I get uniform temperature in whole domain (not sure if this was the purpose of that case) |
|
@MattijsJ: thank you for your effort. In my case I am struggling at combining ACMI with mesh deformation. |
|
So what happens with the patch? What motion solver are you using? Does this use a finite-volume motion solver (e.g. displacementLaplacian)? If so you get additionally the whole issue of interpolating cell values to points. |
|
I am using velocityComponentLaplacian for the motion. Are you able to downlaod any of my attached files? |
|
The problem is indeed in the selected motion solver (velocityComponentLaplacian). It uses volPointInterpolation to go from a cell-based velocity to the point motion. The interpolation will most likely do slightly different things depending on the coupling state and this will amplify any errors. Since your motion is quite simple you could try one of the point based ones, e.g.src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.H It requires faceZones for all the patches in the z direction and tables for the motion of these faceZones. It will then interpolate the motion according to the distance to these faceZones. You'll have to experiment a bit with the setup; it is not used in any tutorial. |
|
Resolved by commit 691e7186b4287cc38b259cae6edcdc53f63807be |
|
I Downloaded and compiled the newest dev-version (after corresponding commit) in order to try the solution to the current ACMI Problem. Unfortunately I get the following error both by the solver AND paraview. Paraview: --> FOAM FATAL IO ERROR: Expected a ')' while reading binaryBlock, found on line 20 an error file: /home/liggieri/work/Hilti/.../versionTests/ofDev/ACMI-exhaust/constant/polyMesh/faces at line 20. From function Foam::Istream& Foam::Istream::readEnd(const char*) in file db/IOstreams/IOstreams/Istream.C at line 109. FOAM exiting ---------------------------------------------------------------------------- pimpleDymFoam: Create time Create mesh for time = 0 Selecting dynamicFvMesh dynamicMotionSolverFvMesh --> FOAM FATAL IO ERROR: Expected a ')' while reading binaryBlock, found on line 20 an error file: /home/liggieri/work/Hilti/.../versionTests/ofDev/ACMI-exhaust/constant/polyMesh/faces at line 20. From function Foam::Istream& Foam::Istream::readEnd(const char*) in file db/IOstreams/IOstreams/Istream.C at line 109. FOAM exiting Is this issue a cause of the "wrongly" specified motion solver as posted by MattijsJ? Should this be fixed as long as displacementInterpolationMotionSolver is specified in the case? Note: the installation is fine, since other cases without ACMI patches run and are viewed correctly. |
|
Does the oscillatingInletACMI2D work for you now? |
|
yes it does. I am testing the dev-version with the case attached in the curent issue (ACMI-exhaust_OF.tar.gz + points) which I can load and run with OF231,OF30 and OFv3.0+. |
|
- downloaded your case and points - moved points to constant/polyMesh - ran pimpleDyMFoam for a few iterations with current dev and see no problems. I've uploaded the log file. |
|
Thanks for the feedback. Dev-version is running properly now. But the issue explained here is still there. I'm afraid we are mixing up issues here. The core problem from a user point of view here is that the ACMI can't be used as a sliding interface when mesh deformation is applied at the same time. As far as I understand, the resolved part of the ACMI reported now is related to conservation problems due to partially overlapping faces. Although this is a clear advancement, unfortunately, it doesn't seem to solve the problem reported here - namely the use of ACMI as sliding interface in combination with velocityComponentLaplacian. The proposed workaround by using displacementInterpolationMotionSolver.H might work for motions which can be prescribed in advance and which are NOT a consequence of any calculation result during the simulation. E.g. in the current case (the model attached here is basically a moving piston - for simplification purposes it currently moves with constant velocity), in the final model the mesh would move as a function of the pressure on a patch. However, the table only contains prescribed values which cannot change during the case is running. So I think, if this OF version is supposed to be able to model scavenging ports in combination with combustion, which is a very common concept in two-stroke engines, there is no way around fixing this as explained here - namely by using ACMI with velocityComponentLaplacian. |
|
The problem in your setup comes from the interpolation of the mesh velocity field (pointMotionUx (or pointMotionUy or ..z) onto the cell based field (for boundary conditions of solving) and back onto the points. See what happens if you provide a 0/cellMotionUx as well as a 0/pointMotionUx and make sure to set the patch types as the ACMI in this volScalarField to e.g. zeroGradient, e.g. instead of type cyclicACMI; do type zeroGradient; patchType cyclicACMI; (the patchType is needed to 'tell' the code that you are overriding a constraint patch) |
|
I have prepared a simple modification of the oscillatingInletACMI, with deforming mesh, and with the suggestion in the last note by MattijsjJ. It is not working. I agree that the problem seems to be the velocity laplacian solver.And, also, I agree with LIGA that the interpolationDisplacement solver is not the solution, since the motion is not prescribed. |
|
|
|
I tried to apply the patch and I get these errors: patching file src/OpenFOAM/meshes/polyMesh/polyMesh.C Hunk #1 succeeded at 1053 (offset 56 lines). patching file src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C Hunk #1 FAILED at 137. Hunk #2 succeeded at 215 (offset 15 lines). Hunk #3 succeeded at 247 (offset 15 lines). Hunk #4 FAILED at 270. 2 out of 4 hunks FAILED -- saving rejects to file src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C.rej patching file src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H Reversed (or previously applied) patch detected! Assume -R? [n] y Hunk #1 succeeded at 275 with fuzz 2 (offset 57 lines). patching file src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C Hunk #2 FAILED at 86. Hunk #3 FAILED at 139. 2 out of 3 hunks FAILED -- saving rejects to file src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C.rej patching file src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H Hunk #1 FAILED at 174. Hunk #2 FAILED at 186. 2 out of 2 hunks FAILED -- saving rejects to file src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H.rej patching file src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H patching file src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H patching file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C Hunk #1 FAILED at 38. Hunk #2 FAILED at 51. Hunk #3 succeeded at 163 (offset -7 lines). Hunk #4 succeeded at 177 with fuzz 2 (offset -7 lines). Hunk #5 succeeded at 191 (offset -10 lines). Hunk #6 succeeded at 255 (offset -10 lines). Hunk #7 succeeded at 278 (offset -10 lines). Hunk #8 succeeded at 316 (offset -2 lines). Hunk #9 succeeded at 341 (offset -2 lines). Hunk #10 succeeded at 380 (offset 6 lines). 2 out of 10 hunks FAILED -- saving rejects to file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C.rej patching file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H Hunk #5 FAILED at 263. 1 out of 6 hunks FAILED -- saving rejects to file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H.rej patching file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H patching file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C Reversed (or previously applied) patch detected! Assume -R? [n] y Patch attempted to create file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C, which already exists. Hunk #1 FAILED at 1. 1 out of 1 hunk FAILED -- saving rejects to file src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C.rej I tried with versions 2.3.1, 2.4.0 and 3.0.1. For now, I can apply the patch by hand, since it is not big, but I wonder if this patch should be applied on another source tree other than which I have installed. |
|
The patch is specific to dev (of a few weeks ago). It is already merged into dev so if you download that version you get the latest. If you want to patch a previous version you'll probably have to do it 'by hand' e.g. a 3-way diff (e.g. kdiff3) and see what the textual changes are and apply these to your version. |
|
Yes, I was presuming so. I have already applied the patch by hand, but I have still not tested it. In reference to the problem of the mesh deformation in the ACMI, I am not an expert and I don't know how to do that, but I suspect that the problem is in volPointInterpolation::interpolate. The interpolation is made with all the cells owning the point. If there could be a way to say to the function to make the interpolation only with a part of the cells (for instance with a cell zone) I think it could work. |
|
I just pulled the latest updates for the dev version of OpenFOAM, compiled it and ran the ACMI-exhaust_OF example case by LIGA. It looks like ACMI still does not work with deforming mesh. The internal mesh near the ACMI interface becomes distorted and finally the solver crashes. Decreasing the timestep does not affect the solution. |
|
The problem is probably related to volPointInterpolation. In this interpolation the big problem with ACMI is that the points are also on 'normal' patches so it is not clear which contribution to take. A workaround is to look at the values on the 'normal' patches only. This at least produces a linear-consistent field. If you replace src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.C with attached you can experiment with this. cyclicACMIPointPatchField.C (7,659 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. \*---------------------------------------------------------------------------*/ #include "cyclicACMIPointPatchField.H" #include "Swap.H" #include "transformField.H" #include "pointFields.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class Type> Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField ( const pointPatch& p, const DimensionedField<Type, pointMesh>& iF ) : coupledPointPatchField<Type>(p, iF), cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), ppiPtr_(nullptr), nbrPpiPtr_(nullptr) {} template<class Type> Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField ( const pointPatch& p, const DimensionedField<Type, pointMesh>& iF, const dictionary& dict ) : coupledPointPatchField<Type>(p, iF, dict), cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), ppiPtr_(nullptr), nbrPpiPtr_(nullptr) { if (!isType<cyclicACMIPointPatch>(p)) { FatalIOErrorInFunction ( dict ) << "patch " << this->patch().index() << " not cyclicACMI type. " << "Patch type = " << p.type() << exit(FatalIOError); } } template<class Type> Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField ( const cyclicACMIPointPatchField<Type>& ptf, const pointPatch& p, const DimensionedField<Type, pointMesh>& iF, const pointPatchFieldMapper& mapper ) : coupledPointPatchField<Type>(ptf, p, iF, mapper), cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), ppiPtr_(nullptr), nbrPpiPtr_(nullptr) { if (!isType<cyclicACMIPointPatch>(this->patch())) { FatalErrorInFunction << "Field type does not correspond to patch type for patch " << this->patch().index() << "." << endl << "Field type: " << typeName << endl << "Patch type: " << this->patch().type() << exit(FatalError); } } template<class Type> Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField ( const cyclicACMIPointPatchField<Type>& ptf, const DimensionedField<Type, pointMesh>& iF ) : coupledPointPatchField<Type>(ptf, iF), cyclicACMIPatch_(ptf.cyclicACMIPatch_), ppiPtr_(nullptr), nbrPpiPtr_(nullptr) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> void Foam::cyclicACMIPointPatchField<Type>::swapAddSeparated ( const Pstream::commsTypes, Field<Type>& pField ) const { // if (cyclicACMIPatch_.cyclicACMIPatch().owner()) // { // // We inplace modify pField. To prevent the other side (which gets // // evaluated at a later date) using already changed values we do // // all swaps on the side that gets evaluated first. // // // // Get neighbouring pointPatch // const cyclicACMIPointPatch& nbrPatch = cyclicACMIPatch_.neighbPatch(); // // // Get neighbouring pointPatchField // const GeometricField<Type, pointPatchField, pointMesh>& fld = // refCast<const GeometricField<Type, pointPatchField, pointMesh>> // ( // this->internalField() // ); // // const cyclicACMIPointPatchField<Type>& nbr = // refCast<const cyclicACMIPointPatchField<Type>> // ( // fld.boundaryField()[nbrPatch.index()] // ); // // // Field<Type> ptFld(this->patchInternalField(pField)); // Field<Type> nbrPtFld(nbr.patchInternalField(pField)); // // InfoInFunction << "patch:" << cyclicACMIPatch_.name() << endl; // //InfoInFunction << "pointField:" << ptFld << endl; // forAll(cyclicACMIPatch_.localPoints(), i) // { // Pout<< " at:" << cyclicACMIPatch_.localPoints()[i] // << " pointField:" << ptFld[i] << endl; // } // // InfoInFunction << "nbrpatch:" << nbrPatch.name() << endl; // forAll(nbrPatch.localPoints(), i) // { // Pout<< " at:" << nbrPatch.localPoints()[i] // << " nbrPointField:" << nbrPtFld[i] << endl; // } // // // if (doTransform()) // { // const tensor& forwardT = this->forwardT()[0]; // const tensor& reverseT = this->reverseT()[0]; // // transform(ptFld, reverseT, ptFld); // transform(nbrPtFld, forwardT, nbrPtFld); // } // // // convert point field to face field, AMI interpolate, then // // face back to point // { // // add neighbour side contribution to owner // Field<Type> nbrFcFld(nbrPpi().pointToFaceInterpolate(nbrPtFld)); // // InfoInFunction << "nbrFaceField:" << nbrFcFld << endl; // // const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch(); // // // interpolate to owner // nbrFcFld = cami.interpolate(nbrFcFld); // // InfoInFunction << "ACMI interpolated nbrFaceField:" << nbrFcFld // << endl; // InfoInFunction << "local contribution:" // << ppi().faceToPointInterpolate(nbrFcFld)() // << endl; // // // add to internal field // this->addToInternalField // ( // pField, // ppi().faceToPointInterpolate(nbrFcFld)() // ); // // Field<Type> newFld(this->patchInternalField(pField)); // InfoInFunction << "After adding patch:" << cyclicACMIPatch_.name() // << endl; // forAll(cyclicACMIPatch_.localPoints(), i) // { // Pout<< " at:" << cyclicACMIPatch_.localPoints()[i] // << " pointField:" << newFld[i] << endl; // } // } // // { // // add owner side contribution to neighbour // Field<Type> fcFld(ppi().pointToFaceInterpolate(ptFld)); // // const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch(); // // // interpolate to neighbour // fcFld = cami.neighbPatch().cyclicAMIPolyPatch::interpolate(fcFld); // // // add to internal field // nbr.addToInternalField // ( // pField, // nbrPpi().faceToPointInterpolate(fcFld)() // ); // } // } } // ************************************************************************* // |
|
I replaced the cyclicACMIPointPatchField.C and recompiled OpenFOAM. The version with the body of the member function commented out (the one provided by MattijsJ) produced the same result as the unmodified version(?). It looks like the pointMotion and cellMotion field are leaking from the deforming part of the mesh through the ACMI interface to the nondeforming part (see the animations of the ACMI-exhaust_OF and another example cases). Playing with the InfoInFunction requires more work. Any ideas what to try next? |
|
Hi all, I just want to jump in here. The problem seems to be the same one as I reported once: https://bugs.openfoam.org/view.php?id=2155 As far as the ACMI is coupled, one gets the point and cell fields (which are related to the motion) coupled with the static one and thus, we get errors. Such in my 2-Stroke-Engine-Case I uploaded a few month ago (I check if I have it somewhere else, to enable the download again). @MattijsJ, during that time, you also told me to overwrite the patch entries of the pointMotion or cellMotion field to zeroGradient. However, the interpolation was still applied. I hope I got the point of the problem here (ACMI.mp4 + the comments here). However, I did not have time to investigate into that, and will not have time the next weeks. I just wanted to give the link to the last discussion. Tobi |
|
Hi, is there any progress in this issue? I was trying to make this case work in the newest dev version and it still doesn't work. It is a quite an old "issue report" without a conclusion - moreover, it seems to me that the newest OpenFOAM-dev has different implementation of ACMI (cyclicACMIPointPatchField.C file is not present in the newest dev anymore). Is it possible to fix it? Or am I wrong and it shall work in the newest OF-dev? Thanks Jirka |
|
As far as I know, the majority for the open reports regarding AMI and ACMI are pending funding. A strategy/plan to solve the issues AMI and ACMI already exists, but it's pending funding. This was one of the topics mentioned on the Open Day last month: https://openfoam.org/events/open-day-2018/ - I believe the recordings of the sessions will be up sometime soon... |
|
The implementation hasn't changed. cyclicACMIPointPatchField.C was removed because the code was almost entirely duplicated in cyclicAMIPointPatchField.C. The latter is now the only implementation. The problems with running this case, as I see it, are as follows: First, a cellMotionUz field is needed with appropriate "patchType" entries in the coupled patches, in order to prevent the solution of the motion from coupling across the ACMI. This is all nice and possible with the code as it is. Second, the temporary "sumWeights" point field in volPointInterpolation.C needs de-coupling in the same way. There is no mechanism to do this at present; volPointInterpolation would need to change significantly. The weights are computed and cached in advance of interpolating the field. This assumes that the constraint patch types are applied to the field as they are to the mesh, so it doesn't work if the field specifies "patchType" entries. The boundary weights would need re-computing in this case. Finally, there is a tiny problem in (what is now) cyclicAMIPointPatchField.C in that it is checking the type of the underlying patch a bit too exactly. Now, with the AMI and ACMI implementations merged, it needs to be a bit more flexible and accept derivations. This is trivial to fix (just replace the isType-s with isA-s). I'll do this tomorrow. |
|
I've made the necessary changes to dev, so if you have "patchType" entries set correctly in both the cell and point motion fields, it should now work. Attached is a modified version of the provided case that shows it working. Just run "moveDynamicMesh". |
|
Resolved in dev by commit a0a88d66 |
Date Modified | Username | Field | Change |
---|---|---|---|
2016-04-20 16:14 | LIGA | New Issue | |
2016-04-20 16:14 | LIGA | File Added: ACMI.mp4 | |
2016-04-20 16:39 | henry | Priority | urgent => normal |
2016-04-21 22:27 | wyldckat | Tag Attached: ACMI | |
2016-05-03 17:39 | henry | Product Version | 3.0.0 => dev |
2016-05-03 17:40 | henry | Note Added: 0006224 | |
2016-05-04 09:35 | LIGA | File Added: ACMI-exhaust_OF.tar.gz | |
2016-05-04 09:35 | LIGA | File Added: points | |
2016-05-04 09:37 | LIGA | Note Added: 0006227 | |
2016-05-04 09:52 | henry | Note Edited: 0006224 | |
2016-05-04 11:03 | henry | Relationship added | has duplicate 0002082 |
2016-05-19 17:39 | MattijsJ | File Added: ACMI_conservative.patch | |
2016-05-19 17:44 | MattijsJ | Note Added: 0006294 | |
2016-05-19 18:02 | MattijsJ | Note Added: 0006295 | |
2016-05-24 16:24 | LIGA | Note Added: 0006312 | |
2016-05-24 16:45 | MattijsJ | Note Added: 0006313 | |
2016-05-24 16:49 | LIGA | Note Added: 0006314 | |
2016-05-24 18:36 | MattijsJ | Note Added: 0006315 | |
2016-05-30 08:31 | henry | Note Added: 0006332 | |
2016-05-30 08:31 | henry | Status | new => resolved |
2016-05-30 08:31 | henry | Fixed in Version | => dev |
2016-05-30 08:31 | henry | Resolution | open => fixed |
2016-05-30 08:31 | henry | Assigned To | => henry |
2016-05-30 17:19 | LIGA | Note Added: 0006338 | |
2016-05-30 17:19 | LIGA | Status | resolved => feedback |
2016-05-30 17:19 | LIGA | Resolution | fixed => reopened |
2016-05-31 11:13 | MattijsJ | Note Added: 0006340 | |
2016-05-31 12:39 | LIGA | Note Added: 0006341 | |
2016-05-31 12:39 | LIGA | Status | feedback => assigned |
2016-05-31 16:27 | MattijsJ | Note Added: 0006347 | |
2016-05-31 17:20 | henry | Status | assigned => resolved |
2016-05-31 17:20 | henry | Resolution | reopened => fixed |
2016-06-01 08:51 | LIGA | Note Added: 0006351 | |
2016-06-01 08:51 | LIGA | Status | resolved => feedback |
2016-06-01 08:51 | LIGA | Resolution | fixed => reopened |
2016-06-01 09:10 | LIGA | Note Edited: 0006351 | |
2016-06-01 09:11 | LIGA | Note Edited: 0006351 | |
2016-06-02 10:36 | henry | Relationship added | has duplicate 0002109 |
2016-06-03 10:19 | MattijsJ | Note Added: 0006362 | |
2016-06-04 19:14 | rcl | Note Added: 0006371 | |
2016-06-04 19:15 | rcl | File Added: deformingInletACMI2DTesting.tar.gz | |
2016-06-09 08:41 | rcl | Note Added: 0006417 | |
2016-06-10 09:20 | MattijsJ | Note Added: 0006419 | |
2016-06-10 10:08 | rcl | Note Added: 0006420 | |
2016-08-17 19:00 | jskortel | Note Added: 0006698 | |
2016-09-16 14:20 | MattijsJ | File Added: cyclicACMIPointPatchField.C | |
2016-09-16 14:20 | MattijsJ | Note Added: 0006871 | |
2016-09-25 19:24 | jskortel | File Added: example_videos.tar.gz | |
2016-09-25 19:24 | jskortel | Note Added: 0006923 | |
2018-01-12 14:28 | will | Note Edited: 0006338 | |
2018-01-16 22:03 | Shorty | Note Added: 0009206 | |
2018-10-10 10:54 | jirka | Note Added: 0010092 | |
2018-10-13 13:21 | wyldckat | Note Added: 0010100 | |
2018-10-14 10:34 | will | Note Added: 0010101 | |
2018-10-14 10:35 | will | Note Edited: 0010101 | |
2018-10-19 11:34 | will | File Added: ACMI-exhaust_OF-v1.tar.xz | |
2018-10-19 11:34 | will | Note Added: 0010115 | |
2018-10-19 11:35 | will | Status | feedback => resolved |
2018-10-19 11:35 | will | Note Added: 0010116 | |
2018-10-20 00:16 | wyldckat | Relationship added | has duplicate 0002155 |