FreeFOAM The Cross-Platform CFD Toolkit
Field.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 "FieldMapper.H"
27 #include "FieldM.H"
28 #include <OpenFOAM/dictionary.H>
29 #include <OpenFOAM/contiguous.H>
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
37 
38 template<class Type>
39 const char* const Field<Type>::typeName("Field");
40 
41 
42 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
43 
44 template<class Type>
46 :
47  List<Type>()
48 {}
49 
50 
51 template<class Type>
52 Field<Type>::Field(const label size)
53 :
54  List<Type>(size)
55 {}
56 
57 
58 template<class Type>
59 Field<Type>::Field(const label size, const Type& t)
60 :
61  List<Type>(size, t)
62 {}
63 
64 
65 template<class Type>
67 (
68  const UList<Type>& mapF,
69  const unallocLabelList& mapAddressing
70 )
71 :
72  List<Type>(mapAddressing.size())
73 {
74  map(mapF, mapAddressing);
75 }
76 
77 template<class Type>
79 (
80  const tmp<Field<Type> >& tmapF,
81  const unallocLabelList& mapAddressing
82 )
83 :
84  List<Type>(mapAddressing.size())
85 {
86  map(tmapF, mapAddressing);
87 }
88 
89 
90 template<class Type>
92 (
93  const UList<Type>& mapF,
94  const labelListList& mapAddressing,
95  const scalarListList& mapWeights
96 )
97 :
98  List<Type>(mapAddressing.size())
99 {
100  map(mapF, mapAddressing, mapWeights);
101 }
102 
103 template<class Type>
105 (
106  const tmp<Field<Type> >& tmapF,
107  const labelListList& mapAddressing,
108  const scalarListList& mapWeights
109 )
110 :
111  List<Type>(mapAddressing.size())
112 {
113  map(tmapF, mapAddressing, mapWeights);
114 }
115 
116 
117 template<class Type>
119 (
120  const UList<Type>& mapF,
121  const FieldMapper& mapper
122 )
123 :
124  List<Type>(mapper.size())
125 {
126  map(mapF, mapper);
127 }
128 
129 template<class Type>
131 (
132  const tmp<Field<Type> >& tmapF,
133  const FieldMapper& mapper
134 )
135 :
136  List<Type>(mapper.size())
137 {
138  map(tmapF, mapper);
139 }
140 
141 
142 template<class Type>
144 :
145  refCount(),
146  List<Type>(f)
147 {}
148 
149 
150 template<class Type>
152 :
153  List<Type>(f, reUse)
154 {}
155 
156 
157 template<class Type>
159 :
160  List<Type>(f)
161 {}
162 
163 
164 template<class Type>
166 :
167  List<Type>(f)
168 {}
169 
170 
171 template<class Type>
173 :
174  List<Type>(sf)
175 {}
176 
177 
178 template<class Type>
180 :
181  List<Type>(list)
182 {}
183 
184 
185 // Construct as copy of tmp<Field>
186 #ifdef ConstructFromTmp
187 template<class Type>
189 :
190  List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
191 {
192  const_cast<Field<Type>&>(tf()).resetRefCount();
193 }
194 #endif
195 
196 
197 template<class Type>
199 :
200  List<Type>(is)
201 {}
202 
203 
204 template<class Type>
206 (
207  const word& keyword,
208  const dictionary& dict,
209  const label s
210 )
211 {
212  if (s)
213  {
214  ITstream& is = dict.lookup(keyword);
215 
216  // Read first token
217  token firstToken(is);
218 
219  if (firstToken.isWord())
220  {
221  if (firstToken.wordToken() == "uniform")
222  {
223  this->setSize(s);
224  operator=(pTraits<Type>(is));
225  }
226  else if (firstToken.wordToken() == "nonuniform")
227  {
228  is >> static_cast<List<Type>&>(*this);
229  if (this->size() != s)
230  {
232  (
233  "Field<Type>::Field"
234  "(const word& keyword, const dictionary&, const label)",
235  dict
236  ) << "size " << this->size()
237  << " is not equal to the given value of " << s
238  << exit(FatalIOError);
239  }
240  }
241  else
242  {
244  (
245  "Field<Type>::Field"
246  "(const word& keyword, const dictionary&, const label)",
247  dict
248  ) << "expected keyword 'uniform' or 'nonuniform', found "
249  << firstToken.wordToken()
250  << exit(FatalIOError);
251  }
252  }
253  else
254  {
255  if (is.version() == 2.0)
256  {
258  (
259  "Field<Type>::Field"
260  "(const word& keyword, const dictionary&, const label)",
261  dict
262  ) << "expected keyword 'uniform' or 'nonuniform', "
263  "assuming deprecated Field format from "
264  "Foam version 2.0." << endl;
265 
266  this->setSize(s);
267 
268  is.putBack(firstToken);
269  operator=(pTraits<Type>(is));
270  }
271  else
272  {
274  (
275  "Field<Type>::Field"
276  "(const word& keyword, const dictionary&, const label)",
277  dict
278  ) << "expected keyword 'uniform' or 'nonuniform', found "
279  << firstToken.info()
280  << exit(FatalIOError);
281  }
282  }
283  }
284 }
285 
286 
287 template<class Type>
289 {
290  return tmp<Field<Type> >(new Field<Type>(*this));
291 }
292 
293 
294 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
295 
296 template<class Type>
297 void Field<Type>::map
298 (
299  const UList<Type>& mapF,
300  const unallocLabelList& mapAddressing
301 )
302 {
303  Field<Type>& f = *this;
304 
305  if (f.size() != mapAddressing.size())
306  {
307  f.setSize(mapAddressing.size());
308  }
309 
310  if (mapF.size() > 0)
311  {
312  forAll(f, i)
313  {
314  label mapI = mapAddressing[i];
315 
316  if (mapI >= 0)
317  {
318  f[i] = mapF[mapI];
319  }
320  }
321  }
322 }
323 
324 
325 template<class Type>
326 void Field<Type>::map
327 (
328  const tmp<Field<Type> >& tmapF,
329  const unallocLabelList& mapAddressing
330 )
331 {
332  map(tmapF(), mapAddressing);
333  tmapF.clear();
334 }
335 
336 
337 template<class Type>
338 void Field<Type>::map
339 (
340  const UList<Type>& mapF,
341  const labelListList& mapAddressing,
342  const scalarListList& mapWeights
343 )
344 {
345  Field<Type>& f = *this;
346 
347  if (f.size() != mapAddressing.size())
348  {
349  f.setSize(mapAddressing.size());
350  }
351 
352  if (mapWeights.size() != mapAddressing.size())
353  {
355  (
356  "void Field<Type>::map\n"
357  "(\n"
358  " const UList<Type>& mapF,\n"
359  " const labelListList& mapAddressing,\n"
360  " const scalarListList& mapWeights\n"
361  ")"
362  ) << "Weights and addressing map have different sizes. Weights size: "
363  << mapWeights.size() << " map size: " << mapAddressing.size()
364  << abort(FatalError);
365  }
366 
367  forAll(f, i)
368  {
369  const labelList& localAddrs = mapAddressing[i];
370  const scalarList& localWeights = mapWeights[i];
371 
372  f[i] = pTraits<Type>::zero;
373 
374  forAll(localAddrs, j)
375  {
376  f[i] += localWeights[j]*mapF[localAddrs[j]];
377  }
378  }
379 }
380 
381 template<class Type>
382 void Field<Type>::map
383 (
384  const tmp<Field<Type> >& tmapF,
385  const labelListList& mapAddressing,
386  const scalarListList& mapWeights
387 )
388 {
389  map(tmapF(), mapAddressing, mapWeights);
390  tmapF.clear();
391 }
392 
393 
394 template<class Type>
395 void Field<Type>::map
396 (
397  const UList<Type>& mapF,
398  const FieldMapper& mapper
399 )
400 {
401  if
402  (
403  mapper.direct()
404  && &mapper.directAddressing()
405  && mapper.directAddressing().size()
406  )
407  {
408  map(mapF, mapper.directAddressing());
409  }
410  else if (!mapper.direct() && mapper.addressing().size())
411  {
412  map(mapF, mapper.addressing(), mapper.weights());
413  }
414 }
415 
416 template<class Type>
417 void Field<Type>::map
418 (
419  const tmp<Field<Type> >& tmapF,
420  const FieldMapper& mapper
421 )
422 {
423  map(tmapF(), mapper);
424  tmapF.clear();
425 }
426 
427 
428 template<class Type>
430 (
431  const FieldMapper& mapper
432 )
433 {
434  if
435  (
436  (
437  mapper.direct()
438  && &mapper.directAddressing()
439  && mapper.directAddressing().size()
440  )
441  || (!mapper.direct() && mapper.addressing().size())
442  )
443  {
444  Field<Type> fCpy(*this);
445  map(fCpy, mapper);
446  }
447  else
448  {
449  this->setSize(mapper.size());
450  }
451 }
452 
453 
454 template<class Type>
456 (
457  const UList<Type>& mapF,
458  const unallocLabelList& mapAddressing
459 )
460 {
461  Field<Type>& f = *this;
462 
463  forAll(mapF, i)
464  {
465  label mapI = mapAddressing[i];
466 
467  if (mapI >= 0)
468  {
469  f[mapI] = mapF[i];
470  }
471  }
472 }
473 
474 template<class Type>
476 (
477  const tmp<Field<Type> >& tmapF,
478  const unallocLabelList& mapAddressing
479 )
480 {
481  rmap(tmapF(), mapAddressing);
482  tmapF.clear();
483 }
484 
485 
486 template<class Type>
488 (
489  const UList<Type>& mapF,
490  const unallocLabelList& mapAddressing,
491  const scalarList& mapWeights
492 )
493 {
494  Field<Type>& f = *this;
495 
497 
498  forAll(mapF, i)
499  {
500  f[mapAddressing[i]] += mapF[i]*mapWeights[i];
501  }
502 }
503 
504 template<class Type>
506 (
507  const tmp<Field<Type> >& tmapF,
508  const unallocLabelList& mapAddressing,
509  const scalarList& mapWeights
510 )
511 {
512  rmap(tmapF(), mapAddressing, mapWeights);
513  tmapF.clear();
514 }
515 
516 
517 template<class Type>
519 {
520  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
521 }
522 
523 
524 template<class Type>
526 (
527  const direction d
528 ) const
529 {
530  tmp<Field<cmptType> > Component(new Field<cmptType>(this->size()));
531  ::Foam::component(Component(), *this, d);
532  return Component;
533 }
534 
535 
536 template<class Type>
538 (
539  const direction d,
540  const UList<cmptType>& sf
541 )
542 {
543  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
544  cmptType, sf)
545 }
546 
547 
548 template<class Type>
550 (
551  const direction d,
552  const tmp<Field<cmptType> >& tsf
553 )
554 {
555  replace(d, tsf());
556  tsf.clear();
557 }
558 
559 
560 template<class Type>
562 (
563  const direction d,
564  const cmptType& c
565 )
566 {
567  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
568  cmptType, c)
569 }
570 
571 
572 template<class Type>
574 {
575  tmp<Field<Type> > transpose(new Field<Type>(this->size()));
576  ::Foam::T(transpose(), *this);
577  return transpose;
578 }
579 
580 
581 template<class Type>
582 void Field<Type>::writeEntry(const word& keyword, Ostream& os) const
583 {
584  os.writeKeyword(keyword);
585 
586  bool uniform = false;
587 
588  if (this->size() && contiguous<Type>())
589  {
590  uniform = true;
591 
592  forAll(*this, i)
593  {
594  if (this->operator[](i) != this->operator[](0))
595  {
596  uniform = false;
597  break;
598  }
599  }
600  }
601 
602  if (uniform)
603  {
604  os << "uniform " << this->operator[](0) << token::END_STATEMENT;
605  }
606  else
607  {
608  os << "nonuniform ";
610  os << token::END_STATEMENT;
611  }
612 
613  os << endl;
614 }
615 
616 
617 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
618 
619 template<class Type>
621 {
622  if (this == &rhs)
623  {
624  FatalErrorIn("Field<Type>::operator=(const Field<Type>&)")
625  << "attempted assignment to self"
626  << abort(FatalError);
627  }
628 
630 }
631 
632 
633 template<class Type>
635 {
637 }
638 
639 
640 template<class Type>
642 {
644 }
645 
646 
647 template<class Type>
649 {
650  if (this == &(rhs()))
651  {
652  FatalErrorIn("Field<Type>::operator=(const tmp<Field>&)")
653  << "attempted assignment to self"
654  << abort(FatalError);
655  }
656 
657  // This is dodgy stuff, don't try it at home.
658  Field* fieldPtr = rhs.ptr();
659  List<Type>::transfer(*fieldPtr);
660  delete fieldPtr;
661 }
662 
663 
664 template<class Type>
665 void Field<Type>::operator=(const Type& t)
666 {
668 }
669 
670 
671 template<class Type>
672 template<class Form, class Cmpt, int nCmpt>
674 {
675  typedef VectorSpace<Form,Cmpt,nCmpt> VSType;
676  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
677 }
678 
679 
680 #define COMPUTED_ASSIGNMENT(TYPE, op) \
681  \
682 template<class Type> \
683 void Field<Type>::operator op(const UList<TYPE>& f) \
684 { \
685  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
686 } \
687  \
688 template<class Type> \
689 void Field<Type>::operator op(const tmp<Field<TYPE> >& tf) \
690 { \
691  operator op(tf()); \
692  tf.clear(); \
693 } \
694  \
695 template<class Type> \
696 void Field<Type>::operator op(const TYPE& t) \
697 { \
698  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
699 }
700 
705 
706 #undef COMPUTED_ASSIGNMENT
707 
708 
709 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
710 
711 template<class Type>
712 Ostream& operator<<(Ostream& os, const Field<Type>& f)
713 {
714  os << static_cast<const List<Type>&>(f);
715  return os;
716 }
717 
718 
719 template<class Type>
720 Ostream& operator<<(Ostream& os, const tmp<Field<Type> >& tf)
721 {
722  os << tf();
723  tf.clear();
724  return os;
725 }
726 
727 
728 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
729 
730 } // End namespace Foam
731 
732 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
733 
734 # include "FieldFunctions.C"
735 
736 // ************************ vim: set sw=4 sts=4 et: ************************ //