cyclicFaPatch.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2019-2021 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 "cyclicFaPatch.H"
30 #include "coupledPolyPatch.H"
32 #include "transform.H"
33 #include "faMesh.H"
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(cyclicFaPatch, 0);
40  addToRunTimeSelectionTable(faPatch, cyclicFaPatch, dictionary);
41 }
42 
43 const Foam::scalar Foam::cyclicFaPatch::matchTol_ = 1e-3;
44 
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 void Foam::cyclicFaPatch::calcTransforms()
49 {
50  const label sizeby2 = this->size()/2;
51  if (size() > 0)
52  {
53  pointField half0Ctrs(sizeby2);
54  pointField half1Ctrs(sizeby2);
55  for (label edgei=0; edgei < sizeby2; ++edgei)
56  {
57  half0Ctrs[edgei] = this->edgeCentres()[edgei];
58  half1Ctrs[edgei] = this->edgeCentres()[edgei + sizeby2];
59  }
60 
61  vectorField half0Normals(sizeby2);
62  vectorField half1Normals(sizeby2);
63 
65 
66  scalar maxMatchError = 0;
67  label errorEdge = -1;
68 
69  for (label edgei = 0; edgei < sizeby2; ++edgei)
70  {
71  half0Normals[edgei] = eN[edgei];
72  half1Normals[edgei] = eN[edgei + sizeby2];
73 
74  scalar magLe = mag(half0Normals[edgei]);
75  scalar nbrMagLe = mag(half1Normals[edgei]);
76  scalar avLe = 0.5*(magLe + nbrMagLe);
77 
78  if (magLe < ROOTVSMALL && nbrMagLe < ROOTVSMALL)
79  {
80  // Undetermined normal. Use dummy normal to force separation
81  // check. (note use of sqrt(VSMALL) since that is how mag
82  // scales)
83  half0Normals[edgei] = point(1, 0, 0);
84  half1Normals[edgei] = half0Normals[edgei];
85  }
86  else if (mag(magLe - nbrMagLe)/avLe > matchTol_)
87  {
88  // Error in area matching. Find largest error
89  maxMatchError =
90  Foam::max(maxMatchError, mag(magLe - nbrMagLe)/avLe);
91  errorEdge = edgei;
92  }
93  else
94  {
95  half0Normals[edgei] /= magLe;
96  half1Normals[edgei] /= nbrMagLe;
97  }
98  }
99 
100  // Check for error in edge matching
101  if (maxMatchError > matchTol_)
102  {
103  label nbrEdgei = errorEdge + sizeby2;
104  scalar magLe = mag(half0Normals[errorEdge]);
105  scalar nbrMagLe = mag(half1Normals[errorEdge]);
106  scalar avLe = 0.5*(magLe + nbrMagLe);
107 
109  << "edge " << errorEdge
110  << " area does not match neighbour "
111  << nbrEdgei << " by "
112  << 100*mag(magLe - nbrMagLe)/avLe
113  << "% -- possible edge ordering problem." << endl
114  << "patch:" << name()
115  << " my area:" << magLe
116  << " neighbour area:" << nbrMagLe
117  << " matching tolerance:" << matchTol_
118  << endl
119  << "Mesh edge:" << start() + errorEdge
120  << endl
121  << "Neighbour edge:" << start() + nbrEdgei
122  << endl
123  << "Other errors also exist, only the largest is reported. "
124  << "Please rerun with cyclic debug flag set"
125  << " for more information." << exit(FatalError);
126  }
127 
128  // Calculate transformation tensors
130  (
131  half0Ctrs,
132  half1Ctrs,
133  half0Normals,
134  half1Normals
135  );
136 
137  // Check transformation tensors
138  if (!parallel())
139  {
140  if (forwardT().size() > 1 || reverseT().size() > 1)
141  {
143  << "Transformation tensor is not constant for the cyclic "
144  << "patch. Please reconsider your setup and definition of "
145  << "cyclic boundaries." << endl;
146  }
147  }
148  }
149 }
150 
151 
153 {
154  const scalarField& magL = magEdgeLengths();
155 
156  const scalarField deltas(edgeNormals() & faPatch::delta());
157  const label sizeby2 = deltas.size()/2;
158 
159  scalar maxMatchError = 0;
160  label errorEdge = -1;
161 
162  for (label edgei = 0; edgei < sizeby2; ++edgei)
163  {
164  scalar avL = 0.5*(magL[edgei] + magL[edgei + sizeby2]);
165 
166  if
167  (
168  mag(magL[edgei] - magL[edgei + sizeby2])/avL
169  > matchTol_
170  )
171  {
172  // Found error. Look for largest matching error
173  maxMatchError =
174  Foam::max
175  (
176  maxMatchError,
177  mag(magL[edgei] - magL[edgei + sizeby2])/avL
178  );
179 
180  errorEdge = edgei;
181  }
182 
183  scalar di = deltas[edgei];
184  scalar dni = deltas[edgei + sizeby2];
185 
186  w[edgei] = dni/(di + dni);
187  w[edgei + sizeby2] = 1 - w[edgei];
188  }
189 
190  // Check for error in matching
191  if (maxMatchError > matchTol_)
192  {
193  scalar avL = 0.5*(magL[errorEdge] + magL[errorEdge + sizeby2]);
194 
196  << "edge " << errorEdge << " and " << errorEdge + sizeby2
197  << " areas do not match by "
198  << 100*mag(magL[errorEdge] - magL[errorEdge + sizeby2])/avL
199  << "% -- possible edge ordering problem." << nl
200  << "Cyclic area match tolerance = "
201  << matchTol_ << " patch: " << name()
202  << abort(FatalError);
203  }
204 }
205 
206 
208 {
209  const scalarField deltas(edgeNormals() & faPatch::delta());
210  const label sizeby2 = deltas.size()/2;
211 
212  for (label edgei = 0; edgei < sizeby2; ++edgei)
213  {
214  scalar di = deltas[edgei];
215  scalar dni = deltas[edgei + sizeby2];
216 
217  dc[edgei] = 1.0/(di + dni);
218  dc[edgei + sizeby2] = dc[edgei];
219  }
220 }
221 
222 
224 {
226 }
227 
228 
230 {
232  calcTransforms();
233 }
234 
235 
237 {
239 }
240 
241 
243 {
245  calcTransforms();
246 }
247 
248 
250 {
251  const vectorField patchD(faPatch::delta());
252  const label sizeby2 = patchD.size()/2;
253 
254  auto tpdv = tmp<vectorField>::New(patchD.size());
255  auto& pdv = tpdv.ref();
256 
257  // Do the transformation if necessary
258  if (parallel())
259  {
260  for (label edgei = 0; edgei < sizeby2; ++edgei)
261  {
262  const vector& ddi = patchD[edgei];
263  vector dni = patchD[edgei + sizeby2];
264 
265  pdv[edgei] = ddi - dni;
266  pdv[edgei + sizeby2] = -pdv[edgei];
267  }
268  }
269  else
270  {
271  for (label edgei = 0; edgei < sizeby2; ++edgei)
272  {
273  const vector& ddi = patchD[edgei];
274  vector dni = patchD[edgei + sizeby2];
275 
276  pdv[edgei] = ddi - transform(forwardT()[0], dni);
277  pdv[edgei + sizeby2] = -transform(reverseT()[0], pdv[edgei]);
278  }
279  }
280 
281  return tpdv;
282 }
283 
284 
286 (
287  const labelUList& internalData
288 ) const
289 {
290  return patchInternalField(internalData);
291 }
292 
293 
295 (
296  const labelUList& internalData,
297  const labelUList& edgeFaces
298 ) const
299 {
300  return patchInternalField(internalData, edgeFaces);
301 }
302 
303 
305 (
306  const Pstream::commsTypes commsType,
307  const labelUList& interfaceData
308 ) const
309 {
310  auto tpnf = tmp<labelField>::New(this->size());
311  auto& pnf = tpnf.ref();
312 
313  const label sizeby2 = this->size()/2;
314 
315  for (label edgei=0; edgei < sizeby2; ++edgei)
316  {
317  pnf[edgei] = interfaceData[edgei + sizeby2];
318  pnf[edgei + sizeby2] = interfaceData[edgei];
319  }
320 
321  return tpnf;
322 }
323 
324 
326 (
327  const Pstream::commsTypes commsType,
328  const labelUList& iF
329 ) const
330 {
331  return internalFieldTransfer(commsType, iF, this->faceCells());
332 }
333 
334 
336 (
337  const Pstream::commsTypes commsType,
338  const labelUList& iF,
339  const labelUList& edgeCells
340 ) const
341 {
342  auto tpnf = tmp<labelField>::New(this->size());
343  auto& pnf = tpnf.ref();
344 
345  const label sizeby2 = this->size()/2;
346 
347  for (label edgei=0; edgei < sizeby2; ++edgei)
348  {
349  pnf[edgei] = iF[edgeCells[edgei + sizeby2]];
350  pnf[edgei + sizeby2] = iF[edgeCells[edgei]];
351  }
352 
353  return tpnf;
354 }
355 
356 
357 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::cyclicFaPatch::initMovePoints
virtual void initMovePoints(const pointField &)
Initialise the patches for moving points.
Definition: cyclicFaPatch.C:236
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::cyclicFaPatch::calcGeometry
virtual void calcGeometry()
Calculate the patch geometry.
Definition: cyclicFaPatch.C:229
Foam::cyclicFaPatch::makeWeights
void makeWeights(scalarField &) const
Make patch weighting factors.
Definition: cyclicFaPatch.C:152
Foam::coupledFaPatch::parallel
bool parallel() const
Are the cyclic planes parallel.
Definition: coupledFaPatch.H:198
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::faPatch::movePoints
virtual void movePoints(const pointField &)
Correct patch after moving points.
Definition: faPatch.C:463
Foam::cyclicFaPatch::makeDeltaCoeffs
void makeDeltaCoeffs(scalarField &) const
Make patch face - neighbour cell distances.
Definition: cyclicFaPatch.C:207
cyclicFaPatch.H
Foam::faPatch::calcGeometry
virtual void calcGeometry()
Calculate the patch geometry.
Definition: faPatch.H:122
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
faMesh.H
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:521
Foam::faPatch::delta
virtual tmp< vectorField > delta() const
Return cell-centre to face-centre vector.
Definition: faPatch.C:423
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::faPatch::initMovePoints
virtual void initMovePoints(const pointField &)
Initialise the patches for moving points.
Definition: faPatch.H:126
coupledPolyPatch.H
Foam::Field< scalar >
Foam::faPatch::edgeCentres
const vectorField & edgeCentres() const
Return edge centres.
Definition: faPatch.C:372
SeriousErrorInFunction
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Definition: messageStream.H:306
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::cyclicFaPatch::interfaceInternalField
virtual tmp< labelField > interfaceInternalField(const labelUList &internalData) const
Definition: cyclicFaPatch.C:286
Foam::cyclicFaPatch::matchTol_
static const scalar matchTol_
Relative tolerance (for geometric matching). Is factor of.
Definition: cyclicFaPatch.H:72
Foam::cyclicFaPatch::initGeometry
virtual void initGeometry()
Initialise the calculation of the patch geometry.
Definition: cyclicFaPatch.C:223
Foam::FatalError
error FatalError
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::cyclicFaPatch::forwardT
virtual const tensorField & forwardT() const
Return face transformation tensor.
Definition: cyclicFaPatch.H:139
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::cyclicFaPatch::reverseT
virtual const tensorField & reverseT() const
Return neighbour-cell transformation tensor.
Definition: cyclicFaPatch.H:145
Foam::faPatch::start
label start() const
Patch start in edge list.
Definition: faPatch.C:126
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:69
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::coupledFaPatch::calcTransformTensors
void calcTransformTensors(const vector &Cf, const vector &Cr, const vector &nf, const vector &nr) const
Calculate the uniform transformation tensors.
Definition: coupledFaPatch.C:41
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::faPatch::magEdgeLengths
const scalarField & magEdgeLengths() const
Return edge length magnitudes.
Definition: faPatch.C:384
Foam::Vector< scalar >
Foam::cyclicFaPatch::transfer
virtual tmp< labelField > transfer(const Pstream::commsTypes commsType, const labelUList &interfaceData) const
Transfer and return neighbour field.
Definition: cyclicFaPatch.C:305
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::cyclicFaPatch::movePoints
virtual void movePoints(const pointField &)
Correct patches after moving points.
Definition: cyclicFaPatch.C:242
Foam::UList< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
Foam::faPatch::edgeNormals
tmp< vectorField > edgeNormals() const
Return edge normals.
Definition: faPatch.C:390
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::cyclicFaPatch::delta
virtual tmp< vectorField > delta() const
Return delta (P to N) vectors across coupled patch.
Definition: cyclicFaPatch.C:249
Foam::patchIdentifier::name
const word & name() const noexcept
The patch name.
Definition: patchIdentifier.H:135
Foam::faPatch::initGeometry
virtual void initGeometry()
Initialise the calculation of the patch geometry.
Definition: faPatch.H:118
transform.H
3D tensor transformation operations.
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::cyclicFaPatch::internalFieldTransfer
virtual tmp< labelField > internalFieldTransfer(const Pstream::commsTypes commsType, const labelUList &internalData) const
Return neighbour field.
Definition: cyclicFaPatch.C:326
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::faceCells
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:56
Foam::faPatch::size
virtual label size() const
Patch size is the number of edge labels.
Definition: faPatch.H:264