View Issue Details

IDProjectCategoryView StatusLast Update
0002057OpenFOAMBugpublic2018-12-31 10:51
ReporterLIGA Assigned Tohenry  
PrioritynormalSeverityfeatureReproducibilityalways
Status resolvedResolutionreopened 
PlatformGNU/LinuxOSUbuntuOS Version14.04
Product Versiondev 
Fixed in Versiondev 
Summary0002057: ACMI incompatible with velocityComponentLaplacian
DescriptionA 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 InformationIf needed, it is possible to provide the whole case with the current settings.
TagsACMI

Relationships

has duplicate 0002082 resolvedhenry AMI + dynamic mesh + 6 DoF 
has duplicate 0002109 resolvedwill Surface mesh changes at the interface, the ACMI doesn't work as expected. 
has duplicate 0002155 resolvedwill Deactivating ACMI interpolation for special fields 

Activities

LIGA

2016-04-20 16:14

reporter  

ACMI.mp4 (649,477 bytes)   

henry

2016-05-03 17:40

manager   ~0006224

Last edited: 2016-05-04 09:52

It would indeed be useful if you could provide a test-case which demonstrates the issue.

LIGA

2016-05-04 09:35

reporter  

ACMI-exhaust_OF.tar.gz (1,425,309 bytes)

LIGA

2016-05-04 09:35

reporter  

points (1,237,360 bytes)

LIGA

2016-05-04 09:37

reporter   ~0006227

Sample case is uploaded. Simply move points file to polyMesh. Thanks

MattijsJ

2016-05-19 17:39

reporter  

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;
-    }
-}
-
-
-// ************************************************************************* //
ACMI_conservative.patch (37,275 bytes)   

MattijsJ

2016-05-19 17:44

reporter   ~0006294

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

MattijsJ

2016-05-19 18:02

reporter   ~0006295

Ran #2057 with this and I get uniform temperature in whole domain (not sure if this was the purpose of that case)

LIGA

2016-05-24 16:24

reporter   ~0006312

@MattijsJ: thank you for your effort. In my case I am struggling at combining ACMI with mesh deformation.

MattijsJ

2016-05-24 16:45

reporter   ~0006313

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.

LIGA

2016-05-24 16:49

reporter   ~0006314

I am using velocityComponentLaplacian for the motion. Are you able to downlaod any of my attached files?

MattijsJ

2016-05-24 18:36

reporter   ~0006315

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.

henry

2016-05-30 08:31

manager   ~0006332

Resolved by commit 691e7186b4287cc38b259cae6edcdc53f63807be

LIGA

2016-05-30 17:19

reporter   ~0006338

Last edited: 2018-01-12 14:28

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.

MattijsJ

2016-05-31 11:13

reporter   ~0006340

Does the oscillatingInletACMI2D work for you now?

LIGA

2016-05-31 12:39

reporter   ~0006341

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+.

MattijsJ

2016-05-31 16:27

reporter   ~0006347

- 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.

LIGA

2016-06-01 08:51

reporter   ~0006351

Last edited: 2016-06-01 09:11

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.

MattijsJ

2016-06-03 10:19

reporter   ~0006362

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)

rcl

2016-06-04 19:14

reporter   ~0006371

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.

rcl

2016-06-04 19:15

reporter  

rcl

2016-06-09 08:41

reporter   ~0006417

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.

MattijsJ

2016-06-10 09:20

reporter   ~0006419

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.

rcl

2016-06-10 10:08

reporter   ~0006420

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.

jskortel

2016-08-17 19:00

reporter   ~0006698

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.

MattijsJ

2016-09-16 14:20

reporter   ~0006871

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)()
//             );
//         }
//     }
}


// ************************************************************************* //
cyclicACMIPointPatchField.C (7,659 bytes)   

jskortel

2016-09-25 19:24

reporter   ~0006923

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?
example_videos.tar.gz (4,233,985 bytes)

Shorty

2018-01-16 22:03

reporter   ~0009206

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

jirka

2018-10-10 10:54

reporter   ~0010092

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

wyldckat

2018-10-13 13:21

updater   ~0010100

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...

will

2018-10-14 10:34

manager   ~0010101

Last edited: 2018-10-14 10:35

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.

will

2018-10-19 11:34

manager   ~0010115

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".
ACMI-exhaust_OF-v1.tar.xz (1,342,508 bytes)

will

2018-10-19 11:35

manager   ~0010116

Resolved in dev by commit a0a88d66

Issue History

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