cyclicACMIFvPatch.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2013-2016 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "cyclicACMIFvPatch.H"
30 #include "fvMesh.H"
31 #include "transform.H"
32 #include "surfaceFields.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(cyclicACMIFvPatch, 0);
40  addToRunTimeSelectionTable(fvPatch, cyclicACMIFvPatch, polyPatch);
41 }
42 
43 
44 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
45 
47 {
48  // Give AMI chance to update itself
49  bool updated = cyclicACMIPolyPatch_.updateAreas();
50 
51  if (!cyclicACMIPolyPatch_.owner())
52  {
53  return updated;
54  }
55 
56  if (updated || !cyclicACMIPolyPatch_.upToDate(areaTime_))
57  {
58  if (debug)
59  {
60  Pout<< "cyclicACMIFvPatch::updateAreas() : updating fv areas for "
61  << name() << " and " << this->nonOverlapPatch().name()
62  << endl;
63  }
64 
65  const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
66  const cyclicACMIFvPatch& nbrACMI = neighbPatch();
67  const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
68 
69  resetPatchAreas(*this);
71  resetPatchAreas(nbrACMI);
72  resetPatchAreas(nbrNonOverlapPatch);
73 
74  updated = true;
75 
76  // Mark my data to be up to date with ACMI polyPatch level
77  cyclicACMIPolyPatch_.setUpToDate(areaTime_);
78  }
79  return updated;
80 }
81 
82 
84 {
85  const_cast<vectorField&>(fvp.Sf()) = fvp.patch().faceAreas();
86  const_cast<vectorField&>(fvp.Cf()) = fvp.patch().faceCentres();
87  const_cast<scalarField&>(fvp.magSf()) = mag(fvp.patch().faceAreas());
88 
89  DebugPout
90  << fvp.patch().name() << " area:" << sum(fvp.magSf()) << endl;
91 }
92 
93 
95 {
96  if (coupled())
97  {
98  const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
99  const scalarField deltas(nf() & coupledFvPatch::delta());
100 
101  // These deltas are of the cyclic part alone - they are
102  // not affected by the amount of overlap with the nonOverlapPatch
103  scalarField nbrDeltas
104  (
106  (
107  nbrPatch.nf() & nbrPatch.coupledFvPatch::delta()
108  )
109  );
110 
111  const scalar tol = cyclicACMIPolyPatch::tolerance();
112 
113 
114  forAll(deltas, facei)
115  {
116  scalar di = mag(deltas[facei]);
117  scalar dni = mag(nbrDeltas[facei]);
118 
119  if (dni < tol)
120  {
121  // Avoid zero weights on disconnected faces. This value
122  // will be weighted with the (zero) face area so will not
123  // influence calculations.
124  w[facei] = 1.0;
125  }
126  else
127  {
128  w[facei] = dni/(di + dni);
129  }
130  }
131  }
132  else
133  {
134  // Behave as uncoupled patch
136  }
137 }
138 
139 
140 // * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
141 
143 (
144  const polyPatch& patch,
145  const fvBoundaryMesh& bm
146 )
147 :
148  coupledFvPatch(patch, bm),
150  cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch)),
151  areaTime_
152  (
153  IOobject
154  (
155  "areaTime",
156  boundaryMesh().mesh().pointsInstance(),
157  boundaryMesh().mesh(),
160  false
161  ),
162  dimensionedScalar("time", dimTime, -GREAT)
163  )
164 {
165  areaTime_.eventNo() = -1;
166 }
167 
168 
169 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
170 
172 {
173  return Pstream::parRun() || (this->size() && neighbFvPatch().size());
174 }
175 
176 
178 {
179  if (coupled())
180  {
181  const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
182 
183  const vectorField patchD(coupledFvPatch::delta());
184 
185  vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta()));
186 
187  auto tpdv = tmp<vectorField>::New(patchD.size());
188  vectorField& pdv = tpdv.ref();
189 
190  // do the transformation if necessary
191  if (parallel())
192  {
193  forAll(patchD, facei)
194  {
195  const vector& ddi = patchD[facei];
196  const vector& dni = nbrPatchD[facei];
197 
198  pdv[facei] = ddi - dni;
199  }
200  }
201  else
202  {
203  forAll(patchD, facei)
204  {
205  const vector& ddi = patchD[facei];
206  const vector& dni = nbrPatchD[facei];
207 
208  pdv[facei] = ddi - transform(forwardT()[0], dni);
209  }
210  }
211 
212  return tpdv;
213  }
214  else
215  {
216  return coupledFvPatch::delta();
217  }
218 }
219 
220 
222 (
223  const labelUList& internalData
224 ) const
225 {
226  return patchInternalField(internalData);
227 }
228 
229 
231 (
232  const Pstream::commsTypes commsType,
233  const labelUList& iF
234 ) const
235 {
236  return neighbFvPatch().patchInternalField(iF);
237 }
238 
239 
241 {
242  if (!cyclicACMIPolyPatch_.owner())
243  {
244  return;
245  }
246 
247 
248  if (!cyclicACMIPolyPatch_.upToDate(areaTime_))
249  {
250  if (debug)
251  {
252  Pout<< "cyclicACMIFvPatch::movePoints() : updating fv areas for "
253  << name() << " and " << this->nonOverlapPatch().name()
254  << endl;
255  }
256 
257 
258  // Set the patch face areas to be consistent with the changes made
259  // at the polyPatch level
260 
261  const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
262  const cyclicACMIFvPatch& nbrACMI = neighbPatch();
263  const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
264 
265  resetPatchAreas(*this);
266  resetPatchAreas(nonOverlapPatch);
267  resetPatchAreas(nbrACMI);
268  resetPatchAreas(nbrNonOverlapPatch);
269 
270  // Scale the mesh flux
271 
272  const labelListList& newSrcAddr = AMI().srcAddress();
273  const labelListList& newTgtAddr = AMI().tgtAddress();
274 
275  const fvMesh& mesh = boundaryMesh().mesh();
276  surfaceScalarField& meshPhi = const_cast<fvMesh&>(mesh).setPhi();
277  surfaceScalarField::Boundary& meshPhiBf = meshPhi.boundaryFieldRef();
278 
279  // Note: phip and phiNonOverlap will be different sizes if new faces
280  // have been added
281  scalarField& phip = meshPhiBf[cyclicACMIPolyPatch_.index()];
282  scalarField& phiNonOverlapp =
283  meshPhiBf[nonOverlapPatch.patch().index()];
284 
285  const auto& points = mesh.points();
286 
287  forAll(phip, facei)
288  {
289  if (newSrcAddr[facei].empty())
290  {
291  // AMI patch with no connection to other coupled faces
292  phip[facei] = 0.0;
293  }
294  else
295  {
296  // Scale the mesh flux according to the area fraction
297  const face& fAMI = cyclicACMIPolyPatch_[facei];
298 
299  // Note: using raw point locations to calculate the geometric
300  // area - faces areas are currently scaled (decoupled from
301  // mesh points)
302  const scalar geomArea = fAMI.mag(points);
303  phip[facei] *= magSf()[facei]/geomArea;
304  }
305  }
306 
307  forAll(phiNonOverlapp, facei)
308  {
309  const scalar w = 1.0 - cyclicACMIPolyPatch_.srcMask()[facei];
310  phiNonOverlapp[facei] *= w;
311  }
312 
313  const cyclicACMIPolyPatch& nbrPatch = nbrACMI.cyclicACMIPatch();
314  scalarField& nbrPhip = meshPhiBf[nbrPatch.index()];
315  scalarField& nbrPhiNonOverlapp =
316  meshPhiBf[nbrNonOverlapPatch.patch().index()];
317 
318  forAll(nbrPhip, facei)
319  {
320  if (newTgtAddr[facei].empty())
321  {
322  nbrPhip[facei] = 0.0;
323  }
324  else
325  {
326  const face& fAMI = nbrPatch[facei];
327 
328  // Note: using raw point locations to calculate the geometric
329  // area - faces areas are currently scaled (decoupled from
330  // mesh points)
331  const scalar geomArea = fAMI.mag(points);
332  nbrPhip[facei] *= nbrACMI.magSf()[facei]/geomArea;
333  }
334  }
335 
336  forAll(nbrPhiNonOverlapp, facei)
337  {
338  const scalar w = 1.0 - cyclicACMIPolyPatch_.tgtMask()[facei];
339  nbrPhiNonOverlapp[facei] *= w;
340  }
341 
342  // Mark my data to be up to date with ACMI polyPatch level
343  cyclicACMIPolyPatch_.setUpToDate(areaTime_);
344  }
345 }
346 
347 
348 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::boundaryMesh::mesh
const bMesh & mesh() const
Definition: boundaryMesh.H:206
Foam::fvPatch::Sf
const vectorField & Sf() const
Return face area vectors.
Definition: fvPatch.C:144
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::cyclicAMIPolyPatch::owner
virtual bool owner() const
Does this side own the patch?
Definition: cyclicAMIPolyPatch.C:848
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::face::mag
scalar mag(const UList< point > &p) const
Magnitude of face area.
Definition: faceI.H:130
Foam::cyclicACMIPolyPatch::upToDate
bool upToDate(const regIOobject &) const
Return true if given object is up to date with *this.
Definition: cyclicACMIPolyPatch.C:142
Foam::coupledFvPatch::delta
virtual tmp< vectorField > delta() const =0
Return delta (P to N) vectors across coupled patch.
Definition: coupledFvPatch.C:46
Foam::cyclicACMILduInterface
An abstract base class for cyclic ACMI coupled interfaces.
Definition: cyclicACMILduInterface.H:51
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
Foam::cyclicACMIPolyPatch::tolerance
static scalar tolerance()
Overlap tolerance.
Definition: cyclicACMIPolyPatchI.H:65
Foam::cyclicACMIPolyPatch::setUpToDate
void setUpToDate(regIOobject &) const
Set object up to date with *this.
Definition: cyclicACMIPolyPatch.C:151
Foam::fvc::meshPhi
tmp< surfaceScalarField > meshPhi(const volVectorField &U)
Definition: fvcMeshPhi.C:36
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
surfaceFields.H
Foam::surfaceFields.
Foam::fvPatch::name
virtual const word & name() const
Return name.
Definition: fvPatch.H:167
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
Foam::cyclicACMIFvPatch::delta
virtual tmp< vectorField > delta() const
Return delta (P to N) vectors across coupled patch.
Definition: cyclicACMIFvPatch.C:177
Foam::cyclicACMIFvPatch::coupled
virtual bool coupled() const
Definition: cyclicACMIFvPatch.C:171
Foam::cyclicACMIFvPatch::internalFieldTransfer
virtual tmp< labelField > internalFieldTransfer(const Pstream::commsTypes commsType, const labelUList &internalData) const
Return neighbour field.
Definition: cyclicACMIFvPatch.C:231
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:56
Foam::fvPatch::nf
tmp< vectorField > nf() const
Return face normals.
Definition: fvPatch.C:138
Foam::dimTime
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:54
Foam::interpolate
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
Definition: curveTools.C:75
Foam::Field< vector >
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
Foam::cyclicACMIFvPatch::neighbPatch
virtual const cyclicACMIFvPatch & neighbPatch() const
Return neighbour fvPatch.
Definition: cyclicACMIFvPatch.H:119
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::fvPatch::Cf
const vectorField & Cf() const
Return face centres.
Definition: fvPatch.C:113
Foam::cyclicACMIFvPatch::movePoints
virtual void movePoints()
Correct patches after moving points.
Definition: cyclicACMIFvPatch.C:240
Foam::cyclicACMIFvPatch::nonOverlapPatch
virtual const fvPatch & nonOverlapPatch() const
Return non-overlapping fvPatch.
Definition: cyclicACMIFvPatch.H:134
Foam::cyclicACMIFvPatch::updateAreas
virtual bool updateAreas() const
Update the AMI and patch areas. Return true if anything updated.
Definition: cyclicACMIFvPatch.C:46
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
DebugPout
#define DebugPout
Report an information message using Foam::Pout.
Definition: messageStream.H:370
Foam::cyclicACMIFvPatch::cyclicACMIFvPatch
cyclicACMIFvPatch(const polyPatch &patch, const fvBoundaryMesh &bm)
Construct from polyPatch.
Definition: cyclicACMIFvPatch.C:143
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:69
Foam::polyPatch::faceCentres
const vectorField::subField faceCentres() const
Return face centres.
Definition: polyPatch.C:313
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::Vector< scalar >
Foam::cyclicACMIFvPatch::resetPatchAreas
void resetPatchAreas(const fvPatch &fvp) const
Helper function to reset the FV patch areas from the primitive patch.
Definition: cyclicACMIFvPatch.C:83
Foam::List< labelList >
Foam::polyPatch::faceAreas
const vectorField::subField faceAreas() const
Return face normals.
Definition: polyPatch.C:319
Foam::cyclicACMIPolyPatch::updateAreas
virtual bool updateAreas() const
Update the AMI and patch areas. Return true if anything.
Definition: cyclicACMIPolyPatch.C:46
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::cyclicACMIFvPatch::cyclicACMIPatch
const cyclicACMIPolyPatch & cyclicACMIPatch() const
Return local reference cast into the cyclic patch.
Definition: cyclicACMIFvPatch.H:102
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::cyclicACMIFvPatch::interfaceInternalField
virtual tmp< labelField > interfaceInternalField(const labelUList &internalData) const
Definition: cyclicACMIFvPatch.C:222
Foam::fvPatch::patch
const polyPatch & patch() const
Return the polyPatch.
Definition: fvPatch.H:161
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
cyclicACMIFvPatch.H
Foam::coupledFvPatch
An abstract base class for patches that couple regions of the computational domain e....
Definition: coupledFvPatch.H:53
Foam::cyclicACMIPolyPatch
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
Definition: cyclicACMIPolyPatch.H:79
transform.H
3D tensor transformation operations.
Foam::fvPatch::magSf
const scalarField & magSf() const
Return face area magnitudes.
Definition: fvPatch.C:150
Foam::cyclicACMIFvPatch::makeWeights
void makeWeights(scalarField &) const
Make patch weighting factors.
Definition: cyclicACMIFvPatch.C:94
Foam::GeometricField< scalar, fvsPatchField, surfaceMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:123
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
Foam::patchIdentifier::index
label index() const
The index of this patch in the boundaryMesh.
Definition: patchIdentifier.H:158
Foam::fvPatch::makeWeights
virtual void makeWeights(scalarField &) const
Make patch weighting factors.
Definition: fvPatch.C:164
Foam::cyclicACMIFvPatch
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
Definition: cyclicACMIFvPatch.H:54