00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "FieldMapper.H"
00027 #include "FieldM.H"
00028 #include <OpenFOAM/dictionary.H>
00029 #include <OpenFOAM/contiguous.H>
00030
00031
00032
00033 namespace Foam
00034 {
00035
00036
00037
00038 template<class Type>
00039 const char* const Field<Type>::typeName("Field");
00040
00041
00042
00043
00044 template<class Type>
00045 Field<Type>::Field()
00046 :
00047 List<Type>()
00048 {}
00049
00050
00051 template<class Type>
00052 Field<Type>::Field(const label size)
00053 :
00054 List<Type>(size)
00055 {}
00056
00057
00058 template<class Type>
00059 Field<Type>::Field(const label size, const Type& t)
00060 :
00061 List<Type>(size, t)
00062 {}
00063
00064
00065 template<class Type>
00066 Field<Type>::Field
00067 (
00068 const UList<Type>& mapF,
00069 const unallocLabelList& mapAddressing
00070 )
00071 :
00072 List<Type>(mapAddressing.size())
00073 {
00074 map(mapF, mapAddressing);
00075 }
00076
00077 template<class Type>
00078 Field<Type>::Field
00079 (
00080 const tmp<Field<Type> >& tmapF,
00081 const unallocLabelList& mapAddressing
00082 )
00083 :
00084 List<Type>(mapAddressing.size())
00085 {
00086 map(tmapF, mapAddressing);
00087 }
00088
00089
00090 template<class Type>
00091 Field<Type>::Field
00092 (
00093 const UList<Type>& mapF,
00094 const labelListList& mapAddressing,
00095 const scalarListList& mapWeights
00096 )
00097 :
00098 List<Type>(mapAddressing.size())
00099 {
00100 map(mapF, mapAddressing, mapWeights);
00101 }
00102
00103 template<class Type>
00104 Field<Type>::Field
00105 (
00106 const tmp<Field<Type> >& tmapF,
00107 const labelListList& mapAddressing,
00108 const scalarListList& mapWeights
00109 )
00110 :
00111 List<Type>(mapAddressing.size())
00112 {
00113 map(tmapF, mapAddressing, mapWeights);
00114 }
00115
00116
00117 template<class Type>
00118 Field<Type>::Field
00119 (
00120 const UList<Type>& mapF,
00121 const FieldMapper& mapper
00122 )
00123 :
00124 List<Type>(mapper.size())
00125 {
00126 map(mapF, mapper);
00127 }
00128
00129 template<class Type>
00130 Field<Type>::Field
00131 (
00132 const tmp<Field<Type> >& tmapF,
00133 const FieldMapper& mapper
00134 )
00135 :
00136 List<Type>(mapper.size())
00137 {
00138 map(tmapF, mapper);
00139 }
00140
00141
00142 template<class Type>
00143 Field<Type>::Field(const Field<Type>& f)
00144 :
00145 refCount(),
00146 List<Type>(f)
00147 {}
00148
00149
00150 template<class Type>
00151 Field<Type>::Field(Field<Type>& f, bool reUse)
00152 :
00153 List<Type>(f, reUse)
00154 {}
00155
00156
00157 template<class Type>
00158 Field<Type>::Field(const Xfer<List<Type> >& f)
00159 :
00160 List<Type>(f)
00161 {}
00162
00163
00164 template<class Type>
00165 Field<Type>::Field(const Xfer<Field<Type> >& f)
00166 :
00167 List<Type>(f)
00168 {}
00169
00170
00171 template<class Type>
00172 Field<Type>::Field(const typename Field<Type>::subField& sf)
00173 :
00174 List<Type>(sf)
00175 {}
00176
00177
00178 template<class Type>
00179 Field<Type>::Field(const UList<Type>& list)
00180 :
00181 List<Type>(list)
00182 {}
00183
00184
00185
00186 #ifdef ConstructFromTmp
00187 template<class Type>
00188 Field<Type>::Field(const tmp<Field<Type> >& tf)
00189 :
00190 List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
00191 {
00192 const_cast<Field<Type>&>(tf()).resetRefCount();
00193 }
00194 #endif
00195
00196
00197 template<class Type>
00198 Field<Type>::Field(Istream& is)
00199 :
00200 List<Type>(is)
00201 {}
00202
00203
00204 template<class Type>
00205 Field<Type>::Field
00206 (
00207 const word& keyword,
00208 const dictionary& dict,
00209 const label s
00210 )
00211 {
00212 if (s)
00213 {
00214 ITstream& is = dict.lookup(keyword);
00215
00216
00217 token firstToken(is);
00218
00219 if (firstToken.isWord())
00220 {
00221 if (firstToken.wordToken() == "uniform")
00222 {
00223 this->setSize(s);
00224 operator=(pTraits<Type>(is));
00225 }
00226 else if (firstToken.wordToken() == "nonuniform")
00227 {
00228 is >> static_cast<List<Type>&>(*this);
00229 if (this->size() != s)
00230 {
00231 FatalIOErrorIn
00232 (
00233 "Field<Type>::Field"
00234 "(const word& keyword, const dictionary&, const label)",
00235 dict
00236 ) << "size " << this->size()
00237 << " is not equal to the given value of " << s
00238 << exit(FatalIOError);
00239 }
00240 }
00241 else
00242 {
00243 FatalIOErrorIn
00244 (
00245 "Field<Type>::Field"
00246 "(const word& keyword, const dictionary&, const label)",
00247 dict
00248 ) << "expected keyword 'uniform' or 'nonuniform', found "
00249 << firstToken.wordToken()
00250 << exit(FatalIOError);
00251 }
00252 }
00253 else
00254 {
00255 if (is.version() == 2.0)
00256 {
00257 IOWarningIn
00258 (
00259 "Field<Type>::Field"
00260 "(const word& keyword, const dictionary&, const label)",
00261 dict
00262 ) << "expected keyword 'uniform' or 'nonuniform', "
00263 "assuming deprecated Field format from "
00264 "Foam version 2.0." << endl;
00265
00266 this->setSize(s);
00267
00268 is.putBack(firstToken);
00269 operator=(pTraits<Type>(is));
00270 }
00271 else
00272 {
00273 FatalIOErrorIn
00274 (
00275 "Field<Type>::Field"
00276 "(const word& keyword, const dictionary&, const label)",
00277 dict
00278 ) << "expected keyword 'uniform' or 'nonuniform', found "
00279 << firstToken.info()
00280 << exit(FatalIOError);
00281 }
00282 }
00283 }
00284 }
00285
00286
00287 template<class Type>
00288 tmp<Field<Type> > Field<Type>::clone() const
00289 {
00290 return tmp<Field<Type> >(new Field<Type>(*this));
00291 }
00292
00293
00294
00295
00296 template<class Type>
00297 void Field<Type>::map
00298 (
00299 const UList<Type>& mapF,
00300 const unallocLabelList& mapAddressing
00301 )
00302 {
00303 Field<Type>& f = *this;
00304
00305 if (f.size() != mapAddressing.size())
00306 {
00307 f.setSize(mapAddressing.size());
00308 }
00309
00310 if (mapF.size() > 0)
00311 {
00312 forAll(f, i)
00313 {
00314 label mapI = mapAddressing[i];
00315
00316 if (mapI >= 0)
00317 {
00318 f[i] = mapF[mapI];
00319 }
00320 }
00321 }
00322 }
00323
00324
00325 template<class Type>
00326 void Field<Type>::map
00327 (
00328 const tmp<Field<Type> >& tmapF,
00329 const unallocLabelList& mapAddressing
00330 )
00331 {
00332 map(tmapF(), mapAddressing);
00333 tmapF.clear();
00334 }
00335
00336
00337 template<class Type>
00338 void Field<Type>::map
00339 (
00340 const UList<Type>& mapF,
00341 const labelListList& mapAddressing,
00342 const scalarListList& mapWeights
00343 )
00344 {
00345 Field<Type>& f = *this;
00346
00347 if (f.size() != mapAddressing.size())
00348 {
00349 f.setSize(mapAddressing.size());
00350 }
00351
00352 if (mapWeights.size() != mapAddressing.size())
00353 {
00354 FatalErrorIn
00355 (
00356 "void Field<Type>::map\n"
00357 "(\n"
00358 " const UList<Type>& mapF,\n"
00359 " const labelListList& mapAddressing,\n"
00360 " const scalarListList& mapWeights\n"
00361 ")"
00362 ) << "Weights and addressing map have different sizes. Weights size: "
00363 << mapWeights.size() << " map size: " << mapAddressing.size()
00364 << abort(FatalError);
00365 }
00366
00367 forAll(f, i)
00368 {
00369 const labelList& localAddrs = mapAddressing[i];
00370 const scalarList& localWeights = mapWeights[i];
00371
00372 f[i] = pTraits<Type>::zero;
00373
00374 forAll(localAddrs, j)
00375 {
00376 f[i] += localWeights[j]*mapF[localAddrs[j]];
00377 }
00378 }
00379 }
00380
00381 template<class Type>
00382 void Field<Type>::map
00383 (
00384 const tmp<Field<Type> >& tmapF,
00385 const labelListList& mapAddressing,
00386 const scalarListList& mapWeights
00387 )
00388 {
00389 map(tmapF(), mapAddressing, mapWeights);
00390 tmapF.clear();
00391 }
00392
00393
00394 template<class Type>
00395 void Field<Type>::map
00396 (
00397 const UList<Type>& mapF,
00398 const FieldMapper& mapper
00399 )
00400 {
00401 if
00402 (
00403 mapper.direct()
00404 && &mapper.directAddressing()
00405 && mapper.directAddressing().size()
00406 )
00407 {
00408 map(mapF, mapper.directAddressing());
00409 }
00410 else if (!mapper.direct() && mapper.addressing().size())
00411 {
00412 map(mapF, mapper.addressing(), mapper.weights());
00413 }
00414 }
00415
00416 template<class Type>
00417 void Field<Type>::map
00418 (
00419 const tmp<Field<Type> >& tmapF,
00420 const FieldMapper& mapper
00421 )
00422 {
00423 map(tmapF(), mapper);
00424 tmapF.clear();
00425 }
00426
00427
00428 template<class Type>
00429 void Field<Type>::autoMap
00430 (
00431 const FieldMapper& mapper
00432 )
00433 {
00434 if
00435 (
00436 (
00437 mapper.direct()
00438 && &mapper.directAddressing()
00439 && mapper.directAddressing().size()
00440 )
00441 || (!mapper.direct() && mapper.addressing().size())
00442 )
00443 {
00444 Field<Type> fCpy(*this);
00445 map(fCpy, mapper);
00446 }
00447 else
00448 {
00449 this->setSize(mapper.size());
00450 }
00451 }
00452
00453
00454 template<class Type>
00455 void Field<Type>::rmap
00456 (
00457 const UList<Type>& mapF,
00458 const unallocLabelList& mapAddressing
00459 )
00460 {
00461 Field<Type>& f = *this;
00462
00463 forAll(mapF, i)
00464 {
00465 label mapI = mapAddressing[i];
00466
00467 if (mapI >= 0)
00468 {
00469 f[mapI] = mapF[i];
00470 }
00471 }
00472 }
00473
00474 template<class Type>
00475 void Field<Type>::rmap
00476 (
00477 const tmp<Field<Type> >& tmapF,
00478 const unallocLabelList& mapAddressing
00479 )
00480 {
00481 rmap(tmapF(), mapAddressing);
00482 tmapF.clear();
00483 }
00484
00485
00486 template<class Type>
00487 void Field<Type>::rmap
00488 (
00489 const UList<Type>& mapF,
00490 const unallocLabelList& mapAddressing,
00491 const scalarList& mapWeights
00492 )
00493 {
00494 Field<Type>& f = *this;
00495
00496 f = pTraits<Type>::zero;
00497
00498 forAll(mapF, i)
00499 {
00500 f[mapAddressing[i]] += mapF[i]*mapWeights[i];
00501 }
00502 }
00503
00504 template<class Type>
00505 void Field<Type>::rmap
00506 (
00507 const tmp<Field<Type> >& tmapF,
00508 const unallocLabelList& mapAddressing,
00509 const scalarList& mapWeights
00510 )
00511 {
00512 rmap(tmapF(), mapAddressing, mapWeights);
00513 tmapF.clear();
00514 }
00515
00516
00517 template<class Type>
00518 void Field<Type>::negate()
00519 {
00520 TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
00521 }
00522
00523
00524 template<class Type>
00525 tmp<Field<typename Field<Type>::cmptType> > Field<Type>::component
00526 (
00527 const direction d
00528 ) const
00529 {
00530 tmp<Field<cmptType> > Component(new Field<cmptType>(this->size()));
00531 ::Foam::component(Component(), *this, d);
00532 return Component;
00533 }
00534
00535
00536 template<class Type>
00537 void Field<Type>::replace
00538 (
00539 const direction d,
00540 const UList<cmptType>& sf
00541 )
00542 {
00543 TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
00544 cmptType, sf)
00545 }
00546
00547
00548 template<class Type>
00549 void Field<Type>::replace
00550 (
00551 const direction d,
00552 const tmp<Field<cmptType> >& tsf
00553 )
00554 {
00555 replace(d, tsf());
00556 tsf.clear();
00557 }
00558
00559
00560 template<class Type>
00561 void Field<Type>::replace
00562 (
00563 const direction d,
00564 const cmptType& c
00565 )
00566 {
00567 TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
00568 cmptType, c)
00569 }
00570
00571
00572 template<class Type>
00573 tmp<Field<Type> > Field<Type>::T() const
00574 {
00575 tmp<Field<Type> > transpose(new Field<Type>(this->size()));
00576 ::Foam::T(transpose(), *this);
00577 return transpose;
00578 }
00579
00580
00581 template<class Type>
00582 void Field<Type>::writeEntry(const word& keyword, Ostream& os) const
00583 {
00584 os.writeKeyword(keyword);
00585
00586 bool uniform = false;
00587
00588 if (this->size() && contiguous<Type>())
00589 {
00590 uniform = true;
00591
00592 forAll(*this, i)
00593 {
00594 if (this->operator[](i) != this->operator[](0))
00595 {
00596 uniform = false;
00597 break;
00598 }
00599 }
00600 }
00601
00602 if (uniform)
00603 {
00604 os << "uniform " << this->operator[](0) << token::END_STATEMENT;
00605 }
00606 else
00607 {
00608 os << "nonuniform ";
00609 List<Type>::writeEntry(os);
00610 os << token::END_STATEMENT;
00611 }
00612
00613 os << endl;
00614 }
00615
00616
00617
00618
00619 template<class Type>
00620 void Field<Type>::operator=(const Field<Type>& rhs)
00621 {
00622 if (this == &rhs)
00623 {
00624 FatalErrorIn("Field<Type>::operator=(const Field<Type>&)")
00625 << "attempted assignment to self"
00626 << abort(FatalError);
00627 }
00628
00629 List<Type>::operator=(rhs);
00630 }
00631
00632
00633 template<class Type>
00634 void Field<Type>::operator=(const SubField<Type>& rhs)
00635 {
00636 List<Type>::operator=(rhs);
00637 }
00638
00639
00640 template<class Type>
00641 void Field<Type>::operator=(const UList<Type>& rhs)
00642 {
00643 List<Type>::operator=(rhs);
00644 }
00645
00646
00647 template<class Type>
00648 void Field<Type>::operator=(const tmp<Field>& rhs)
00649 {
00650 if (this == &(rhs()))
00651 {
00652 FatalErrorIn("Field<Type>::operator=(const tmp<Field>&)")
00653 << "attempted assignment to self"
00654 << abort(FatalError);
00655 }
00656
00657
00658 Field* fieldPtr = rhs.ptr();
00659 List<Type>::transfer(*fieldPtr);
00660 delete fieldPtr;
00661 }
00662
00663
00664 template<class Type>
00665 void Field<Type>::operator=(const Type& t)
00666 {
00667 List<Type>::operator=(t);
00668 }
00669
00670
00671 template<class Type>
00672 template<class Form, class Cmpt, int nCmpt>
00673 void Field<Type>::operator=(const VectorSpace<Form,Cmpt,nCmpt>& vs)
00674 {
00675 typedef VectorSpace<Form,Cmpt,nCmpt> VSType;
00676 TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
00677 }
00678
00679
00680 #define COMPUTED_ASSIGNMENT(TYPE, op) \
00681 \
00682 template<class Type> \
00683 void Field<Type>::operator op(const UList<TYPE>& f) \
00684 { \
00685 TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
00686 } \
00687 \
00688 template<class Type> \
00689 void Field<Type>::operator op(const tmp<Field<TYPE> >& tf) \
00690 { \
00691 operator op(tf()); \
00692 tf.clear(); \
00693 } \
00694 \
00695 template<class Type> \
00696 void Field<Type>::operator op(const TYPE& t) \
00697 { \
00698 TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
00699 }
00700
00701 COMPUTED_ASSIGNMENT(Type, +=)
00702 COMPUTED_ASSIGNMENT(Type, -=)
00703 COMPUTED_ASSIGNMENT(scalar, *=)
00704 COMPUTED_ASSIGNMENT(scalar, /=)
00705
00706 #undef COMPUTED_ASSIGNMENT
00707
00708
00709
00710
00711 template<class Type>
00712 Ostream& operator<<(Ostream& os, const Field<Type>& f)
00713 {
00714 os << static_cast<const List<Type>&>(f);
00715 return os;
00716 }
00717
00718
00719 template<class Type>
00720 Ostream& operator<<(Ostream& os, const tmp<Field<Type> >& tf)
00721 {
00722 os << tf();
00723 tf.clear();
00724 return os;
00725 }
00726
00727
00728
00729
00730 }
00731
00732
00733
00734 # include "FieldFunctions.C"
00735
00736