Transferred copyright to the OpenFOAM Foundation
[OpenFOAM-2.0.x.git] / src / finiteVolume / fields / fvPatchFields / derived / directMappedFixedValue / directMappedFixedValueFvPatchField.C
blobd5056caa3440fa481a1ec3cc48ca56275b72bc0d
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "directMappedFixedValueFvPatchField.H"
27 #include "directMappedPatchBase.H"
28 #include "volFields.H"
29 #include "interpolationCell.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 namespace Foam
36 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
38 template<class Type>
39 directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
41     const fvPatch& p,
42     const DimensionedField<Type, volMesh>& iF
45     fixedValueFvPatchField<Type>(p, iF),
46     fieldName_(iF.name()),
47     setAverage_(false),
48     average_(pTraits<Type>::zero),
49     interpolationScheme_(interpolationCell<Type>::typeName)
53 template<class Type>
54 directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
56     const directMappedFixedValueFvPatchField<Type>& ptf,
57     const fvPatch& p,
58     const DimensionedField<Type, volMesh>& iF,
59     const fvPatchFieldMapper& mapper
62     fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
63     fieldName_(ptf.fieldName_),
64     setAverage_(ptf.setAverage_),
65     average_(ptf.average_),
66     interpolationScheme_(ptf.interpolationScheme_)
68     if (!isA<directMappedPatchBase>(this->patch().patch()))
69     {
70         FatalErrorIn
71         (
72             "directMappedFixedValueFvPatchField<Type>::"
73             "directMappedFixedValueFvPatchField\n"
74             "(\n"
75             "    const directMappedFixedValueFvPatchField<Type>&,\n"
76             "    const fvPatch&,\n"
77             "    const Field<Type>&,\n"
78             "    const fvPatchFieldMapper&\n"
79             ")\n"
80         )   << "\n    patch type '" << p.type()
81             << "' not type '" << directMappedPatchBase::typeName << "'"
82             << "\n    for patch " << p.name()
83             << " of field " << this->dimensionedInternalField().name()
84             << " in file " << this->dimensionedInternalField().objectPath()
85             << exit(FatalError);
86     }
90 template<class Type>
91 directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
93     const fvPatch& p,
94     const DimensionedField<Type, volMesh>& iF,
95     const dictionary& dict
98     fixedValueFvPatchField<Type>(p, iF, dict),
99     fieldName_(dict.lookupOrDefault<word>("fieldName", iF.name())),
100     setAverage_(readBool(dict.lookup("setAverage"))),
101     average_(pTraits<Type>(dict.lookup("average"))),
102     interpolationScheme_(interpolationCell<Type>::typeName)
104     if (!isA<directMappedPatchBase>(this->patch().patch()))
105     {
106         FatalErrorIn
107         (
108             "directMappedFixedValueFvPatchField<Type>::"
109             "directMappedFixedValueFvPatchField\n"
110             "(\n"
111             "    const fvPatch& p,\n"
112             "    const DimensionedField<Type, volMesh>& iF,\n"
113             "    const dictionary& dict\n"
114             ")\n"
115         )   << "\n    patch type '" << p.type()
116             << "' not type '" << directMappedPatchBase::typeName << "'"
117             << "\n    for patch " << p.name()
118             << " of field " << this->dimensionedInternalField().name()
119             << " in file " << this->dimensionedInternalField().objectPath()
120             << exit(FatalError);
121     }
123     const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
124     (
125         directMappedFixedValueFvPatchField<Type>::patch().patch()
126     );
127     if (mpp.mode() == directMappedPatchBase::NEARESTCELL)
128     {
129         dict.lookup("interpolationScheme") >> interpolationScheme_;
130     }
134 template<class Type>
135 directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
137     const directMappedFixedValueFvPatchField<Type>& ptf
140     fixedValueFvPatchField<Type>(ptf),
141     fieldName_(ptf.fieldName_),
142     setAverage_(ptf.setAverage_),
143     average_(ptf.average_),
144     interpolationScheme_(ptf.interpolationScheme_)
148 template<class Type>
149 directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
151     const directMappedFixedValueFvPatchField<Type>& ptf,
152     const DimensionedField<Type, volMesh>& iF
155     fixedValueFvPatchField<Type>(ptf, iF),
156     fieldName_(ptf.fieldName_),
157     setAverage_(ptf.setAverage_),
158     average_(ptf.average_),
159     interpolationScheme_(ptf.interpolationScheme_)
163 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
165 template<class Type>
166 const GeometricField<Type, fvPatchField, volMesh>&
167 directMappedFixedValueFvPatchField<Type>::sampleField() const
169     typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
171     const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
172     (
173         directMappedFixedValueFvPatchField<Type>::patch().patch()
174     );
175     const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
177     if (mpp.sameRegion())
178     {
179         if (fieldName_ == this->dimensionedInternalField().name())
180         {
181             // Optimisation: bypass field lookup
182             return
183                 dynamic_cast<const fieldType&>
184                 (
185                     this->dimensionedInternalField()
186                 );
187         }
188         else
189         {
190             const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
191             return thisMesh.lookupObject<fieldType>(fieldName_);
192         }
193     }
194     else
195     {
196         return nbrMesh.lookupObject<fieldType>(fieldName_);
197     }
201 template<class Type>
202 const interpolation<Type>&
203 directMappedFixedValueFvPatchField<Type>::interpolator() const
205     if (!interpolator_.valid())
206     {
207         interpolator_ = interpolation<Type>::New
208         (
209             interpolationScheme_,
210             sampleField()
211         );
212     }
213     return interpolator_();
217 template<class Type>
218 void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
220     if (this->updated())
221     {
222         return;
223     }
225     typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
227     // Get the scheduling information from the directMappedPatchBase
228     const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
229     (
230         directMappedFixedValueFvPatchField<Type>::patch().patch()
231     );
232     const mapDistribute& distMap = mpp.map();
234     const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
235     const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
237     // Result of obtaining remote values
238     Field<Type> newValues;
240     switch (mpp.mode())
241     {
242         case directMappedPatchBase::NEARESTCELL:
243         {
244             if (interpolationScheme_ != interpolationCell<Type>::typeName)
245             {
246                 // Send back sample points to the processor that holds the cell
247                 vectorField samples(mpp.samplePoints());
248                 distMap.reverseDistribute
249                 (
250                     (mpp.sameRegion() ? thisMesh.nCells() : nbrMesh.nCells()),
251                     point::max,
252                     samples
253                 );
255                 const interpolation<Type>& interp = interpolator();
257                 newValues.setSize(samples.size(), pTraits<Type>::max);
258                 forAll(samples, cellI)
259                 {
260                     if (samples[cellI] != point::max)
261                     {
262                         newValues[cellI] = interp.interpolate
263                         (
264                             samples[cellI],
265                             cellI
266                         );
267                     }
268                 }
269             }
270             else
271             {
272                 newValues = sampleField();
273             }
275             distMap.distribute(newValues);
277             break;
278         }
279         case directMappedPatchBase::NEARESTPATCHFACE:
280         {
281             const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
282             (
283                 mpp.samplePatch()
284             );
285             if (nbrPatchID < 0)
286             {
287                 FatalErrorIn
288                 (
289                     "void directMappedFixedValueFvPatchField<Type>::"
290                     "updateCoeffs()"
291                 )<< "Unable to find sample patch " << mpp.samplePatch()
292                  << " in region " << mpp.sampleRegion()
293                  << " for patch " << this->patch().name() << nl
294                  << abort(FatalError);
295             }
297             const fieldType& nbrField = sampleField();
299             newValues = nbrField.boundaryField()[nbrPatchID];
300             distMap.distribute(newValues);
302             break;
303         }
304         case directMappedPatchBase::NEARESTFACE:
305         {
306             Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
308             const fieldType& nbrField = sampleField();
310             forAll(nbrField.boundaryField(), patchI)
311             {
312                 const fvPatchField<Type>& pf =
313                     nbrField.boundaryField()[patchI];
314                 label faceStart = pf.patch().start();
316                 forAll(pf, faceI)
317                 {
318                     allValues[faceStart++] = pf[faceI];
319                 }
320             }
322             distMap.distribute(allValues);
323             newValues.transfer(allValues);
325             break;
326         }
327         default:
328         {
329             FatalErrorIn
330             (
331                 "directMappedFixedValueFvPatchField<Type>::updateCoeffs()"
332             )<< "Unknown sampling mode: " << mpp.mode()
333              << nl << abort(FatalError);
334         }
335     }
337     if (setAverage_)
338     {
339         Type averagePsi =
340             gSum(this->patch().magSf()*newValues)
341            /gSum(this->patch().magSf());
343         if (mag(averagePsi)/mag(average_) > 0.5)
344         {
345             newValues *= mag(average_)/mag(averagePsi);
346         }
347         else
348         {
349             newValues += (average_ - averagePsi);
350         }
351     }
353     this->operator==(newValues);
355     if (debug)
356     {
357         Info<< "directMapped on field:"
358             << this->dimensionedInternalField().name()
359             << " patch:" << this->patch().name()
360             << "  avg:" << gAverage(*this)
361             << "  min:" << gMin(*this)
362             << "  max:" << gMax(*this)
363             << endl;
364     }
366     fixedValueFvPatchField<Type>::updateCoeffs();
370 template<class Type>
371 void directMappedFixedValueFvPatchField<Type>::write(Ostream& os) const
373     fvPatchField<Type>::write(os);
374     os.writeKeyword("fieldName") << fieldName_ << token::END_STATEMENT << nl;
375     os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
376     os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
377     os.writeKeyword("interpolationScheme") << interpolationScheme_
378         << token::END_STATEMENT << nl;
379     this->writeEntry("value", os);
383 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
385 } // End namespace Foam
387 // ************************************************************************* //