1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Hrvoje Jasak, Wikki Ltd. All rights reserved
28 \*---------------------------------------------------------------------------*/
30 #include "regionCoupleFvPatchField.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 regionCoupleFvPatchField<Type>::regionCoupleFvPatchField
43 const DimensionedField<Type, volMesh>& iF
46 coupledFvPatchField<Type>(p, iF),
47 regionCouplePatch_(refCast<const regionCoupleFvPatch>(p)),
48 remoteFieldName_(iF.name()),
54 regionCoupleFvPatchField<Type>::regionCoupleFvPatchField
57 const DimensionedField<Type, volMesh>& iF,
58 const dictionary& dict
61 coupledFvPatchField<Type>(p, iF, dict),
62 regionCouplePatch_(refCast<const regionCoupleFvPatch>(p)),
63 remoteFieldName_(dict.lookup("remoteField")),
66 if (!isType<regionCoupleFvPatch>(p))
70 "regionCoupleFvPatchField<Type>::regionCoupleFvPatchField\n"
72 " const fvPatch& p,\n"
73 " const DimensionedField<Type, volMesh>& iF,\n"
74 " const dictionary& dict\n"
77 ) << "patch " << this->patch().index() << " not regionCouple type. "
78 << "Patch type = " << p.type()
79 << exit(FatalIOError);
85 regionCoupleFvPatchField<Type>::regionCoupleFvPatchField
87 const regionCoupleFvPatchField<Type>& ptf,
89 const DimensionedField<Type, volMesh>& iF,
90 const fvPatchFieldMapper& mapper
93 coupledFvPatchField<Type>(ptf, p, iF, mapper),
94 regionCouplePatch_(refCast<const regionCoupleFvPatch>(p)),
95 remoteFieldName_(ptf.remoteFieldName_),
98 if (!isType<regionCoupleFvPatch>(this->patch()))
102 "regionCoupleFvPatchField<Type>::regionCoupleFvPatchField\n"
104 " const regionCoupleFvPatchField<Type>& ptf,\n"
105 " const fvPatch& p,\n"
106 " const DimensionedField<Type, volMesh>& iF,\n"
107 " const fvPatchFieldMapper& mapper\n"
109 ) << "Field type does not correspond to patch type for patch "
110 << this->patch().index() << "." << endl
111 << "Field type: " << typeName << endl
112 << "Patch type: " << this->patch().type()
119 regionCoupleFvPatchField<Type>::regionCoupleFvPatchField
121 const regionCoupleFvPatchField<Type>& ptf,
122 const DimensionedField<Type, volMesh>& iF
125 regionCoupleLduInterfaceField(),
126 coupledFvPatchField<Type>(ptf, iF),
127 regionCouplePatch_(refCast<const regionCoupleFvPatch>(ptf.patch())),
128 remoteFieldName_(ptf.remoteFieldName_),
129 matrixUpdateBuffer_()
133 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
135 // Return neighbour field
137 const regionCoupleFvPatchField<Type>&
138 regionCoupleFvPatchField<Type>::shadowPatchField() const
140 // Lookup neighbour field
141 typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
143 const GeoField& coupleField =
144 regionCouplePatch_.shadowRegion().
145 objectRegistry::lookupObject<GeoField>(remoteFieldName_);
147 return refCast<const regionCoupleFvPatchField<Type> >
149 coupleField.boundaryField()[regionCouplePatch_.shadowIndex()]
154 // Return neighbour field
156 tmp<Field<Type> > regionCoupleFvPatchField<Type>::patchNeighbourField() const
158 return regionCouplePatch_.interpolate
160 shadowPatchField().patchInternalField()
166 void regionCoupleFvPatchField<Type>::evaluate
168 const Pstream::commsTypes
171 // Implement weights-based stabilised harmonic interpolation using
174 // 1) calculate magnitude of internal field and neighbour field
175 // 2) calculate harmonic mean magnitude
176 // 3) express harmonic mean magnitude as: mean = w*mOwn + (1 - w)*mNei
177 // 4) Based on above, calculate w = (mean - mNei)/(mOwn - mNei)
178 // 5) Use weights to interpolate values
180 Field<Type> fOwn = this->patchInternalField();
181 Field<Type> fNei = this->patchNeighbourField();
183 scalarField magFOwn = mag(fOwn);
184 scalarField magFNei = mag(fNei);
186 // Calculate internal weights using field magnitude
187 scalarField weights(fOwn.size());
189 forAll (weights, faceI)
191 scalar mOwn = magFOwn[faceI];
192 scalar mNei = magFNei[faceI];
194 scalar den = mOwn - mNei;
196 if (mag(den) > SMALL)
198 scalar mean = 2.0*mOwn*mNei/(mOwn + mNei);
199 weights[faceI] = (mean - mNei)/den;
203 weights[faceI] = 0.5;
208 Field<Type>::operator=(weights*fOwn + (1.0 - weights)*fNei);
212 // Initialise neighbour processor internal cell data
214 void regionCoupleFvPatchField<Type>::initInterfaceMatrixUpdate
216 const scalarField& psiInternal,
221 const Pstream::commsTypes
224 matrixUpdateBuffer_ = this->patch().patchInternalField(psiInternal);
228 // Return matrix product for coupled boundary
230 void regionCoupleFvPatchField<Type>::updateInterfaceMatrix
232 const scalarField& psiInternal,
235 const scalarField& coeffs,
236 const direction cmpt,
237 const Pstream::commsTypes
241 regionCouplePatch_.interpolate
243 this->shadowPatchField().matrixUpdateBuffer()
246 // Multiply the field by coefficients and add into the result
247 const unallocLabelList& fc = regionCouplePatch_.faceCells();
251 result[fc[elemI]] -= coeffs[elemI]*pnf[elemI];
258 void regionCoupleFvPatchField<Type>::write(Ostream& os) const
260 fvPatchField<Type>::write(os);
261 os.writeKeyword("remoteField")
262 << remoteFieldName_ << token::END_STATEMENT << nl;
263 this->writeEntry("value", os);
267 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
269 } // End namespace Foam
271 // ************************************************************************* //