FreeFOAM The Cross-Platform CFD Toolkit
genericFvPatchField.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
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"
28 
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 
31 template<class Type>
33 (
34  const fvPatch& p,
36 )
37 :
39 {
41  (
42  "genericFvPatchField<Type>::genericFvPatchField"
43  "(const fvPatch& p, const DimensionedField<Type, volMesh>& iF)"
44  ) << "Not Implemented\n "
45  << "Trying to construct an genericFvPatchField on patch "
46  << this->patch().name()
47  << " of field " << this->dimensionedInternalField().name()
48  << abort(FatalError);
49 }
50 
51 
52 template<class Type>
54 (
55  const fvPatch& p,
57  const dictionary& dict
58 )
59 :
60  calculatedFvPatchField<Type>(p, iF, dict, false),
61  actualTypeName_(dict.lookup("type")),
62  dict_(dict)
63 {
64  if (!dict.found("value"))
65  {
67  (
68  "genericFvPatchField<Type>::genericFvPatchField"
69  "(const fvPatch&, const Field<Type>&, const dictionary&)",
70  dict
71  ) << "\n Cannot find 'value' entry"
72  << " on patch " << this->patch().name()
73  << " of field " << this->dimensionedInternalField().name()
74  << " in file " << this->dimensionedInternalField().objectPath()
75  << nl
76  << " which is required to set the"
77  " values of the generic patch field." << nl
78  << " (Actual type " << actualTypeName_ << ")" << nl
79  << "\n Please add the 'value' entry to the write function "
80  "of the user-defined boundary-condition\n"
81  " or link the boundary-condition into libfoamUtil.so"
82  << exit(FatalIOError);
83  }
84 
85  for
86  (
87  dictionary::const_iterator iter = dict_.begin();
88  iter != dict_.end();
89  ++iter
90  )
91  {
92  if (iter().keyword() != "type" && iter().keyword() != "value")
93  {
94  if
95  (
96  iter().isStream()
97  && iter().stream().size()
98  )
99  {
100  ITstream& is = iter().stream();
101 
102  // Read first token
103  token firstToken(is);
104 
105  if
106  (
107  firstToken.isWord()
108  && firstToken.wordToken() == "nonuniform"
109  )
110  {
111  token fieldToken(is);
112 
113  if (!fieldToken.isCompound())
114  {
115  if
116  (
117  fieldToken.isLabel()
118  && fieldToken.labelToken() == 0
119  )
120  {
121  scalarFields_.insert
122  (
123  iter().keyword(),
124  new scalarField(0)
125  );
126  }
127  else
128  {
130  (
131  "genericFvPatchField<Type>::genericFvPatchField"
132  "(const fvPatch&, const Field<Type>&, "
133  "const dictionary&)",
134  dict
135  ) << "\n token following 'nonuniform' "
136  "is not a compound"
137  << "\n on patch " << this->patch().name()
138  << " of field "
139  << this->dimensionedInternalField().name()
140  << " in file "
141  << this->dimensionedInternalField().objectPath()
142  << exit(FatalIOError);
143  }
144  }
145  else if
146  (
147  fieldToken.compoundToken().type()
148  == token::Compound<List<scalar> >::typeName
149  )
150  {
151  scalarField* fPtr = new scalarField;
152  fPtr->transfer
153  (
155  (
156  fieldToken.transferCompoundToken()
157  )
158  );
159 
160  if (fPtr->size() != this->size())
161  {
163  (
164  "genericFvPatchField<Type>::genericFvPatchField"
165  "(const fvPatch&, const Field<Type>&, "
166  "const dictionary&)",
167  dict
168  ) << "\n size of field " << iter().keyword()
169  << " (" << fPtr->size() << ')'
170  << " is not the same size as the patch ("
171  << this->size() << ')'
172  << "\n on patch " << this->patch().name()
173  << " of field "
174  << this->dimensionedInternalField().name()
175  << " in file "
176  << this->dimensionedInternalField().objectPath()
177  << exit(FatalIOError);
178  }
179 
180  scalarFields_.insert(iter().keyword(), fPtr);
181  }
182  else if
183  (
184  fieldToken.compoundToken().type()
185  == token::Compound<List<vector> >::typeName
186  )
187  {
188  vectorField* fPtr = new vectorField;
189  fPtr->transfer
190  (
192  (
193  fieldToken.transferCompoundToken()
194  )
195  );
196 
197  if (fPtr->size() != this->size())
198  {
200  (
201  "genericFvPatchField<Type>::genericFvPatchField"
202  "(const fvPatch&, const Field<Type>&, "
203  "const dictionary&)",
204  dict
205  ) << "\n size of field " << iter().keyword()
206  << " (" << fPtr->size() << ')'
207  << " is not the same size as the patch ("
208  << this->size() << ')'
209  << "\n on patch " << this->patch().name()
210  << " of field "
211  << this->dimensionedInternalField().name()
212  << " in file "
213  << this->dimensionedInternalField().objectPath()
214  << exit(FatalIOError);
215  }
216 
217  vectorFields_.insert(iter().keyword(), fPtr);
218  }
219  else if
220  (
221  fieldToken.compoundToken().type()
223  )
224  {
226  fPtr->transfer
227  (
229  <
231  >
232  (
233  fieldToken.transferCompoundToken()
234  )
235  );
236 
237  if (fPtr->size() != this->size())
238  {
240  (
241  "genericFvPatchField<Type>::genericFvPatchField"
242  "(const fvPatch&, const Field<Type>&, "
243  "const dictionary&)",
244  dict
245  ) << "\n size of field " << iter().keyword()
246  << " (" << fPtr->size() << ')'
247  << " is not the same size as the patch ("
248  << this->size() << ')'
249  << "\n on patch " << this->patch().name()
250  << " of field "
251  << this->dimensionedInternalField().name()
252  << " in file "
253  << this->dimensionedInternalField().objectPath()
254  << exit(FatalIOError);
255  }
256 
257  sphericalTensorFields_.insert(iter().keyword(), fPtr);
258  }
259  else if
260  (
261  fieldToken.compoundToken().type()
262  == token::Compound<List<symmTensor> >::typeName
263  )
264  {
265  symmTensorField* fPtr = new symmTensorField;
266  fPtr->transfer
267  (
269  <
271  >
272  (
273  fieldToken.transferCompoundToken()
274  )
275  );
276 
277  if (fPtr->size() != this->size())
278  {
280  (
281  "genericFvPatchField<Type>::genericFvPatchField"
282  "(const fvPatch&, const Field<Type>&, "
283  "const dictionary&)",
284  dict
285  ) << "\n size of field " << iter().keyword()
286  << " (" << fPtr->size() << ')'
287  << " is not the same size as the patch ("
288  << this->size() << ')'
289  << "\n on patch " << this->patch().name()
290  << " of field "
291  << this->dimensionedInternalField().name()
292  << " in file "
293  << this->dimensionedInternalField().objectPath()
294  << exit(FatalIOError);
295  }
296 
297  symmTensorFields_.insert(iter().keyword(), fPtr);
298  }
299  else if
300  (
301  fieldToken.compoundToken().type()
302  == token::Compound<List<tensor> >::typeName
303  )
304  {
305  tensorField* fPtr = new tensorField;
306  fPtr->transfer
307  (
309  (
310  fieldToken.transferCompoundToken()
311  )
312  );
313 
314  if (fPtr->size() != this->size())
315  {
317  (
318  "genericFvPatchField<Type>::genericFvPatchField"
319  "(const fvPatch&, const Field<Type>&, "
320  "const dictionary&)",
321  dict
322  ) << "\n size of field " << iter().keyword()
323  << " (" << fPtr->size() << ')'
324  << " is not the same size as the patch ("
325  << this->size() << ')'
326  << "\n on patch " << this->patch().name()
327  << " of field "
328  << this->dimensionedInternalField().name()
329  << " in file "
330  << this->dimensionedInternalField().objectPath()
331  << exit(FatalIOError);
332  }
333 
334  tensorFields_.insert(iter().keyword(), fPtr);
335  }
336  else
337  {
339  (
340  "genericFvPatchField<Type>::genericFvPatchField"
341  "(const fvPatch&, const Field<Type>&, "
342  "const dictionary&)",
343  dict
344  ) << "\n compound " << fieldToken.compoundToken()
345  << " not supported"
346  << "\n on patch " << this->patch().name()
347  << " of field "
348  << this->dimensionedInternalField().name()
349  << " in file "
350  << this->dimensionedInternalField().objectPath()
351  << exit(FatalIOError);
352  }
353  }
354  else if
355  (
356  firstToken.isWord()
357  && firstToken.wordToken() == "uniform"
358  )
359  {
360  token fieldToken(is);
361 
362  if (!fieldToken.isPunctuation())
363  {
364  scalarFields_.insert
365  (
366  iter().keyword(),
367  new scalarField
368  (
369  this->size(),
370  fieldToken.number()
371  )
372  );
373  }
374  else
375  {
376  // Read as scalarList.
377  is.putBack(fieldToken);
378 
379  scalarList l(is);
380 
381  if (l.size() == vector::nComponents)
382  {
383  vector vs(l[0], l[1], l[2]);
384 
385  vectorFields_.insert
386  (
387  iter().keyword(),
388  new vectorField(this->size(), vs)
389  );
390  }
391  else if (l.size() == sphericalTensor::nComponents)
392  {
393  sphericalTensor vs(l[0]);
394 
395  sphericalTensorFields_.insert
396  (
397  iter().keyword(),
398  new sphericalTensorField(this->size(), vs)
399  );
400  }
401  else if (l.size() == symmTensor::nComponents)
402  {
403  symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]);
404 
405  symmTensorFields_.insert
406  (
407  iter().keyword(),
408  new symmTensorField(this->size(), vs)
409  );
410  }
411  else if (l.size() == tensor::nComponents)
412  {
413  tensor vs
414  (
415  l[0], l[1], l[2],
416  l[3], l[4], l[5],
417  l[6], l[7], l[8]
418  );
419 
420  tensorFields_.insert
421  (
422  iter().keyword(),
423  new tensorField(this->size(), vs)
424  );
425  }
426  else
427  {
429  (
430  "genericFvPatchField<Type>::genericFvPatchField"
431  "(const fvPatch&, const Field<Type>&, "
432  "const dictionary&)",
433  dict
434  ) << "\n unrecognised native type " << l
435  << "\n on patch " << this->patch().name()
436  << " of field "
437  << this->dimensionedInternalField().name()
438  << " in file "
439  << this->dimensionedInternalField().objectPath()
440  << exit(FatalIOError);
441  }
442  }
443  }
444  }
445  }
446  }
447 }
448 
449 
450 template<class Type>
452 (
453  const genericFvPatchField<Type>& ptf,
454  const fvPatch& p,
456  const fvPatchFieldMapper& mapper
457 )
458 :
459  calculatedFvPatchField<Type>(ptf, p, iF, mapper),
460  actualTypeName_(ptf.actualTypeName_),
461  dict_(ptf.dict_)
462 {
463  for
464  (
466  ptf.scalarFields_.begin();
467  iter != ptf.scalarFields_.end();
468  ++iter
469  )
470  {
471  scalarFields_.insert(iter.key(), new scalarField(*iter(), mapper));
472  }
473 
474  for
475  (
477  ptf.vectorFields_.begin();
478  iter != ptf.vectorFields_.end();
479  ++iter
480  )
481  {
482  vectorFields_.insert(iter.key(), new vectorField(*iter(), mapper));
483  }
484 
485  for
486  (
488  ptf.sphericalTensorFields_.begin();
489  iter != ptf.sphericalTensorFields_.end();
490  ++iter
491  )
492  {
493  sphericalTensorFields_.insert
494  (
495  iter.key(),
496  new sphericalTensorField(*iter(), mapper)
497  );
498  }
499 
500  for
501  (
503  ptf.symmTensorFields_.begin();
504  iter != ptf.symmTensorFields_.end();
505  ++iter
506  )
507  {
508  symmTensorFields_.insert
509  (
510  iter.key(),
511  new symmTensorField(*iter(), mapper)
512  );
513  }
514 
515  for
516  (
518  ptf.tensorFields_.begin();
519  iter != ptf.tensorFields_.end();
520  ++iter
521  )
522  {
523  tensorFields_.insert(iter.key(), new tensorField(*iter(), mapper));
524  }
525 }
526 
527 
528 template<class Type>
530 (
531  const genericFvPatchField<Type>& ptf
532 )
533 :
535  actualTypeName_(ptf.actualTypeName_),
536  dict_(ptf.dict_),
537  scalarFields_(ptf.scalarFields_),
538  vectorFields_(ptf.vectorFields_),
539  sphericalTensorFields_(ptf.sphericalTensorFields_),
540  symmTensorFields_(ptf.symmTensorFields_),
541  tensorFields_(ptf.tensorFields_)
542 {}
543 
544 
545 template<class Type>
547 (
548  const genericFvPatchField<Type>& ptf,
550 )
551 :
553  actualTypeName_(ptf.actualTypeName_),
554  dict_(ptf.dict_),
555  scalarFields_(ptf.scalarFields_),
556  vectorFields_(ptf.vectorFields_),
557  sphericalTensorFields_(ptf.sphericalTensorFields_),
558  symmTensorFields_(ptf.symmTensorFields_),
559  tensorFields_(ptf.tensorFields_)
560 {}
561 
562 
563 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
564 
565 template<class Type>
567 (
568  const fvPatchFieldMapper& m
569 )
570 {
572 
573  for
574  (
575  HashPtrTable<scalarField>::iterator iter = scalarFields_.begin();
576  iter != scalarFields_.end();
577  ++iter
578  )
579  {
580  iter()->autoMap(m);
581  }
582 
583  for
584  (
585  HashPtrTable<vectorField>::iterator iter = vectorFields_.begin();
586  iter != vectorFields_.end();
587  ++iter
588  )
589  {
590  iter()->autoMap(m);
591  }
592 
593  for
594  (
596  sphericalTensorFields_.begin();
597  iter != sphericalTensorFields_.end();
598  ++iter
599  )
600  {
601  iter()->autoMap(m);
602  }
603 
604  for
605  (
607  symmTensorFields_.begin();
608  iter != symmTensorFields_.end();
609  ++iter
610  )
611  {
612  iter()->autoMap(m);
613  }
614 
615  for
616  (
617  HashPtrTable<tensorField>::iterator iter = tensorFields_.begin();
618  iter != tensorFields_.end();
619  ++iter
620  )
621  {
622  iter()->autoMap(m);
623  }
624 }
625 
626 
627 template<class Type>
629 (
630  const fvPatchField<Type>& ptf,
631  const labelList& addr
632 )
633 {
635 
636  const genericFvPatchField<Type>& dptf =
637  refCast<const genericFvPatchField<Type> >(ptf);
638 
639  for
640  (
641  HashPtrTable<scalarField>::iterator iter = scalarFields_.begin();
642  iter != scalarFields_.end();
643  ++iter
644  )
645  {
647  dptf.scalarFields_.find(iter.key());
648 
649  if (dptfIter != dptf.scalarFields_.end())
650  {
651  iter()->rmap(*dptfIter(), addr);
652  }
653  }
654 
655  for
656  (
657  HashPtrTable<vectorField>::iterator iter = vectorFields_.begin();
658  iter != vectorFields_.end();
659  ++iter
660  )
661  {
663  dptf.vectorFields_.find(iter.key());
664 
665  if (dptfIter != dptf.vectorFields_.end())
666  {
667  iter()->rmap(*dptfIter(), addr);
668  }
669  }
670 
671  for
672  (
674  sphericalTensorFields_.begin();
675  iter != sphericalTensorFields_.end();
676  ++iter
677  )
678  {
680  dptf.sphericalTensorFields_.find(iter.key());
681 
682  if (dptfIter != dptf.sphericalTensorFields_.end())
683  {
684  iter()->rmap(*dptfIter(), addr);
685  }
686  }
687 
688  for
689  (
691  symmTensorFields_.begin();
692  iter != symmTensorFields_.end();
693  ++iter
694  )
695  {
697  dptf.symmTensorFields_.find(iter.key());
698 
699  if (dptfIter != dptf.symmTensorFields_.end())
700  {
701  iter()->rmap(*dptfIter(), addr);
702  }
703  }
704 
705  for
706  (
707  HashPtrTable<tensorField>::iterator iter = tensorFields_.begin();
708  iter != tensorFields_.end();
709  ++iter
710  )
711  {
713  dptf.tensorFields_.find(iter.key());
714 
715  if (dptfIter != dptf.tensorFields_.end())
716  {
717  iter()->rmap(*dptfIter(), addr);
718  }
719  }
720 }
721 
722 
723 template<class Type>
726 (
727  const tmp<scalarField>&
728 ) const
729 {
731  (
732  "genericFvPatchField<Type>::"
733  "valueInternalCoeffs(const tmp<scalarField>&) const"
734  ) << "\n "
735  "valueInternalCoeffs cannot be called for a genericFvPatchField"
736  " (actual type " << actualTypeName_ << ")"
737  << "\n on patch " << this->patch().name()
738  << " of field " << this->dimensionedInternalField().name()
739  << " in file " << this->dimensionedInternalField().objectPath()
740  << "\n You are probably trying to solve for a field with a "
741  "generic boundary condition."
742  << exit(FatalError);
743 
744  return *this;
745 }
746 
747 
748 template<class Type>
751 (
752  const tmp<scalarField>&
753 ) const
754 {
756  (
757  "genericFvPatchField<Type>::"
758  "valueBoundaryCoeffs(const tmp<scalarField>&) const"
759  ) << "\n "
760  "valueBoundaryCoeffs cannot be called for a genericFvPatchField"
761  " (actual type " << actualTypeName_ << ")"
762  << "\n on patch " << this->patch().name()
763  << " of field " << this->dimensionedInternalField().name()
764  << " in file " << this->dimensionedInternalField().objectPath()
765  << "\n You are probably trying to solve for a field with a "
766  "generic boundary condition."
767  << exit(FatalError);
768 
769  return *this;
770 }
771 
772 
773 template<class Type>
776 {
778  (
779  "genericFvPatchField<Type>::"
780  "gradientInternalCoeffs() const"
781  ) << "\n "
782  "gradientInternalCoeffs cannot be called for a genericFvPatchField"
783  " (actual type " << actualTypeName_ << ")"
784  << "\n on patch " << this->patch().name()
785  << " of field " << this->dimensionedInternalField().name()
786  << " in file " << this->dimensionedInternalField().objectPath()
787  << "\n You are probably trying to solve for a field with a "
788  "generic boundary condition."
789  << exit(FatalError);
790 
791  return *this;
792 }
793 
794 template<class Type>
797 {
799  (
800  "genericFvPatchField<Type>::"
801  "gradientBoundaryCoeffs() const"
802  ) << "\n "
803  "gradientBoundaryCoeffs cannot be called for a genericFvPatchField"
804  " (actual type " << actualTypeName_ << ")"
805  << "\n on patch " << this->patch().name()
806  << " of field " << this->dimensionedInternalField().name()
807  << " in file " << this->dimensionedInternalField().objectPath()
808  << "\n You are probably trying to solve for a field with a "
809  "generic boundary condition."
810  << exit(FatalError);
811 
812  return *this;
813 }
814 
815 
816 template<class Type>
818 {
819  os.writeKeyword("type") << actualTypeName_ << token::END_STATEMENT << nl;
820 
821  for
822  (
823  dictionary::const_iterator iter = dict_.begin();
824  iter != dict_.end();
825  ++iter
826  )
827  {
828  if (iter().keyword() != "type" && iter().keyword() != "value")
829  {
830  if
831  (
832  iter().isStream()
833  && iter().stream().size()
834  && iter().stream()[0].isWord()
835  && iter().stream()[0].wordToken() == "nonuniform"
836  )
837  {
838  if (scalarFields_.found(iter().keyword()))
839  {
840  scalarFields_.find(iter().keyword())()
841  ->writeEntry(iter().keyword(), os);
842  }
843  else if (vectorFields_.found(iter().keyword()))
844  {
845  vectorFields_.find(iter().keyword())()
846  ->writeEntry(iter().keyword(), os);
847  }
848  else if (sphericalTensorFields_.found(iter().keyword()))
849  {
850  sphericalTensorFields_.find(iter().keyword())()
851  ->writeEntry(iter().keyword(), os);
852  }
853  else if (symmTensorFields_.found(iter().keyword()))
854  {
855  symmTensorFields_.find(iter().keyword())()
856  ->writeEntry(iter().keyword(), os);
857  }
858  else if (tensorFields_.found(iter().keyword()))
859  {
860  tensorFields_.find(iter().keyword())()
861  ->writeEntry(iter().keyword(), os);
862  }
863  }
864  else
865  {
866  iter().write(os);
867  }
868  }
869  }
870 
871  this->writeEntry("value", os);
872 }
873 
874 
875 // ************************ vim: set sw=4 sts=4 et: ************************ //