cyclicFvPatchField.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) 2011-2017 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 "fvMatrix.H"
30 #include "cyclicFvPatchField.H"
31 #include "transformField.H"
32 #include "volFields.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class Type>
38 (
39  const fvPatch& p,
41 )
42 :
43  coupledFvPatchField<Type>(p, iF),
44  cyclicPatch_(refCast<const cyclicFvPatch>(p))
45 {}
46 
47 
48 template<class Type>
50 (
51  const fvPatch& p,
53  const dictionary& dict,
54  const bool valueRequired
55 )
56 :
57  coupledFvPatchField<Type>(p, iF, dict, false), // Pass no valueRequired
58  cyclicPatch_(refCast<const cyclicFvPatch>(p, dict))
59 {
60  if (!isA<cyclicFvPatch>(p))
61  {
63  << " patch type '" << p.type()
64  << "' not constraint type '" << typeName << "'"
65  << "\n for patch " << p.name()
66  << " of field " << this->internalField().name()
67  << " in file " << this->internalField().objectPath()
68  << exit(FatalIOError);
69  }
70 
71  if (valueRequired)
72  {
74  }
75 }
76 
77 
78 template<class Type>
80 (
81  const cyclicFvPatchField<Type>& ptf,
82  const fvPatch& p,
83  const DimensionedField<Type, volMesh>& iF,
84  const fvPatchFieldMapper& mapper
85 )
86 :
87  coupledFvPatchField<Type>(ptf, p, iF, mapper),
88  cyclicPatch_(refCast<const cyclicFvPatch>(p))
89 {
90  if (!isA<cyclicFvPatch>(this->patch()))
91  {
93  << "' not constraint type '" << typeName << "'"
94  << "\n for patch " << p.name()
95  << " of field " << this->internalField().name()
96  << " in file " << this->internalField().objectPath()
98  }
99 }
100 
101 
102 template<class Type>
104 (
105  const cyclicFvPatchField<Type>& ptf
106 )
107 :
108  cyclicLduInterfaceField(),
110  cyclicPatch_(ptf.cyclicPatch_)
111 {}
112 
113 
114 template<class Type>
116 (
117  const cyclicFvPatchField<Type>& ptf,
119 )
120 :
121  coupledFvPatchField<Type>(ptf, iF),
122  cyclicPatch_(ptf.cyclicPatch_)
123 {}
124 
125 
126 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
127 
128 template<class Type>
131 {
132  const Field<Type>& iField = this->primitiveField();
133  const labelUList& nbrFaceCells =
134  cyclicPatch().cyclicPatch().neighbPatch().faceCells();
135 
136  tmp<Field<Type>> tpnf(new Field<Type>(this->size()));
137  Field<Type>& pnf = tpnf.ref();
138 
139 
140  if (doTransform())
141  {
142  forAll(pnf, facei)
143  {
144  pnf[facei] = transform
145  (
146  forwardT()[0], iField[nbrFaceCells[facei]]
147  );
148  }
149  }
150  else
151  {
152  forAll(pnf, facei)
153  {
154  pnf[facei] = iField[nbrFaceCells[facei]];
155  }
156  }
158  return tpnf;
159 }
160 
161 
162 template<class Type>
165 {
168  (
169  this->primitiveField()
170  );
171 
172  return refCast<const cyclicFvPatchField<Type>>
173  (
174  fld.boundaryField()[this->cyclicPatch().neighbPatchID()]
175  );
176 }
177 
178 
179 
180 template<class Type>
182 (
183  solveScalarField& result,
184  const bool add,
185  const lduAddressing& lduAddr,
186  const label patchId,
187  const solveScalarField& psiInternal,
188  const scalarField& coeffs,
189  const direction cmpt,
190  const Pstream::commsTypes commsType
191 ) const
192 {
193  const labelUList& nbrFaceCells =
194  lduAddr.patchAddr
195  (
196  this->cyclicPatch().neighbPatchID()
197  );
198 
199  solveScalarField pnf(psiInternal, nbrFaceCells);
200 
201  // Transform according to the transformation tensors
202  transformCoupleField(pnf, cmpt);
203 
204 
205  const labelUList& faceCells = lduAddr.patchAddr(patchId);
206 
207  // Multiply the field by coefficients and add into the result
208  this->addToInternalField(result, !add, faceCells, coeffs, pnf);
209 }
210 
211 
212 template<class Type>
214 (
215  Field<Type>& result,
216  const bool add,
217  const lduAddressing& lduAddr,
218  const label patchId,
219  const Field<Type>& psiInternal,
220  const scalarField& coeffs,
221  const Pstream::commsTypes
222 ) const
223 {
224  const labelList& nbrFaceCells =
225  lduAddr.patchAddr
226  (
227  this->cyclicPatch().neighbPatchID()
228  );
229 
230  Field<Type> pnf(psiInternal, nbrFaceCells);
231 
232  // Transform according to the transformation tensors
233  transformCoupleField(pnf);
234 
235  const labelUList& faceCells = lduAddr.patchAddr(patchId);
237  // Multiply the field by coefficients and add into the result
238  this->addToInternalField(result, !add, faceCells, coeffs, pnf);
239 }
240 
241 
242 template<class Type>
244 {
246 }
247 
248 
249 template<class Type>
251 (
252  fvMatrix<Type>& matrix,
253  const label mat,
254  const direction cmpt
255 )
256 {
257  if (this->cyclicPatch().owner())
258  {
259  label index = this->patch().index();
260 
261  const label globalPatchID =
262  matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index];
263 
264  const Field<scalar> intCoeffsCmpt
265  (
266  matrix.internalCoeffs()[globalPatchID].component(cmpt)
267  );
268 
269  const Field<scalar> boundCoeffsCmpt
270  (
271  matrix.boundaryCoeffs()[globalPatchID].component(cmpt)
272  );
273 
274  const labelUList& u = matrix.lduAddr().upperAddr();
275  const labelUList& l = matrix.lduAddr().lowerAddr();
276 
277  const labelList& faceMap =
278  matrix.lduMeshAssembly().faceBoundMap()[mat][index];
279 
280  forAll (faceMap, faceI)
281  {
282  label globalFaceI = faceMap[faceI];
283 
284  const scalar boundCorr = -boundCoeffsCmpt[faceI];
285  const scalar intCorr = -intCoeffsCmpt[faceI];
286 
287  matrix.upper()[globalFaceI] += boundCorr;
288  matrix.diag()[u[globalFaceI]] -= boundCorr;
289  matrix.diag()[l[globalFaceI]] -= intCorr;
290 
291  if (matrix.asymmetric())
292  {
293  matrix.lower()[globalFaceI] += intCorr;
294  }
295  }
296 
297  if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name()))
298  {
299  matrix.internalCoeffs().set
300  (
301  globalPatchID, intCoeffsCmpt*pTraits<Type>::one
302  );
303  matrix.boundaryCoeffs().set
304  (
305  globalPatchID, boundCoeffsCmpt*pTraits<Type>::one
306  );
307 
308  const label nbrPathID = this->cyclicPatch().neighbPatchID();
309 
310  const label nbrGlobalPatchID =
311  matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][nbrPathID];
312 
313  matrix.internalCoeffs().set
314  (
315  nbrGlobalPatchID, intCoeffsCmpt*pTraits<Type>::one
316 
317  );
318  matrix.boundaryCoeffs().set
319  (
320  nbrGlobalPatchID, boundCoeffsCmpt*pTraits<Type>::one
321  );
322  }
323  }
324 }
325 
326 // ************************************************************************* //
label patchId(-1)
dictionary dict
"blocking" : (MPI_Bsend, MPI_Recv)
virtual void updateInterfaceMatrix(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
uint8_t direction
Definition: direction.H:46
const labelListList & patchLocalToGlobalMap() const
Return patchLocalToGlobalMap.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
commsTypes
Types of communications.
Definition: UPstream.H:66
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
const fvPatch & patch() const noexcept
Return the patch.
Definition: fvPatchField.H:199
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
Definition: fvMatrix.H:477
Type & refCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts, uses the virtual type() me...
Definition: typeInfo.H:151
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:68
const cyclicFvPatchField< Type > & neighbourPatchField() const
Return reference to neighbour patchField.
Generic GeometricField class.
Definition: areaFieldsFwd.H:50
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:52
virtual void write(Ostream &) const
Write.
Definition: fvPatchField.C:333
scalarField & upper()
Definition: lduMatrix.C:207
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
static const char *const typeName
Typename for Field.
Definition: Field.H:86
Spatial transformation functions for primitive fields.
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Definition: fvMatrix.H:486
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
Generic templated field type.
Definition: Field.H:61
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
Definition: fvPatchField.H:64
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
Cyclic-plane patch.
Definition: cyclicFvPatch.H:50
Abstract base class for coupled patches.
This boundary condition enforces a cyclic condition between a pair of boundaries. ...
bool asymmetric() const noexcept
Definition: lduMatrix.H:771
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
OBJstream os(runTime.globalPath()/outputName)
const labelListListList & faceBoundMap() const
Return boundary face map.
virtual void manipulateMatrix(fvMatrix< Type > &m, const label iMatrix, const direction cmp)
Manipulate matrix.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:714
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
scalarField & lower()
Definition: lduMatrix.C:178
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
const DimensionedField< Type, volMesh > & internalField() const noexcept
Return dimensioned internal field reference.
Definition: fvPatchField.H:576
const std::string patch
OpenFOAM patch number as a std::string.
virtual void write(Ostream &os) const
Write.
tmp< Field< Type > > patchNeighbourField() const
Return neighbour coupled internal cell data.
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
Definition: fvMatrix.H:548
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
Definition: fvMatrix.H:566
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
scalarField & diag()
Definition: lduMatrix.C:196
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:529
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
cyclicFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.