Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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"
31#include "transformField.H"
32#include "volFields.H"
33
34// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35
36template<class Type>
38(
39 const fvPatch& p,
41)
43 coupledFvPatchField<Type>(p, iF),
44 cyclicPatch_(refCast<const cyclicFvPatch>(p))
45{}
46
47
48template<class Type>
50(
51 const fvPatch& p,
53 const dictionary& dict,
54 const bool needValue
55)
56:
57 coupledFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
58 cyclicPatch_(refCast<const cyclicFvPatch>(p, dict))
59{
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()
69 }
70
71 if (needValue)
72 {
74 }
75}
76
77
78template<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()
98 << exit(FatalError);
99 }
100}
101
102
103template<class Type>
105(
106 const cyclicFvPatchField<Type>& ptf
107)
108:
110 coupledFvPatchField<Type>(ptf),
111 cyclicPatch_(ptf.cyclicPatch_)
112{}
113
114
115template<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
129template<class Type>
131{
132 const Field<Type>& iField = this->primitiveField();
133 const labelUList& nbrFaceCells =
134 cyclicPatch().cyclicPatch().neighbPatch().faceCells();
135
136 if (doTransform())
137 {
138 forAll(pnf, facei)
139 {
140 pnf[facei] = transform
141 (
142 forwardT()[0], iField[nbrFaceCells[facei]]
143 );
144 }
145 }
146 else
147 {
148 forAll(pnf, facei)
149 {
150 pnf[facei] = iField[nbrFaceCells[facei]];
152 }
153}
154
155
156template<class Type>
157Foam::tmp<Foam::Field<Type>>
159{
160 auto tpnf = tmp<Field<Type>>::New(this->size());
161 this->patchNeighbourField(tpnf.ref());
162 return tpnf;
163}
164
165
166template<class Type>
169{
170 const auto& fld =
172 (
173 this->primitiveField()
174 );
175
177 (
178 fld.boundaryField()[this->cyclicPatch().neighbPatchID()]
179 );
181
182
183
184template<class Type>
186(
187 solveScalarField& result,
188 const bool add,
189 const lduAddressing& lduAddr,
190 const label patchId,
191 const solveScalarField& psiInternal,
192 const scalarField& coeffs,
193 const direction cmpt,
194 const Pstream::commsTypes commsType
195) const
196{
197 const labelUList& nbrFaceCells =
198 lduAddr.patchAddr
199 (
200 this->cyclicPatch().neighbPatchID()
201 );
202
203 solveScalarField pnf(psiInternal, nbrFaceCells);
204
205 // Transform according to the transformation tensors
206 transformCoupleField(pnf, cmpt);
207
208
209 const labelUList& faceCells = lduAddr.patchAddr(patchId);
211 // Multiply the field by coefficients and add into the result
212 this->addToInternalField(result, !add, faceCells, coeffs, pnf);
213}
214
215
216template<class Type>
218(
219 Field<Type>& result,
220 const bool add,
221 const lduAddressing& lduAddr,
222 const label patchId,
223 const Field<Type>& psiInternal,
224 const scalarField& coeffs,
226) const
227{
228 const labelUList& nbrFaceCells =
229 lduAddr.patchAddr
230 (
231 this->cyclicPatch().neighbPatchID()
232 );
233
234 Field<Type> pnf(psiInternal, nbrFaceCells);
235
236 // Transform according to the transformation tensors
238
239 const labelUList& faceCells = lduAddr.patchAddr(patchId);
241 // Multiply the field by coefficients and add into the result
242 this->addToInternalField(result, !add, faceCells, coeffs, pnf);
243}
244
245
246template<class Type>
248{
250}
251
252
253template<class Type>
255(
256 fvMatrix<Type>& matrix,
257 const label mat,
258 const direction cmpt
259)
260{
261 if (this->cyclicPatch().owner())
262 {
263 label index = this->patch().index();
264
265 const label globalPatchID =
266 matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index];
267
268 const Field<scalar> intCoeffsCmpt
269 (
270 matrix.internalCoeffs()[globalPatchID].component(cmpt)
271 );
272
273 const Field<scalar> boundCoeffsCmpt
274 (
275 matrix.boundaryCoeffs()[globalPatchID].component(cmpt)
276 );
277
278 const labelUList& u = matrix.lduAddr().upperAddr();
279 const labelUList& l = matrix.lduAddr().lowerAddr();
280
281 const labelList& faceMap =
282 matrix.lduMeshAssembly().faceBoundMap()[mat][index];
283
284 forAll (faceMap, faceI)
285 {
286 label globalFaceI = faceMap[faceI];
287
288 const scalar boundCorr = -boundCoeffsCmpt[faceI];
289 const scalar intCorr = -intCoeffsCmpt[faceI];
290
291 matrix.upper()[globalFaceI] += boundCorr;
292 matrix.diag()[u[globalFaceI]] -= boundCorr;
293 matrix.diag()[l[globalFaceI]] -= intCorr;
294
295 if (matrix.asymmetric())
296 {
297 matrix.lower()[globalFaceI] += intCorr;
298 }
299 }
300
301 if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name()))
302 {
303 matrix.internalCoeffs().set
304 (
305 globalPatchID, intCoeffsCmpt*pTraits<Type>::one
306 );
307 matrix.boundaryCoeffs().set
308 (
309 globalPatchID, boundCoeffsCmpt*pTraits<Type>::one
310 );
311
312 const label nbrPathID = this->cyclicPatch().neighbPatchID();
313
314 const label nbrGlobalPatchID =
315 matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][nbrPathID];
316
317 matrix.internalCoeffs().set
318 (
319 nbrGlobalPatchID, intCoeffsCmpt*pTraits<Type>::one
320
321 );
322 matrix.boundaryCoeffs().set
323 (
324 nbrGlobalPatchID, boundCoeffsCmpt*pTraits<Type>::one
325 );
326 }
327 }
328}
329
330
331// ************************************************************************* //
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const Mesh & mesh() const noexcept
Return const reference to mesh.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
Generic GeometricField class.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
fileName objectPath() const
The complete path + object name.
Definition IOobjectI.H:313
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
void size(const label n)
Definition UList.H:118
commsTypes
Communications types.
Definition UPstream.H:81
@ buffered
"buffered" : (MPI_Bsend, MPI_Recv)
Definition UPstream.H:82
Abstract base class for coupled patches.
coupledFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
This boundary condition enforces a cyclic condition between a pair of boundaries.
const cyclicFvPatchField< Type > & neighbourPatchField() const
Return reference to neighbour patchField.
virtual bool doTransform() const
Does the patch field perform the transformation.
cyclicFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
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.
const cyclicFvPatch & cyclicPatch() const
Return local reference cast into the cyclic patch.
virtual void write(Ostream &os) const
Write.
virtual void manipulateMatrix(fvMatrix< Type > &m, const label iMatrix, const direction cmp)
Manipulate matrix.
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour coupled internal cell data.
virtual const tensorField & forwardT() const
Return face transformation tensor.
Cyclic-plane patch.
cyclicLduInterfaceField()=default
Construct null.
void transformCoupleField(Field< Type > &f) const
Transform given patch field.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Smooth ATC in cells next to a set of patches supplied by type.
Definition faceCells.H:55
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition fvMatrix.H:118
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
Definition fvMatrix.H:549
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
Definition fvMatrix.H:567
const lduPrimitiveMeshAssembly & lduMeshAssembly()
Return optional lduAdressing.
Definition fvMatrix.H:478
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Definition fvMatrix.H:487
const fvPatch & patch() const noexcept
Return the patch.
A FieldMapper for finite-volume patch fields.
virtual void write(Ostream &) const
Write.
const Field< Type > & primitiveField() const noexcept
Return const-reference to the internal field values.
const DimensionedField< Type, volMesh > & internalField() const noexcept
Return const-reference to the dimensioned internal field.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition fvPatch.H:71
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
void addToInternalField(Field< Type > &result, const bool add, const labelUList &faceCells, const scalarField &coeffs, const Field< Type > &vals) const
Add/subtract weighted contributions to internal field.
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition lduMatrix.H:769
bool asymmetric() const noexcept
Matrix is asymmetric (ie, full).
Definition lduMatrix.H:850
const scalarField & diag() const
Definition lduMatrix.C:195
const scalarField & upper() const
Definition lduMatrix.C:235
const scalarField & lower() const
Definition lduMatrix.C:306
const labelListListList & faceBoundMap() const
Return boundary face map.
const labelListList & patchLocalToGlobalMap() const
Return patchLocalToGlobalMap.
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
bool fluxRequired(const word &name) const
Get flux-required for given name, or default.
A class for managing temporary objects.
Definition tmp.H:75
volScalarField & p
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
label patchId(-1)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< label > labelList
A List of labels.
Definition List.H:62
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
void add(DimensionedField< scalar, GeoMesh > &result, const dimensioned< scalar > &dt1, const DimensionedField< scalar, GeoMesh > &f2)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
Field< solveScalar > solveScalarField
uint8_t direction
Definition direction.H:49
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
UList< label > labelUList
A UList of labels.
Definition UList.H:75
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Spatial transformation functions for primitive fields.