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, IOobjectOption::NO_READ),
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  {
73  this->evaluate(Pstream::commsTypes::blocking);
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  << "\n patch type '" << p.type()
94  << "' not constraint type '" << typeName << "'"
95  << "\n for patch " << p.name()
96  << " of field " << this->internalField().name()
97  << " in file " << this->internalField().objectPath()
99  }
100 }
101 
102 
103 template<class Type>
105 (
106  const cyclicFvPatchField<Type>& ptf
107 )
108 :
109  cyclicLduInterfaceField(),
111  cyclicPatch_(ptf.cyclicPatch_)
112 {}
113 
114 
115 template<class Type>
117 (
118  const cyclicFvPatchField<Type>& ptf,
120 )
121 :
122  coupledFvPatchField<Type>(ptf, iF),
123  cyclicPatch_(ptf.cyclicPatch_)
124 {}
125 
126 
127 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
128 
129 template<class Type>
132 {
133  const Field<Type>& iField = this->primitiveField();
134  const labelUList& nbrFaceCells =
135  cyclicPatch().cyclicPatch().neighbPatch().faceCells();
136 
137  tmp<Field<Type>> tpnf(new Field<Type>(this->size()));
138  Field<Type>& pnf = tpnf.ref();
139 
140 
141  if (doTransform())
142  {
143  forAll(pnf, facei)
144  {
145  pnf[facei] = transform
146  (
147  forwardT()[0], iField[nbrFaceCells[facei]]
148  );
149  }
150  }
151  else
152  {
153  forAll(pnf, facei)
154  {
155  pnf[facei] = iField[nbrFaceCells[facei]];
156  }
157  }
159  return tpnf;
160 }
161 
162 
163 template<class Type>
166 {
169  (
170  this->primitiveField()
171  );
172 
173  return refCast<const cyclicFvPatchField<Type>>
174  (
175  fld.boundaryField()[this->cyclicPatch().neighbPatchID()]
176  );
177 }
178 
179 
180 
181 template<class Type>
183 (
184  solveScalarField& result,
185  const bool add,
186  const lduAddressing& lduAddr,
187  const label patchId,
188  const solveScalarField& psiInternal,
189  const scalarField& coeffs,
190  const direction cmpt,
191  const Pstream::commsTypes commsType
192 ) const
193 {
194  const labelUList& nbrFaceCells =
195  lduAddr.patchAddr
196  (
197  this->cyclicPatch().neighbPatchID()
198  );
199 
200  solveScalarField pnf(psiInternal, nbrFaceCells);
201 
202  // Transform according to the transformation tensors
203  transformCoupleField(pnf, cmpt);
204 
205 
206  const labelUList& faceCells = lduAddr.patchAddr(patchId);
207 
208  // Multiply the field by coefficients and add into the result
209  this->addToInternalField(result, !add, faceCells, coeffs, pnf);
210 }
211 
212 
213 template<class Type>
215 (
216  Field<Type>& result,
217  const bool add,
218  const lduAddressing& lduAddr,
219  const label patchId,
220  const Field<Type>& psiInternal,
221  const scalarField& coeffs,
222  const Pstream::commsTypes
223 ) const
224 {
225  const labelList& nbrFaceCells =
226  lduAddr.patchAddr
227  (
228  this->cyclicPatch().neighbPatchID()
229  );
230 
231  Field<Type> pnf(psiInternal, nbrFaceCells);
232 
233  // Transform according to the transformation tensors
234  transformCoupleField(pnf);
235 
236  const labelUList& faceCells = lduAddr.patchAddr(patchId);
238  // Multiply the field by coefficients and add into the result
239  this->addToInternalField(result, !add, faceCells, coeffs, pnf);
240 }
241 
242 
243 template<class Type>
245 {
247 }
248 
249 
250 template<class Type>
252 (
253  fvMatrix<Type>& matrix,
254  const label mat,
255  const direction cmpt
256 )
257 {
258  if (this->cyclicPatch().owner())
259  {
260  label index = this->patch().index();
261 
262  const label globalPatchID =
263  matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index];
264 
265  const Field<scalar> intCoeffsCmpt
266  (
267  matrix.internalCoeffs()[globalPatchID].component(cmpt)
268  );
269 
270  const Field<scalar> boundCoeffsCmpt
271  (
272  matrix.boundaryCoeffs()[globalPatchID].component(cmpt)
273  );
274 
275  const labelUList& u = matrix.lduAddr().upperAddr();
276  const labelUList& l = matrix.lduAddr().lowerAddr();
277 
278  const labelList& faceMap =
279  matrix.lduMeshAssembly().faceBoundMap()[mat][index];
280 
281  forAll (faceMap, faceI)
282  {
283  label globalFaceI = faceMap[faceI];
284 
285  const scalar boundCorr = -boundCoeffsCmpt[faceI];
286  const scalar intCorr = -intCoeffsCmpt[faceI];
287 
288  matrix.upper()[globalFaceI] += boundCorr;
289  matrix.diag()[u[globalFaceI]] -= boundCorr;
290  matrix.diag()[l[globalFaceI]] -= intCorr;
291 
292  if (matrix.asymmetric())
293  {
294  matrix.lower()[globalFaceI] += intCorr;
295  }
296  }
297 
298  if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name()))
299  {
300  matrix.internalCoeffs().set
301  (
302  globalPatchID, intCoeffsCmpt*pTraits<Type>::one
303  );
304  matrix.boundaryCoeffs().set
305  (
306  globalPatchID, boundCoeffsCmpt*pTraits<Type>::one
307  );
308 
309  const label nbrPathID = this->cyclicPatch().neighbPatchID();
310 
311  const label nbrGlobalPatchID =
312  matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][nbrPathID];
313 
314  matrix.internalCoeffs().set
315  (
316  nbrGlobalPatchID, intCoeffsCmpt*pTraits<Type>::one
317 
318  );
319  matrix.boundaryCoeffs().set
320  (
321  nbrGlobalPatchID, boundCoeffsCmpt*pTraits<Type>::one
322  );
323  }
324  }
325 }
326 
327 // ************************************************************************* //
label patchId(-1)
dictionary dict
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
commsTypes
Communications types.
Definition: UPstream.H:72
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:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
Definition: fvMatrix.H:476
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
Definition: typeInfo.H:159
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
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
scalarField & upper()
Definition: lduMatrix.C:208
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:421
Spatial transformation functions for primitive fields.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Definition: fvMatrix.H:485
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
Generic templated field type.
Definition: Field.H:62
string evaluate(label fieldWidth, const std::string &s, size_t pos=0, size_t len=std::string::npos)
String evaluation with specified (positive, non-zero) field width.
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
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:791
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
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)
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:734
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
scalarField & lower()
Definition: lduMatrix.C:179
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
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:547
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:565
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
scalarField & diag()
Definition: lduMatrix.C:197
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:521
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.