All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
genericFvPatchField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "genericFvPatchField.H"
27 #include "fvPatchFieldMapper.H"
28 
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 
31 template<class Type>
33 (
34  const fvPatch& p,
36 )
37 :
39 {
41  << "Trying to construct an genericFvPatchField on patch "
42  << this->patch().name()
43  << " of field " << this->internalField().name()
44  << abort(FatalError);
45 }
46 
47 
48 template<class Type>
50 (
51  const fvPatch& p,
53  const dictionary& dict
54 )
55 :
56  genericPatchField(dict.lookup("type")),
57  calculatedFvPatchField<Type>(p, iF, dict),
58  dict_(dict)
59 {
60  if (!dict.found("value"))
61  {
63  (
64  dict
65  ) << "\n Cannot find 'value' entry"
66  << " on patch " << this->patch().name()
67  << " of field " << this->internalField().name()
68  << " in file " << this->internalField().objectPath()
69  << nl
70  << " which is required to set the"
71  " values of the generic patch field." << nl
72  << " (Actual type " << actualTypeName() << ")" << nl
73  << "\n Please add the 'value' entry to the write function "
74  "of the user-defined boundary-condition\n"
75  << exit(FatalIOError);
76  }
77 
78  forAllConstIter(dictionary, dict_, iter)
79  {
80  if (iter().keyword() != "type" && iter().keyword() != "value")
81  {
82  if
83  (
84  iter().isStream()
85  && iter().stream().size()
86  )
87  {
88  ITstream& is = iter().stream();
89 
90  // Read first token
91  token firstToken(is);
92 
93  if
94  (
95  firstToken.isWord()
96  && firstToken.wordToken() == "nonuniform"
97  )
98  {
99  token fieldToken(is);
100 
101  if (!fieldToken.isCompound())
102  {
103  if
104  (
105  fieldToken.isLabel()
106  && fieldToken.labelToken() == 0
107  )
108  {
109  scalarFields_.insert
110  (
111  iter().keyword(),
112  new scalarField(0)
113  );
114  }
115  else
116  {
118  (
119  dict
120  ) << "\n token following 'nonuniform' "
121  "is not a compound"
122  << "\n on patch " << this->patch().name()
123  << " of field "
124  << this->internalField().name()
125  << " in file "
126  << this->internalField().objectPath()
127  << exit(FatalIOError);
128  }
129  }
130  else if
131  (
132  fieldToken.compoundToken().type()
133  == token::Compound<List<scalar>>::typeName
134  )
135  {
136  scalarField* fPtr = new scalarField;
137  fPtr->transfer
138  (
140  (
141  fieldToken.transferCompoundToken(is)
142  )
143  );
144 
145  if (fPtr->size() != this->size())
146  {
148  (
149  dict
150  ) << "\n size of field " << iter().keyword()
151  << " (" << fPtr->size() << ')'
152  << " is not the same size as the patch ("
153  << this->size() << ')'
154  << "\n on patch " << this->patch().name()
155  << " of field "
156  << this->internalField().name()
157  << " in file "
158  << this->internalField().objectPath()
159  << exit(FatalIOError);
160  }
161 
162  scalarFields_.insert(iter().keyword(), fPtr);
163  }
164  else if
165  (
166  fieldToken.compoundToken().type()
167  == token::Compound<List<vector>>::typeName
168  )
169  {
170  vectorField* fPtr = new vectorField;
171  fPtr->transfer
172  (
174  (
175  fieldToken.transferCompoundToken(is)
176  )
177  );
178 
179  if (fPtr->size() != this->size())
180  {
182  (
183  dict
184  ) << "\n size of field " << iter().keyword()
185  << " (" << fPtr->size() << ')'
186  << " is not the same size as the patch ("
187  << this->size() << ')'
188  << "\n on patch " << this->patch().name()
189  << " of field "
190  << this->internalField().name()
191  << " in file "
192  << this->internalField().objectPath()
193  << exit(FatalIOError);
194  }
195 
196  vectorFields_.insert(iter().keyword(), fPtr);
197  }
198  else if
199  (
200  fieldToken.compoundToken().type()
202  )
203  {
205  fPtr->transfer
206  (
208  <
210  >
211  (
212  fieldToken.transferCompoundToken(is)
213  )
214  );
215 
216  if (fPtr->size() != this->size())
217  {
219  (
220  dict
221  ) << "\n size of field " << iter().keyword()
222  << " (" << fPtr->size() << ')'
223  << " is not the same size as the patch ("
224  << this->size() << ')'
225  << "\n on patch " << this->patch().name()
226  << " of field "
227  << this->internalField().name()
228  << " in file "
229  << this->internalField().objectPath()
230  << exit(FatalIOError);
231  }
232 
233  sphericalTensorFields_.insert(iter().keyword(), fPtr);
234  }
235  else if
236  (
237  fieldToken.compoundToken().type()
239  )
240  {
241  symmTensorField* fPtr = new symmTensorField;
242  fPtr->transfer
243  (
245  <
247  >
248  (
249  fieldToken.transferCompoundToken(is)
250  )
251  );
252 
253  if (fPtr->size() != this->size())
254  {
256  (
257  dict
258  ) << "\n size of field " << iter().keyword()
259  << " (" << fPtr->size() << ')'
260  << " is not the same size as the patch ("
261  << this->size() << ')'
262  << "\n on patch " << this->patch().name()
263  << " of field "
264  << this->internalField().name()
265  << " in file "
266  << this->internalField().objectPath()
267  << exit(FatalIOError);
268  }
269 
270  symmTensorFields_.insert(iter().keyword(), fPtr);
271  }
272  else if
273  (
274  fieldToken.compoundToken().type()
275  == token::Compound<List<tensor>>::typeName
276  )
277  {
278  tensorField* fPtr = new tensorField;
279  fPtr->transfer
280  (
282  (
283  fieldToken.transferCompoundToken(is)
284  )
285  );
286 
287  if (fPtr->size() != this->size())
288  {
290  (
291  dict
292  ) << "\n size of field " << iter().keyword()
293  << " (" << fPtr->size() << ')'
294  << " is not the same size as the patch ("
295  << this->size() << ')'
296  << "\n on patch " << this->patch().name()
297  << " of field "
298  << this->internalField().name()
299  << " in file "
300  << this->internalField().objectPath()
301  << exit(FatalIOError);
302  }
303 
304  tensorFields_.insert(iter().keyword(), fPtr);
305  }
306  else
307  {
309  (
310  dict
311  ) << "\n compound " << fieldToken.compoundToken()
312  << " not supported"
313  << "\n on patch " << this->patch().name()
314  << " of field "
315  << this->internalField().name()
316  << " in file "
317  << this->internalField().objectPath()
318  << exit(FatalIOError);
319  }
320  }
321  else if
322  (
323  firstToken.isWord()
324  && firstToken.wordToken() == "uniform"
325  )
326  {
327  token fieldToken(is);
328 
329  if (!fieldToken.isPunctuation())
330  {
331  scalarFields_.insert
332  (
333  iter().keyword(),
334  new scalarField
335  (
336  this->size(),
337  fieldToken.number()
338  )
339  );
340  }
341  else
342  {
343  // Read as scalarList.
344  is.putBack(fieldToken);
345 
346  scalarList l(is);
347 
348  if (l.size() == vector::nComponents)
349  {
350  vector vs(l[0], l[1], l[2]);
351 
352  vectorFields_.insert
353  (
354  iter().keyword(),
355  new vectorField(this->size(), vs)
356  );
357  }
358  else if (l.size() == sphericalTensor::nComponents)
359  {
360  sphericalTensor vs(l[0]);
361 
362  sphericalTensorFields_.insert
363  (
364  iter().keyword(),
365  new sphericalTensorField(this->size(), vs)
366  );
367  }
368  else if (l.size() == symmTensor::nComponents)
369  {
370  symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]);
371 
372  symmTensorFields_.insert
373  (
374  iter().keyword(),
375  new symmTensorField(this->size(), vs)
376  );
377  }
378  else if (l.size() == tensor::nComponents)
379  {
380  tensor vs
381  (
382  l[0], l[1], l[2],
383  l[3], l[4], l[5],
384  l[6], l[7], l[8]
385  );
386 
387  tensorFields_.insert
388  (
389  iter().keyword(),
390  new tensorField(this->size(), vs)
391  );
392  }
393  else
394  {
396  (
397  dict
398  ) << "\n unrecognised native type " << l
399  << "\n on patch " << this->patch().name()
400  << " of field "
401  << this->internalField().name()
402  << " in file "
403  << this->internalField().objectPath()
404  << exit(FatalIOError);
405  }
406  }
407  }
408  }
409  }
410  }
411 }
412 
413 
414 template<class Type>
416 (
417  const genericFvPatchField<Type>& ptf,
418  const fvPatch& p,
420  const fvPatchFieldMapper& mapper
421 )
422 :
423  genericPatchField(ptf),
424  calculatedFvPatchField<Type>(ptf, p, iF, mapper),
425  dict_(ptf.dict_)
426 {
428  (
430  ptf.scalarFields_,
431  iter
432  )
433  {
434  scalarFields_.insert
435  (
436  iter.key(),
437  mapper(*iter()).ptr()
438  );
439  }
440 
442  (
444  ptf.vectorFields_,
445  iter
446  )
447  {
448  vectorFields_.insert
449  (
450  iter.key(),
451  mapper(*iter()).ptr()
452  );
453  }
454 
456  (
458  ptf.sphericalTensorFields_,
459  iter
460  )
461  {
462  sphericalTensorFields_.insert
463  (
464  iter.key(),
465  mapper(*iter()).ptr()
466  );
467  }
468 
470  (
472  ptf.symmTensorFields_,
473  iter
474  )
475  {
476  symmTensorFields_.insert
477  (
478  iter.key(),
479  mapper(*iter()).ptr()
480  );
481  }
482 
484  (
486  ptf.tensorFields_,
487  iter
488  )
489  {
490  tensorFields_.insert
491  (
492  iter.key(),
493  mapper(*iter()).ptr()
494  );
495  }
496 }
497 
498 
499 template<class Type>
501 (
502  const genericFvPatchField<Type>& ptf
503 )
504 :
505  genericPatchField(ptf),
507  dict_(ptf.dict_),
508  scalarFields_(ptf.scalarFields_),
509  vectorFields_(ptf.vectorFields_),
510  sphericalTensorFields_(ptf.sphericalTensorFields_),
511  symmTensorFields_(ptf.symmTensorFields_),
512  tensorFields_(ptf.tensorFields_)
513 {}
514 
515 
516 template<class Type>
518 (
519  const genericFvPatchField<Type>& ptf,
521 )
522 :
523  genericPatchField(ptf),
525  dict_(ptf.dict_),
526  scalarFields_(ptf.scalarFields_),
527  vectorFields_(ptf.vectorFields_),
528  sphericalTensorFields_(ptf.sphericalTensorFields_),
529  symmTensorFields_(ptf.symmTensorFields_),
530  tensorFields_(ptf.tensorFields_)
531 {}
532 
533 
534 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
535 
536 template<class Type>
538 (
539  const fvPatchFieldMapper& m
540 )
541 {
543 
544  forAllIter
545  (
547  scalarFields_,
548  iter
549  )
550  {
551  m(*iter(), *iter());
552  }
553 
554  forAllIter
555  (
557  vectorFields_,
558  iter
559  )
560  {
561  m(*iter(), *iter());
562  }
563 
564  forAllIter
565  (
567  sphericalTensorFields_,
568  iter
569  )
570  {
571  m(*iter(), *iter());
572  }
573 
574  forAllIter
575  (
577  symmTensorFields_,
578  iter
579  )
580  {
581  m(*iter(), *iter());
582  }
583 
584  forAllIter
585  (
587  tensorFields_,
588  iter
589  )
590  {
591  m(*iter(), *iter());
592  }
593 }
594 
595 
596 template<class Type>
598 (
599  const fvPatchField<Type>& ptf,
600  const labelList& addr
601 )
602 {
604 
605  const genericFvPatchField<Type>& dptf =
606  refCast<const genericFvPatchField<Type>>(ptf);
607 
608  forAllIter
609  (
611  scalarFields_,
612  iter
613  )
614  {
616  dptf.scalarFields_.find(iter.key());
617 
618  if (dptfIter != dptf.scalarFields_.end())
619  {
620  iter()->rmap(*dptfIter(), addr);
621  }
622  }
623 
624  forAllIter
625  (
627  vectorFields_,
628  iter
629  )
630  {
632  dptf.vectorFields_.find(iter.key());
633 
634  if (dptfIter != dptf.vectorFields_.end())
635  {
636  iter()->rmap(*dptfIter(), addr);
637  }
638  }
639 
640  forAllIter
641  (
643  sphericalTensorFields_,
644  iter
645  )
646  {
648  dptf.sphericalTensorFields_.find(iter.key());
649 
650  if (dptfIter != dptf.sphericalTensorFields_.end())
651  {
652  iter()->rmap(*dptfIter(), addr);
653  }
654  }
655 
656  forAllIter
657  (
659  symmTensorFields_,
660  iter
661  )
662  {
664  dptf.symmTensorFields_.find(iter.key());
665 
666  if (dptfIter != dptf.symmTensorFields_.end())
667  {
668  iter()->rmap(*dptfIter(), addr);
669  }
670  }
671 
672  forAllIter
673  (
675  tensorFields_,
676  iter
677  )
678  {
680  dptf.tensorFields_.find(iter.key());
681 
682  if (dptfIter != dptf.tensorFields_.end())
683  {
684  iter()->rmap(*dptfIter(), addr);
685  }
686  }
687 }
688 
689 
690 template<class Type>
693 (
694  const tmp<scalarField>&
695 ) const
696 {
698  << "cannot be called for a genericFvPatchField"
699  " (actual type " << actualTypeName() << ")"
700  << "\n on patch " << this->patch().name()
701  << " of field " << this->internalField().name()
702  << " in file " << this->internalField().objectPath()
703  << "\n You are probably trying to solve for a field with a "
704  "generic boundary condition."
705  << abort(FatalError);
706 
707  return *this;
708 }
709 
710 
711 template<class Type>
714 (
715  const tmp<scalarField>&
716 ) const
717 {
719  << "cannot be called for a genericFvPatchField"
720  " (actual type " << actualTypeName() << ")"
721  << "\n on patch " << this->patch().name()
722  << " of field " << this->internalField().name()
723  << " in file " << this->internalField().objectPath()
724  << "\n You are probably trying to solve for a field with a "
725  "generic boundary condition."
726  << abort(FatalError);
727 
728  return *this;
729 }
730 
731 
732 template<class Type>
735 {
737  << "cannot be called for a genericFvPatchField"
738  " (actual type " << actualTypeName() << ")"
739  << "\n on patch " << this->patch().name()
740  << " of field " << this->internalField().name()
741  << " in file " << this->internalField().objectPath()
742  << "\n You are probably trying to solve for a field with a "
743  "generic boundary condition."
744  << abort(FatalError);
745 
746  return *this;
747 }
748 
749 template<class Type>
752 {
754  << "cannot be called for a genericFvPatchField"
755  " (actual type " << actualTypeName() << ")"
756  << "\n on patch " << this->patch().name()
757  << " of field " << this->internalField().name()
758  << " in file " << this->internalField().objectPath()
759  << "\n You are probably trying to solve for a field with a "
760  "generic boundary condition."
761  << abort(FatalError);
762 
763  return *this;
764 }
765 
766 
767 template<class Type>
769 {
770  writeEntry(os, "type", actualTypeName());
771 
772  forAllConstIter(dictionary, dict_, iter)
773  {
774  if (iter().keyword() != "type" && iter().keyword() != "value")
775  {
776  if
777  (
778  iter().isStream()
779  && iter().stream().size()
780  && iter().stream()[0].isWord()
781  && iter().stream()[0].wordToken() == "nonuniform"
782  )
783  {
784  if (scalarFields_.found(iter().keyword()))
785  {
786  writeEntry
787  (
788  os,
789  iter().keyword(),
790  *scalarFields_.find(iter().keyword())()
791  );
792  }
793  else if (vectorFields_.found(iter().keyword()))
794  {
795  writeEntry
796  (
797  os,
798  iter().keyword(),
799  *vectorFields_.find(iter().keyword())()
800  );
801  }
802  else if (sphericalTensorFields_.found(iter().keyword()))
803  {
804  writeEntry
805  (
806  os,
807  iter().keyword(),
808  *sphericalTensorFields_.find(iter().keyword())()
809  );
810  }
811  else if (symmTensorFields_.found(iter().keyword()))
812  {
813  writeEntry
814  (
815  os,
816  iter().keyword(),
817  *symmTensorFields_.find(iter().keyword())()
818  );
819  }
820  else if (tensorFields_.found(iter().keyword()))
821  {
822  writeEntry
823  (
824  os,
825  iter().keyword(),
826  *tensorFields_.find(iter().keyword())()
827  );
828  }
829  }
830  else
831  {
832  iter().write(os);
833  }
834  }
835  }
836 
837  writeEntry(os, "value", *this);
838 }
839 
840 
841 // ************************************************************************* //
bool isLabel() const
Definition: tokenI.H:392
tmp< Field< Type > > gradientInternalCoeffs() const
Return the matrix diagonal coefficients corresponding to the.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:667
bool isWord() const
Definition: tokenI.H:261
Field< sphericalTensor > sphericalTensorField
Specialisation of Field<T> for sphericalTensor.
compound & transferCompoundToken(const Istream &is)
Definition: token.C:93
Field< symmTensor > symmTensorField
Specialisation of Field<T> for symmTensor.
virtual void autoMap(const fvPatchFieldMapper &)
Map (and resize as needed) from self given a mapping object.
To & dynamicCast(From &r)
Reference type cast template function,.
Definition: typeInfo.H:85
An STL-conforming const_iterator.
Definition: HashTable.H:481
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
This boundary condition provides a generic version of the calculated condition, useful as a fallback ...
scalar number() const
Definition: tokenI.H:503
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
const word & wordToken() const
Definition: tokenI.H:266
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A token holds items read from Istream.
Definition: token.H:72
void putBack(const token &)
Put back token.
Definition: Istream.C:30
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:61
virtual void write(Ostream &) const
Write.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:66
volVectorField vectorField(fieldObject, mesh)
A HashTable specialization for hashing pointers.
Definition: HashPtrTable.H:50
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
bool isCompound() const
Definition: tokenI.H:520
Templated 3D SphericalTensor derived from VectorSpace adding construction from 1 component, element access using th ii() member function and the inner-product (dot-product) and outer-product operators.
A templated class for holding compound tokens.
Definition: token.H:209
virtual tmp< Field< Type > > valueBoundaryCoeffs(const tmp< scalarField > &) const
Return the matrix source coefficients corresponding to the.
Foam::fvPatchFieldMapper.
tmp< Field< Type > > gradientBoundaryCoeffs() const
Return the matrix source coefficients corresponding to the.
genericFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
This boundary condition is not designed to be evaluated; it is assumed that the value is assigned via...
const compound & compoundToken() const
Definition: tokenI.H:525
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
errorManip< error > abort(error &err)
Definition: errorManip.H:131
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
volScalarField scalarField(fieldObject, mesh)
static const char nl
Definition: Ostream.H:260
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
label labelToken() const
Definition: tokenI.H:397
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
virtual tmp< Field< Type > > valueInternalCoeffs(const tmp< scalarField > &) const
Return the matrix diagonal coefficients corresponding to the.
volScalarField & p
A class for managing temporary objects.
Definition: PtrList.H:53
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
bool isPunctuation() const
Definition: tokenI.H:243
Input token stream.
Definition: ITstream.H:49
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:812
IOerror FatalIOError