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
25 \*---------------------------------------------------------------------------*/
27 #include "genericFvPatchField.H"
28 #include "fvPatchFieldMapper.H"
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 Foam::genericFvPatchField<Type>::genericFvPatchField
36 const DimensionedField<Type, volMesh>& iF
39 calculatedFvPatchField<Type>(p, iF)
43 "genericFvPatchField<Type>::genericFvPatchField"
44 "(const fvPatch& p, const DimensionedField<Type, volMesh>& iF)"
45 ) << "Not Implemented\n "
46 << "Trying to construct an genericFvPatchField on patch "
47 << this->patch().name()
48 << " of field " << this->dimensionedInternalField().name()
54 Foam::genericFvPatchField<Type>::genericFvPatchField
57 const DimensionedField<Type, volMesh>& iF,
58 const dictionary& dict
61 calculatedFvPatchField<Type>(p, iF, dict, false),
62 actualTypeName_(dict.lookup("type")),
65 if (!dict.found("value"))
69 "genericFvPatchField<Type>::genericFvPatchField"
70 "(const fvPatch&, const Field<Type>&, const dictionary&)",
72 ) << "\n Cannot find 'value' entry"
73 << " on patch " << this->patch().name()
74 << " of field " << this->dimensionedInternalField().name()
75 << " in file " << this->dimensionedInternalField().objectPath()
77 << " which is required to set the"
78 " values of the generic patch field." << nl
79 << " (Actual type " << actualTypeName_ << ")" << nl
80 << "\n Please add the 'value' entry to the write function "
81 "of the user-defined boundary-condition\n"
82 " or link the boundary-condition into libfoamUtil.so"
83 << exit(FatalIOError);
88 dictionary::const_iterator iter = dict_.begin();
93 if (iter().keyword() != "type" && iter().keyword() != "value")
98 && iter().stream().size()
101 ITstream& is = iter().stream();
104 token firstToken(is);
109 && firstToken.wordToken() == "nonuniform"
112 token fieldToken(is);
114 if (!fieldToken.isCompound())
119 && fieldToken.labelToken() == 0
132 "genericFvPatchField<Type>::genericFvPatchField"
133 "(const fvPatch&, const Field<Type>&, "
134 "const dictionary&)",
136 ) << "\n token following 'nonuniform' "
138 << "\n on patch " << this->patch().name()
140 << this->dimensionedInternalField().name()
142 << this->dimensionedInternalField().objectPath()
143 << exit(FatalIOError);
148 fieldToken.compoundToken().type()
149 == token::Compound<List<scalar> >::typeName
152 scalarField* fPtr = new scalarField;
155 dynamicCast<token::Compound<List<scalar> > >
157 fieldToken.transferCompoundToken()
161 if (fPtr->size() != this->size())
165 "genericFvPatchField<Type>::genericFvPatchField"
166 "(const fvPatch&, const Field<Type>&, "
167 "const dictionary&)",
169 ) << "\n size of field " << iter().keyword()
170 << " (" << fPtr->size() << ')'
171 << " is not the same size as the patch ("
172 << this->size() << ')'
173 << "\n on patch " << this->patch().name()
175 << this->dimensionedInternalField().name()
177 << this->dimensionedInternalField().objectPath()
178 << exit(FatalIOError);
181 scalarFields_.insert(iter().keyword(), fPtr);
185 fieldToken.compoundToken().type()
186 == token::Compound<List<vector> >::typeName
189 vectorField* fPtr = new vectorField;
192 dynamicCast<token::Compound<List<vector> > >
194 fieldToken.transferCompoundToken()
198 if (fPtr->size() != this->size())
202 "genericFvPatchField<Type>::genericFvPatchField"
203 "(const fvPatch&, const Field<Type>&, "
204 "const dictionary&)",
206 ) << "\n size of field " << iter().keyword()
207 << " (" << fPtr->size() << ')'
208 << " is not the same size as the patch ("
209 << this->size() << ')'
210 << "\n on patch " << this->patch().name()
212 << this->dimensionedInternalField().name()
214 << this->dimensionedInternalField().objectPath()
215 << exit(FatalIOError);
218 vectorFields_.insert(iter().keyword(), fPtr);
222 fieldToken.compoundToken().type()
223 == token::Compound<List<sphericalTensor> >::typeName
226 sphericalTensorField* fPtr = new sphericalTensorField;
231 token::Compound<List<sphericalTensor> >
234 fieldToken.transferCompoundToken()
238 if (fPtr->size() != this->size())
242 "genericFvPatchField<Type>::genericFvPatchField"
243 "(const fvPatch&, const Field<Type>&, "
244 "const dictionary&)",
246 ) << "\n size of field " << iter().keyword()
247 << " (" << fPtr->size() << ')'
248 << " is not the same size as the patch ("
249 << this->size() << ')'
250 << "\n on patch " << this->patch().name()
252 << this->dimensionedInternalField().name()
254 << this->dimensionedInternalField().objectPath()
255 << exit(FatalIOError);
258 sphericalTensorFields_.insert(iter().keyword(), fPtr);
262 fieldToken.compoundToken().type()
263 == token::Compound<List<symmTensor> >::typeName
266 symmTensorField* fPtr = new symmTensorField;
271 token::Compound<List<symmTensor> >
274 fieldToken.transferCompoundToken()
278 if (fPtr->size() != this->size())
282 "genericFvPatchField<Type>::genericFvPatchField"
283 "(const fvPatch&, const Field<Type>&, "
284 "const dictionary&)",
286 ) << "\n size of field " << iter().keyword()
287 << " (" << fPtr->size() << ')'
288 << " is not the same size as the patch ("
289 << this->size() << ')'
290 << "\n on patch " << this->patch().name()
292 << this->dimensionedInternalField().name()
294 << this->dimensionedInternalField().objectPath()
295 << exit(FatalIOError);
298 symmTensorFields_.insert(iter().keyword(), fPtr);
302 fieldToken.compoundToken().type()
303 == token::Compound<List<tensor> >::typeName
306 tensorField* fPtr = new tensorField;
309 dynamicCast<token::Compound<List<tensor> > >
311 fieldToken.transferCompoundToken()
315 if (fPtr->size() != this->size())
319 "genericFvPatchField<Type>::genericFvPatchField"
320 "(const fvPatch&, const Field<Type>&, "
321 "const dictionary&)",
323 ) << "\n size of field " << iter().keyword()
324 << " (" << fPtr->size() << ')'
325 << " is not the same size as the patch ("
326 << this->size() << ')'
327 << "\n on patch " << this->patch().name()
329 << this->dimensionedInternalField().name()
331 << this->dimensionedInternalField().objectPath()
332 << exit(FatalIOError);
335 tensorFields_.insert(iter().keyword(), fPtr);
341 "genericFvPatchField<Type>::genericFvPatchField"
342 "(const fvPatch&, const Field<Type>&, "
343 "const dictionary&)",
345 ) << "\n compound " << fieldToken.compoundToken()
347 << "\n on patch " << this->patch().name()
349 << this->dimensionedInternalField().name()
351 << this->dimensionedInternalField().objectPath()
352 << exit(FatalIOError);
358 && firstToken.wordToken() == "uniform"
361 token fieldToken(is);
363 if (!fieldToken.isPunctuation())
377 // Read as scalarList.
378 is.putBack(fieldToken);
382 if (l.size() == vector::nComponents)
384 vector vs(l[0], l[1], l[2]);
389 new vectorField(this->size(), vs)
392 else if (l.size() == sphericalTensor::nComponents)
394 sphericalTensor vs(l[0]);
396 sphericalTensorFields_.insert
399 new sphericalTensorField(this->size(), vs)
402 else if (l.size() == symmTensor::nComponents)
404 symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]);
406 symmTensorFields_.insert
409 new symmTensorField(this->size(), vs)
412 else if (l.size() == tensor::nComponents)
424 new tensorField(this->size(), vs)
431 "genericFvPatchField<Type>::genericFvPatchField"
432 "(const fvPatch&, const Field<Type>&, "
433 "const dictionary&)",
435 ) << "\n unrecognised native type " << l
436 << "\n on patch " << this->patch().name()
438 << this->dimensionedInternalField().name()
440 << this->dimensionedInternalField().objectPath()
441 << exit(FatalIOError);
452 Foam::genericFvPatchField<Type>::genericFvPatchField
454 const genericFvPatchField<Type>& ptf,
456 const DimensionedField<Type, volMesh>& iF,
457 const fvPatchFieldMapper& mapper
460 calculatedFvPatchField<Type>(ptf, p, iF, mapper),
461 actualTypeName_(ptf.actualTypeName_),
466 HashPtrTable<scalarField>::const_iterator iter =
467 ptf.scalarFields_.begin();
468 iter != ptf.scalarFields_.end();
472 scalarFields_.insert(iter.key(), new scalarField(*iter(), mapper));
477 HashPtrTable<vectorField>::const_iterator iter =
478 ptf.vectorFields_.begin();
479 iter != ptf.vectorFields_.end();
483 vectorFields_.insert(iter.key(), new vectorField(*iter(), mapper));
488 HashPtrTable<sphericalTensorField>::const_iterator iter =
489 ptf.sphericalTensorFields_.begin();
490 iter != ptf.sphericalTensorFields_.end();
494 sphericalTensorFields_.insert
497 new sphericalTensorField(*iter(), mapper)
503 HashPtrTable<symmTensorField>::const_iterator iter =
504 ptf.symmTensorFields_.begin();
505 iter != ptf.symmTensorFields_.end();
509 symmTensorFields_.insert
512 new symmTensorField(*iter(), mapper)
518 HashPtrTable<tensorField>::const_iterator iter =
519 ptf.tensorFields_.begin();
520 iter != ptf.tensorFields_.end();
524 tensorFields_.insert(iter.key(), new tensorField(*iter(), mapper));
530 Foam::genericFvPatchField<Type>::genericFvPatchField
532 const genericFvPatchField<Type>& ptf
535 calculatedFvPatchField<Type>(ptf),
536 actualTypeName_(ptf.actualTypeName_),
538 scalarFields_(ptf.scalarFields_),
539 vectorFields_(ptf.vectorFields_),
540 sphericalTensorFields_(ptf.sphericalTensorFields_),
541 symmTensorFields_(ptf.symmTensorFields_),
542 tensorFields_(ptf.tensorFields_)
547 Foam::genericFvPatchField<Type>::genericFvPatchField
549 const genericFvPatchField<Type>& ptf,
550 const DimensionedField<Type, volMesh>& iF
553 calculatedFvPatchField<Type>(ptf, iF),
554 actualTypeName_(ptf.actualTypeName_),
556 scalarFields_(ptf.scalarFields_),
557 vectorFields_(ptf.vectorFields_),
558 sphericalTensorFields_(ptf.sphericalTensorFields_),
559 symmTensorFields_(ptf.symmTensorFields_),
560 tensorFields_(ptf.tensorFields_)
564 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
567 void Foam::genericFvPatchField<Type>::autoMap
569 const fvPatchFieldMapper& m
572 calculatedFvPatchField<Type>::autoMap(m);
576 HashPtrTable<scalarField>::iterator iter = scalarFields_.begin();
577 iter != scalarFields_.end();
586 HashPtrTable<vectorField>::iterator iter = vectorFields_.begin();
587 iter != vectorFields_.end();
596 HashPtrTable<sphericalTensorField>::iterator iter =
597 sphericalTensorFields_.begin();
598 iter != sphericalTensorFields_.end();
607 HashPtrTable<symmTensorField>::iterator iter =
608 symmTensorFields_.begin();
609 iter != symmTensorFields_.end();
618 HashPtrTable<tensorField>::iterator iter = tensorFields_.begin();
619 iter != tensorFields_.end();
629 void Foam::genericFvPatchField<Type>::rmap
631 const fvPatchField<Type>& ptf,
632 const labelList& addr
635 calculatedFvPatchField<Type>::rmap(ptf, addr);
637 const genericFvPatchField<Type>& dptf =
638 refCast<const genericFvPatchField<Type> >(ptf);
642 HashPtrTable<scalarField>::iterator iter = scalarFields_.begin();
643 iter != scalarFields_.end();
647 HashPtrTable<scalarField>::const_iterator dptfIter =
648 dptf.scalarFields_.find(iter.key());
650 if (dptfIter != dptf.scalarFields_.end())
652 iter()->rmap(*dptfIter(), addr);
658 HashPtrTable<vectorField>::iterator iter = vectorFields_.begin();
659 iter != vectorFields_.end();
663 HashPtrTable<vectorField>::const_iterator dptfIter =
664 dptf.vectorFields_.find(iter.key());
666 if (dptfIter != dptf.vectorFields_.end())
668 iter()->rmap(*dptfIter(), addr);
674 HashPtrTable<sphericalTensorField>::iterator iter =
675 sphericalTensorFields_.begin();
676 iter != sphericalTensorFields_.end();
680 HashPtrTable<sphericalTensorField>::const_iterator dptfIter =
681 dptf.sphericalTensorFields_.find(iter.key());
683 if (dptfIter != dptf.sphericalTensorFields_.end())
685 iter()->rmap(*dptfIter(), addr);
691 HashPtrTable<symmTensorField>::iterator iter =
692 symmTensorFields_.begin();
693 iter != symmTensorFields_.end();
697 HashPtrTable<symmTensorField>::const_iterator dptfIter =
698 dptf.symmTensorFields_.find(iter.key());
700 if (dptfIter != dptf.symmTensorFields_.end())
702 iter()->rmap(*dptfIter(), addr);
708 HashPtrTable<tensorField>::iterator iter = tensorFields_.begin();
709 iter != tensorFields_.end();
713 HashPtrTable<tensorField>::const_iterator dptfIter =
714 dptf.tensorFields_.find(iter.key());
716 if (dptfIter != dptf.tensorFields_.end())
718 iter()->rmap(*dptfIter(), addr);
725 Foam::tmp<Foam::Field<Type> >
726 Foam::genericFvPatchField<Type>::valueInternalCoeffs
728 const tmp<scalarField>&
733 "genericFvPatchField<Type>::"
734 "valueInternalCoeffs(const tmp<scalarField>&) const"
736 "valueInternalCoeffs cannot be called for a genericFvPatchField"
737 " (actual type " << actualTypeName_ << ")"
738 << "\n on patch " << this->patch().name()
739 << " of field " << this->dimensionedInternalField().name()
740 << " in file " << this->dimensionedInternalField().objectPath()
741 << "\n You are probably trying to solve for a field with a "
742 "generic boundary condition."
750 Foam::tmp<Foam::Field<Type> >
751 Foam::genericFvPatchField<Type>::valueBoundaryCoeffs
753 const tmp<scalarField>&
758 "genericFvPatchField<Type>::"
759 "valueBoundaryCoeffs(const tmp<scalarField>&) const"
761 "valueBoundaryCoeffs cannot be called for a genericFvPatchField"
762 " (actual type " << actualTypeName_ << ")"
763 << "\n on patch " << this->patch().name()
764 << " of field " << this->dimensionedInternalField().name()
765 << " in file " << this->dimensionedInternalField().objectPath()
766 << "\n You are probably trying to solve for a field with a "
767 "generic boundary condition."
775 Foam::tmp<Foam::Field<Type> >
776 Foam::genericFvPatchField<Type>::gradientInternalCoeffs() const
780 "genericFvPatchField<Type>::"
781 "gradientInternalCoeffs() const"
783 "gradientInternalCoeffs cannot be called for a genericFvPatchField"
784 " (actual type " << actualTypeName_ << ")"
785 << "\n on patch " << this->patch().name()
786 << " of field " << this->dimensionedInternalField().name()
787 << " in file " << this->dimensionedInternalField().objectPath()
788 << "\n You are probably trying to solve for a field with a "
789 "generic boundary condition."
796 Foam::tmp<Foam::Field<Type> >
797 Foam::genericFvPatchField<Type>::gradientBoundaryCoeffs() const
801 "genericFvPatchField<Type>::"
802 "gradientBoundaryCoeffs() const"
804 "gradientBoundaryCoeffs cannot be called for a genericFvPatchField"
805 " (actual type " << actualTypeName_ << ")"
806 << "\n on patch " << this->patch().name()
807 << " of field " << this->dimensionedInternalField().name()
808 << " in file " << this->dimensionedInternalField().objectPath()
809 << "\n You are probably trying to solve for a field with a "
810 "generic boundary condition."
818 void Foam::genericFvPatchField<Type>::write(Ostream& os) const
820 os.writeKeyword("type") << actualTypeName_ << token::END_STATEMENT << nl;
824 dictionary::const_iterator iter = dict_.begin();
829 if (iter().keyword() != "type" && iter().keyword() != "value")
834 && iter().stream().size()
835 && iter().stream()[0].isWord()
836 && iter().stream()[0].wordToken() == "nonuniform"
839 if (scalarFields_.found(iter().keyword()))
841 scalarFields_.find(iter().keyword())()
842 ->writeEntry(iter().keyword(), os);
844 else if (vectorFields_.found(iter().keyword()))
846 vectorFields_.find(iter().keyword())()
847 ->writeEntry(iter().keyword(), os);
849 else if (sphericalTensorFields_.found(iter().keyword()))
851 sphericalTensorFields_.find(iter().keyword())()
852 ->writeEntry(iter().keyword(), os);
854 else if (symmTensorFields_.found(iter().keyword()))
856 symmTensorFields_.find(iter().keyword())()
857 ->writeEntry(iter().keyword(), os);
859 else if (tensorFields_.found(iter().keyword()))
861 tensorFields_.find(iter().keyword())()
862 ->writeEntry(iter().keyword(), os);
872 this->writeEntry("value", os);
876 // ************************************************************************* //