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 "GeometricField.H"
00027 #include <OpenFOAM/Time.H>
00028 #include <OpenFOAM/demandDrivenData.H>
00029 #include <OpenFOAM/dictionary.H>
00030
00031
00032
00033
00034
00035 #define checkField(gf1, gf2, op) \
00036 if ((gf1).mesh() != (gf2).mesh()) \
00037 { \
00038 FatalErrorIn("checkField(gf1, gf2, op)") \
00039 << "different mesh for fields " \
00040 << (gf1).name() << " and " << (gf2).name() \
00041 << " during operatrion " << op \
00042 << abort(FatalError); \
00043 }
00044
00045
00046
00047
00048 template<class Type, template<class> class PatchField, class GeoMesh>
00049 Foam::tmp
00050 <
00051 typename Foam::GeometricField<Type, PatchField, GeoMesh>::
00052 GeometricBoundaryField
00053 >
00054 Foam::GeometricField<Type, PatchField, GeoMesh>::readField
00055 (
00056 const dictionary& fieldDict
00057 )
00058 {
00059 DimensionedField<Type, GeoMesh>::readField(fieldDict, "internalField");
00060
00061 tmp<GeometricBoundaryField> tboundaryField
00062 (
00063 new GeometricBoundaryField
00064 (
00065 this->mesh().boundary(),
00066 *this,
00067 fieldDict.subDict("boundaryField")
00068 )
00069 );
00070
00071 if (fieldDict.found("referenceLevel"))
00072 {
00073 Type fieldAverage(pTraits<Type>(fieldDict.lookup("referenceLevel")));
00074
00075 Field<Type>::operator+=(fieldAverage);
00076
00077 GeometricBoundaryField& boundaryField = tboundaryField();
00078
00079 forAll(boundaryField, patchi)
00080 {
00081 boundaryField[patchi] == boundaryField[patchi] + fieldAverage;
00082 }
00083 }
00084
00085 return tboundaryField;
00086 }
00087
00088
00089 template<class Type, template<class> class PatchField, class GeoMesh>
00090 Foam::tmp
00091 <
00092 typename Foam::GeometricField<Type, PatchField, GeoMesh>::
00093 GeometricBoundaryField
00094 >
00095 Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is)
00096 {
00097 if (is.version() < 2.0)
00098 {
00099 FatalIOErrorIn
00100 (
00101 "GeometricField<Type, PatchField, GeoMesh>::readField(Istream&)",
00102 is
00103 ) << "IO versions < 2.0 are not supported."
00104 << exit(FatalIOError);
00105 }
00106
00107 return readField(dictionary(is));
00108 }
00109
00110
00111 template<class Type, template<class> class PatchField, class GeoMesh>
00112 bool Foam::GeometricField<Type, PatchField, GeoMesh>::readIfPresent()
00113 {
00114 if (this->readOpt() == IOobject::MUST_READ)
00115 {
00116 WarningIn
00117 (
00118 "GeometricField<Type, PatchField, GeoMesh>::readIfPresent()"
00119 ) << "read option IOobject::MUST_READ "
00120 << "suggests that a read constructor for field " << this->name()
00121 << " would be more appropriate." << endl;
00122 }
00123 else if (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOk())
00124 {
00125 boundaryField_.transfer(readField(this->readStream(typeName))());
00126 this->close();
00127
00128
00129 if (this->size() != GeoMesh::size(this->mesh()))
00130 {
00131 FatalIOErrorIn
00132 (
00133 "GeometricField<Type, PatchField, GeoMesh>::"
00134 "readIfPresent()",
00135 this->readStream(typeName)
00136 ) << " number of field elements = " << this->size()
00137 << " number of mesh elements = "
00138 << GeoMesh::size(this->mesh())
00139 << exit(FatalIOError);
00140 }
00141
00142 readOldTimeIfPresent();
00143
00144 return true;
00145 }
00146
00147 return false;
00148 }
00149
00150
00151 template<class Type, template<class> class PatchField, class GeoMesh>
00152 bool Foam::GeometricField<Type, PatchField, GeoMesh>::readOldTimeIfPresent()
00153 {
00154
00155 IOobject field0
00156 (
00157 this->name() + "_0",
00158 this->time().timeName(),
00159 this->db(),
00160 IOobject::READ_IF_PRESENT,
00161 IOobject::AUTO_WRITE
00162 );
00163
00164 if (field0.headerOk())
00165 {
00166 if (debug)
00167 {
00168 Info<< "Reading old time level for field"
00169 << endl << this->info() << endl;
00170 }
00171
00172 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00173 (
00174 field0,
00175 this->mesh()
00176 );
00177
00178 field0Ptr_->timeIndex_ = timeIndex_ - 1;
00179
00180 if (!field0Ptr_->readOldTimeIfPresent())
00181 {
00182 field0Ptr_->oldTime();
00183 }
00184
00185 return true;
00186 }
00187
00188 return false;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 template<class Type, template<class> class PatchField, class GeoMesh>
00199 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00200 (
00201 const IOobject& io,
00202 const Mesh& mesh,
00203 const dimensionSet& ds,
00204 const word& patchFieldType
00205 )
00206 :
00207 DimensionedField<Type, GeoMesh>(io, mesh, ds),
00208 timeIndex_(this->time().timeIndex()),
00209 field0Ptr_(NULL),
00210 fieldPrevIterPtr_(NULL),
00211 boundaryField_(mesh.boundary(), *this, patchFieldType)
00212 {
00213 if (debug)
00214 {
00215 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00216 "creating temporary"
00217 << endl << this->info() << endl;
00218 }
00219
00220 readIfPresent();
00221 }
00222
00223
00224
00225
00226
00227
00228 template<class Type, template<class> class PatchField, class GeoMesh>
00229 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00230 (
00231 const IOobject& io,
00232 const Mesh& mesh,
00233 const dimensionSet& ds,
00234 const wordList& patchFieldTypes
00235 )
00236 :
00237 DimensionedField<Type, GeoMesh>(io, mesh, ds),
00238 timeIndex_(this->time().timeIndex()),
00239 field0Ptr_(NULL),
00240 fieldPrevIterPtr_(NULL),
00241 boundaryField_(mesh.boundary(), *this, patchFieldTypes)
00242 {
00243 if (debug)
00244 {
00245 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00246 "creating temporary"
00247 << endl << this->info() << endl;
00248 }
00249
00250 readIfPresent();
00251 }
00252
00253
00254
00255 template<class Type, template<class> class PatchField, class GeoMesh>
00256 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00257 (
00258 const IOobject& io,
00259 const Mesh& mesh,
00260 const dimensioned<Type>& dt,
00261 const word& patchFieldType
00262 )
00263 :
00264 DimensionedField<Type, GeoMesh>(io, mesh, dt),
00265 timeIndex_(this->time().timeIndex()),
00266 field0Ptr_(NULL),
00267 fieldPrevIterPtr_(NULL),
00268 boundaryField_(mesh.boundary(), *this, patchFieldType)
00269 {
00270 if (debug)
00271 {
00272 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00273 "creating temporary"
00274 << endl << this->info() << endl;
00275 }
00276
00277 boundaryField_ == dt.value();
00278
00279 readIfPresent();
00280 }
00281
00282
00283
00284 template<class Type, template<class> class PatchField, class GeoMesh>
00285 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00286 (
00287 const IOobject& io,
00288 const Mesh& mesh,
00289 const dimensioned<Type>& dt,
00290 const wordList& patchFieldTypes
00291 )
00292 :
00293 DimensionedField<Type, GeoMesh>(io, mesh, dt),
00294 timeIndex_(this->time().timeIndex()),
00295 field0Ptr_(NULL),
00296 fieldPrevIterPtr_(NULL),
00297 boundaryField_(mesh.boundary(), *this, patchFieldTypes)
00298 {
00299 if (debug)
00300 {
00301 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00302 "creating temporary"
00303 << endl << this->info() << endl;
00304 }
00305
00306 boundaryField_ == dt.value();
00307
00308 readIfPresent();
00309 }
00310
00311
00312
00313 template<class Type, template<class> class PatchField, class GeoMesh>
00314 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00315 (
00316 const IOobject& io,
00317 const Mesh& mesh,
00318 const dimensionSet& ds,
00319 const Field<Type>& iField,
00320 const PtrList<PatchField<Type> >& ptfl
00321 )
00322 :
00323 DimensionedField<Type, GeoMesh>(io, mesh, ds, iField),
00324 timeIndex_(this->time().timeIndex()),
00325 field0Ptr_(NULL),
00326 fieldPrevIterPtr_(NULL),
00327 boundaryField_(mesh.boundary(), *this, ptfl)
00328 {
00329 if (debug)
00330 {
00331 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00332 "constructing from components"
00333 << endl << this->info() << endl;
00334 }
00335
00336 readIfPresent();
00337 }
00338
00339
00340 template<class Type, template<class> class PatchField, class GeoMesh>
00341 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00342 (
00343 const IOobject& io,
00344 const Mesh& mesh
00345 )
00346 :
00347 DimensionedField<Type, GeoMesh>(io, mesh, dimless),
00348 timeIndex_(this->time().timeIndex()),
00349 field0Ptr_(NULL),
00350 fieldPrevIterPtr_(NULL),
00351 boundaryField_(*this, readField(this->readStream(typeName)))
00352 {
00353 this->close();
00354
00355
00356
00357 if (this->size() != GeoMesh::size(this->mesh()))
00358 {
00359 FatalIOErrorIn
00360 (
00361 "GeometricField<Type, PatchField, GeoMesh>::GeometricField"
00362 "(const IOobject&, const Mesh&)",
00363 this->readStream(typeName)
00364 ) << " number of field elements = " << this->size()
00365 << " number of mesh elements = " << GeoMesh::size(this->mesh())
00366 << exit(FatalIOError);
00367 }
00368
00369 readOldTimeIfPresent();
00370
00371 if (debug)
00372 {
00373 Info<< "Finishing read-construct of "
00374 "GeometricField<Type, PatchField, GeoMesh>"
00375 << endl << this->info() << endl;
00376 }
00377 }
00378
00379
00380 template<class Type, template<class> class PatchField, class GeoMesh>
00381 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00382 (
00383 const IOobject& io,
00384 const Mesh& mesh,
00385 Istream& is
00386 )
00387 :
00388 DimensionedField<Type, GeoMesh>(io, mesh, dimless),
00389 timeIndex_(this->time().timeIndex()),
00390 field0Ptr_(NULL),
00391 fieldPrevIterPtr_(NULL),
00392 boundaryField_(*this, readField(is))
00393 {
00394
00395
00396 if (this->size() != GeoMesh::size(this->mesh()))
00397 {
00398 FatalIOErrorIn
00399 (
00400 "GeometricField<Type, PatchField, GeoMesh>::GeometricField"
00401 "(const IOobject&, const Mesh&, Istream&)",
00402 is
00403 ) << " number of field elements = " << this->size()
00404 << " number of mesh elements = " << GeoMesh::size(this->mesh())
00405 << exit(FatalIOError);
00406 }
00407
00408 readOldTimeIfPresent();
00409
00410 if (debug)
00411 {
00412 Info<< "Finishing read-construct of "
00413 "GeometricField<Type, PatchField, GeoMesh>"
00414 << endl << this->info() << endl;
00415 }
00416 }
00417
00418
00419 template<class Type, template<class> class PatchField, class GeoMesh>
00420 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00421 (
00422 const IOobject& io,
00423 const Mesh& mesh,
00424 const dictionary& dict
00425 )
00426 :
00427 DimensionedField<Type, GeoMesh>(io, mesh, dimless),
00428 timeIndex_(this->time().timeIndex()),
00429 field0Ptr_(NULL),
00430 fieldPrevIterPtr_(NULL),
00431 boundaryField_(*this, readField(dict))
00432 {
00433
00434
00435 if (this->size() != GeoMesh::size(this->mesh()))
00436 {
00437 FatalErrorIn
00438 (
00439 "GeometricField<Type, PatchField, GeoMesh>::GeometricField"
00440 "(const IOobject&, const Mesh&, const dictionary&)"
00441 ) << " number of field elements = " << this->size()
00442 << " number of mesh elements = " << GeoMesh::size(this->mesh())
00443 << exit(FatalIOError);
00444 }
00445
00446 readOldTimeIfPresent();
00447
00448 if (debug)
00449 {
00450 Info<< "Finishing dictionary-construct of "
00451 "GeometricField<Type, PatchField, GeoMesh>"
00452 << endl << this->info() << endl;
00453 }
00454 }
00455
00456
00457
00458 template<class Type, template<class> class PatchField, class GeoMesh>
00459 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00460 (
00461 const GeometricField<Type, PatchField, GeoMesh>& gf
00462 )
00463 :
00464 DimensionedField<Type, GeoMesh>(gf),
00465 timeIndex_(gf.timeIndex()),
00466 field0Ptr_(NULL),
00467 fieldPrevIterPtr_(NULL),
00468 boundaryField_(*this, gf.boundaryField_)
00469 {
00470 if (debug)
00471 {
00472 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00473 "constructing as copy"
00474 << endl << this->info() << endl;
00475 }
00476
00477 if (gf.field0Ptr_)
00478 {
00479 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00480 (
00481 *gf.field0Ptr_
00482 );
00483 }
00484
00485 this->writeOpt() = IOobject::NO_WRITE;
00486 }
00487
00488
00489 #ifdef ConstructFromTmp
00490 template<class Type, template<class> class PatchField, class GeoMesh>
00491 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00492 (
00493 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
00494 )
00495 :
00496 DimensionedField<Type, GeoMesh>
00497 (
00498 const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
00499 tgf.isTmp()
00500 ),
00501 timeIndex_(tgf().timeIndex()),
00502 field0Ptr_(NULL),
00503 fieldPrevIterPtr_(NULL),
00504 boundaryField_(*this, tgf().boundaryField_)
00505 {
00506 if (debug)
00507 {
00508 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00509 "constructing as copy"
00510 << endl << this->info() << endl;
00511 }
00512
00513 this->writeOpt() = IOobject::NO_WRITE;
00514
00515 tgf.clear();
00516 }
00517 #endif
00518
00519
00520
00521 template<class Type, template<class> class PatchField, class GeoMesh>
00522 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00523 (
00524 const IOobject& io,
00525 const GeometricField<Type, PatchField, GeoMesh>& gf
00526 )
00527 :
00528 DimensionedField<Type, GeoMesh>(io, gf),
00529 timeIndex_(gf.timeIndex()),
00530 field0Ptr_(NULL),
00531 fieldPrevIterPtr_(NULL),
00532 boundaryField_(*this, gf.boundaryField_)
00533 {
00534 if (debug)
00535 {
00536 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00537 "constructing as copy resetting IO params"
00538 << endl << this->info() << endl;
00539 }
00540
00541 if (!readIfPresent() && gf.field0Ptr_)
00542 {
00543 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00544 (
00545 io.name() + "_0",
00546 *gf.field0Ptr_
00547 );
00548 }
00549 }
00550
00551
00552
00553 template<class Type, template<class> class PatchField, class GeoMesh>
00554 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00555 (
00556 const word& newName,
00557 const GeometricField<Type, PatchField, GeoMesh>& gf
00558 )
00559 :
00560 DimensionedField<Type, GeoMesh>(newName, gf),
00561 timeIndex_(gf.timeIndex()),
00562 field0Ptr_(NULL),
00563 fieldPrevIterPtr_(NULL),
00564 boundaryField_(*this, gf.boundaryField_)
00565 {
00566 if (debug)
00567 {
00568 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00569 "constructing as copy resetting name"
00570 << endl << this->info() << endl;
00571 }
00572
00573 if (!readIfPresent() && gf.field0Ptr_)
00574 {
00575 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00576 (
00577 newName + "_0",
00578 *gf.field0Ptr_
00579 );
00580 }
00581 }
00582
00583
00584
00585 #ifdef ConstructFromTmp
00586 template<class Type, template<class> class PatchField, class GeoMesh>
00587 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00588 (
00589 const word& newName,
00590 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
00591 )
00592 :
00593 DimensionedField<Type, GeoMesh>
00594 (
00595 newName,
00596 const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
00597 tgf.isTmp()
00598 ),
00599 timeIndex_(tgf().timeIndex()),
00600 field0Ptr_(NULL),
00601 fieldPrevIterPtr_(NULL),
00602 boundaryField_(*this, tgf().boundaryField_)
00603 {
00604 if (debug)
00605 {
00606 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00607 "constructing from tmp resetting name"
00608 << endl << this->info() << endl;
00609 }
00610
00611 tgf.clear();
00612 }
00613 #endif
00614
00615
00616 template<class Type, template<class> class PatchField, class GeoMesh>
00617 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00618 (
00619 const IOobject& io,
00620 const GeometricField<Type, PatchField, GeoMesh>& gf,
00621 const word& patchFieldType
00622 )
00623 :
00624 DimensionedField<Type, GeoMesh>(io, gf),
00625 timeIndex_(gf.timeIndex()),
00626 field0Ptr_(NULL),
00627 fieldPrevIterPtr_(NULL),
00628 boundaryField_(this->mesh().boundary(), *this, patchFieldType)
00629 {
00630 if (debug)
00631 {
00632 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00633 "constructing as copy resetting IO params"
00634 << endl << this->info() << endl;
00635 }
00636
00637 boundaryField_ == gf.boundaryField_;
00638
00639 if (!readIfPresent() && gf.field0Ptr_)
00640 {
00641 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00642 (
00643 io.name() + "_0",
00644 *gf.field0Ptr_
00645 );
00646 }
00647 }
00648
00649
00650
00651 template<class Type, template<class> class PatchField, class GeoMesh>
00652 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
00653 (
00654 const IOobject& io,
00655 const GeometricField<Type, PatchField, GeoMesh>& gf,
00656 const wordList& patchFieldTypes
00657 )
00658 :
00659 DimensionedField<Type, GeoMesh>(io, gf),
00660 timeIndex_(gf.timeIndex()),
00661 field0Ptr_(NULL),
00662 fieldPrevIterPtr_(NULL),
00663 boundaryField_(this->mesh().boundary(), *this, patchFieldTypes)
00664 {
00665 if (debug)
00666 {
00667 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
00668 "constructing as copy resetting IO params"
00669 << endl << this->info() << endl;
00670 }
00671
00672 boundaryField_ == gf.boundaryField_;
00673
00674 if (!readIfPresent() && gf.field0Ptr_)
00675 {
00676 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00677 (
00678 io.name() + "_0",
00679 *gf.field0Ptr_
00680 );
00681 }
00682 }
00683
00684
00685
00686
00687 template<class Type, template<class> class PatchField, class GeoMesh>
00688 Foam::GeometricField<Type, PatchField, GeoMesh>::~GeometricField()
00689 {
00690 deleteDemandDrivenData(field0Ptr_);
00691 deleteDemandDrivenData(fieldPrevIterPtr_);
00692 }
00693
00694
00695
00696
00697 template<class Type, template<class> class PatchField, class GeoMesh>
00698 typename
00699 Foam::GeometricField<Type, PatchField, GeoMesh>::DimensionedInternalField&
00700 Foam::GeometricField<Type, PatchField, GeoMesh>::dimensionedInternalField()
00701 {
00702 this->setUpToDate();
00703 storeOldTimes();
00704 return *this;
00705 }
00706
00707
00708 template<class Type, template<class> class PatchField, class GeoMesh>
00709 typename
00710 Foam::GeometricField<Type, PatchField, GeoMesh>::InternalField&
00711 Foam::GeometricField<Type, PatchField, GeoMesh>::internalField()
00712 {
00713 this->setUpToDate();
00714 storeOldTimes();
00715 return *this;
00716 }
00717
00718
00719
00720 template<class Type, template<class> class PatchField, class GeoMesh>
00721 typename
00722 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField&
00723 Foam::GeometricField<Type, PatchField, GeoMesh>::boundaryField()
00724 {
00725 this->setUpToDate();
00726 storeOldTimes();
00727 return boundaryField_;
00728 }
00729
00730
00731
00732 template<class Type, template<class> class PatchField, class GeoMesh>
00733 void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTimes() const
00734 {
00735 if
00736 (
00737 field0Ptr_
00738 && timeIndex_ != this->time().timeIndex()
00739 && !(
00740 this->name().size() > 2
00741 && this->name()(this->name().size()-2, 2) == "_0"
00742 )
00743 )
00744 {
00745 storeOldTime();
00746 }
00747
00748
00749 timeIndex_ = this->time().timeIndex();
00750 }
00751
00752
00753 template<class Type, template<class> class PatchField, class GeoMesh>
00754 void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTime() const
00755 {
00756 if (field0Ptr_)
00757 {
00758 field0Ptr_->storeOldTime();
00759
00760 if (debug)
00761 {
00762 Info<< "Storing old time field for field" << endl
00763 << this->info() << endl;
00764 }
00765
00766 *field0Ptr_ == *this;
00767 field0Ptr_->timeIndex_ = timeIndex_;
00768
00769 if (field0Ptr_->field0Ptr_)
00770 {
00771 field0Ptr_->writeOpt() = this->writeOpt();
00772 }
00773 }
00774 }
00775
00776
00777 template<class Type, template<class> class PatchField, class GeoMesh>
00778 Foam::label Foam::GeometricField<Type, PatchField, GeoMesh>::nOldTimes() const
00779 {
00780 if (field0Ptr_)
00781 {
00782 return field0Ptr_->nOldTimes() + 1;
00783 }
00784 else
00785 {
00786 return 0;
00787 }
00788 }
00789
00790
00791 template<class Type, template<class> class PatchField, class GeoMesh>
00792 const Foam::GeometricField<Type, PatchField, GeoMesh>&
00793 Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime() const
00794 {
00795 if (!field0Ptr_)
00796 {
00797 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
00798 (
00799 IOobject
00800 (
00801 this->name() + "_0",
00802 this->time().timeName(),
00803 this->db()
00804 ),
00805 *this
00806 );
00807 }
00808 else
00809 {
00810 storeOldTimes();
00811 }
00812
00813 return *field0Ptr_;
00814 }
00815
00816
00817 template<class Type, template<class> class PatchField, class GeoMesh>
00818 Foam::GeometricField<Type, PatchField, GeoMesh>&
00819 Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime()
00820 {
00821 static_cast<const GeometricField<Type, PatchField, GeoMesh>&>(*this)
00822 .oldTime();
00823
00824 return *field0Ptr_;
00825 }
00826
00827
00828
00829 template<class Type, template<class> class PatchField, class GeoMesh>
00830 void Foam::GeometricField<Type, PatchField, GeoMesh>::storePrevIter() const
00831 {
00832 if (!fieldPrevIterPtr_)
00833 {
00834 if (debug)
00835 {
00836 Info<< "Allocating previous iteration field" << endl
00837 << this->info() << endl;
00838 }
00839
00840 fieldPrevIterPtr_ = new GeometricField<Type, PatchField, GeoMesh>
00841 (
00842 this->name() + "PrevIter",
00843 *this
00844 );
00845 }
00846 else
00847 {
00848 *fieldPrevIterPtr_ == *this;
00849 }
00850 }
00851
00852
00853
00854 template<class Type, template<class> class PatchField, class GeoMesh>
00855 const Foam::GeometricField<Type, PatchField, GeoMesh>&
00856 Foam::GeometricField<Type, PatchField, GeoMesh>::prevIter() const
00857 {
00858 if (!fieldPrevIterPtr_)
00859 {
00860 FatalErrorIn
00861 (
00862 "GeometricField<Type, PatchField, GeoMesh>::prevIter() const"
00863 ) << "previous iteration field" << endl << this->info() << endl
00864 << " not stored."
00865 << " Use field.storePrevIter() at start of iteration."
00866 << abort(FatalError);
00867 }
00868
00869 return *fieldPrevIterPtr_;
00870 }
00871
00872
00873
00874 template<class Type, template<class> class PatchField, class GeoMesh>
00875 void Foam::GeometricField<Type, PatchField, GeoMesh>::
00876 correctBoundaryConditions()
00877 {
00878 this->setUpToDate();
00879 storeOldTimes();
00880 boundaryField_.evaluate();
00881 }
00882
00883
00884
00885 template<class Type, template<class> class PatchField, class GeoMesh>
00886 bool Foam::GeometricField<Type, PatchField, GeoMesh>::needReference() const
00887 {
00888
00889
00890
00891 bool needRef = true;
00892
00893 forAll(boundaryField_, patchi)
00894 {
00895 if (boundaryField_[patchi].fixesValue())
00896 {
00897 needRef = false;
00898 break;
00899 }
00900 }
00901
00902 reduce(needRef, andOp<bool>());
00903
00904 return needRef;
00905 }
00906
00907
00908 template<class Type, template<class> class PatchField, class GeoMesh>
00909 void Foam::GeometricField<Type, PatchField, GeoMesh>::relax(const scalar alpha)
00910 {
00911 operator==(prevIter() + alpha*(*this - prevIter()));
00912 }
00913
00914
00915 template<class Type, template<class> class PatchField, class GeoMesh>
00916 void Foam::GeometricField<Type, PatchField, GeoMesh>::relax()
00917 {
00918 scalar alpha = 0;
00919
00920 if (this->mesh().relax(this->name()))
00921 {
00922 alpha = this->mesh().relaxationFactor(this->name());
00923 }
00924
00925 if (alpha > 0)
00926 {
00927 relax(alpha);
00928 }
00929 }
00930
00931
00932 template<class Type, template<class> class PatchField, class GeoMesh>
00933 Foam::word Foam::GeometricField<Type, PatchField, GeoMesh>::select
00934 (
00935 bool final
00936 ) const
00937 {
00938 if (final)
00939 {
00940 return this->name() + "Final";
00941 }
00942 else
00943 {
00944 return this->name();
00945 }
00946 }
00947
00948
00949
00950 template<class Type, template<class> class PatchField, class GeoMesh>
00951 bool Foam::GeometricField<Type, PatchField, GeoMesh>::
00952 writeData(Ostream& os) const
00953 {
00954 os << *this;
00955 return os.good();
00956 }
00957
00958
00959
00960
00961 template<class Type, template<class> class PatchField, class GeoMesh>
00962 Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh> >
00963 Foam::GeometricField<Type, PatchField, GeoMesh>::T() const
00964 {
00965 tmp<GeometricField<Type, PatchField, GeoMesh> > result
00966 (
00967 new GeometricField<Type, PatchField, GeoMesh>
00968 (
00969 IOobject
00970 (
00971 this->name() + ".T()",
00972 this->instance(),
00973 this->db()
00974 ),
00975 this->mesh(),
00976 this->dimensions()
00977 )
00978 );
00979
00980 Foam::T(result().internalField(), internalField());
00981 Foam::T(result().boundaryField(), boundaryField());
00982
00983 return result;
00984 }
00985
00986
00987 template<class Type, template<class> class PatchField, class GeoMesh>
00988 Foam::tmp
00989 <
00990 Foam::GeometricField
00991 <
00992 typename Foam::GeometricField<Type, PatchField, GeoMesh>::cmptType,
00993 PatchField,
00994 GeoMesh
00995 >
00996 >
00997 Foam::GeometricField<Type, PatchField, GeoMesh>::component
00998 (
00999 const direction d
01000 ) const
01001 {
01002 tmp<GeometricField<cmptType, PatchField, GeoMesh> > Component
01003 (
01004 new GeometricField<cmptType, PatchField, GeoMesh>
01005 (
01006 IOobject
01007 (
01008 this->name() + ".component(" + Foam::name(d) + ')',
01009 this->instance(),
01010 this->db()
01011 ),
01012 this->mesh(),
01013 this->dimensions()
01014 )
01015 );
01016
01017 Foam::component(Component().internalField(), internalField(), d);
01018 Foam::component(Component().boundaryField(), boundaryField(), d);
01019
01020 return Component;
01021 }
01022
01023
01024 template<class Type, template<class> class PatchField, class GeoMesh>
01025 void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
01026 (
01027 const direction d,
01028 const GeometricField
01029 <
01030 typename GeometricField<Type, PatchField, GeoMesh>::cmptType,
01031 PatchField,
01032 GeoMesh
01033 >& gcf
01034 )
01035 {
01036 internalField().replace(d, gcf.internalField());
01037 boundaryField().replace(d, gcf.boundaryField());
01038 }
01039
01040
01041 template<class Type, template<class> class PatchField, class GeoMesh>
01042 void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
01043 (
01044 const direction d,
01045 const dimensioned<cmptType>& ds
01046 )
01047 {
01048 internalField().replace(d, ds.value());
01049 boundaryField().replace(d, ds.value());
01050 }
01051
01052
01053 template<class Type, template<class> class PatchField, class GeoMesh>
01054 void Foam::GeometricField<Type, PatchField, GeoMesh>::max
01055 (
01056 const dimensioned<Type>& dt
01057 )
01058 {
01059 Foam::max(internalField(), internalField(), dt.value());
01060 Foam::max(boundaryField(), boundaryField(), dt.value());
01061 }
01062
01063
01064 template<class Type, template<class> class PatchField, class GeoMesh>
01065 void Foam::GeometricField<Type, PatchField, GeoMesh>::min
01066 (
01067 const dimensioned<Type>& dt
01068 )
01069 {
01070 Foam::min(internalField(), internalField(), dt.value());
01071 Foam::min(boundaryField(), boundaryField(), dt.value());
01072 }
01073
01074
01075 template<class Type, template<class> class PatchField, class GeoMesh>
01076 void Foam::GeometricField<Type, PatchField, GeoMesh>::negate()
01077 {
01078 internalField().negate();
01079 boundaryField().negate();
01080 }
01081
01082
01083
01084
01085 template<class Type, template<class> class PatchField, class GeoMesh>
01086 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
01087 (
01088 const GeometricField<Type, PatchField, GeoMesh>& gf
01089 )
01090 {
01091 if (this == &gf)
01092 {
01093 FatalErrorIn
01094 (
01095 "GeometricField<Type, PatchField, GeoMesh>::operator="
01096 "(const GeometricField<Type, PatchField, GeoMesh>&)"
01097 ) << "attempted assignment to self"
01098 << abort(FatalError);
01099 }
01100
01101 checkField(*this, gf, "=");
01102
01103
01104
01105 dimensionedInternalField() = gf.dimensionedInternalField();
01106 boundaryField() = gf.boundaryField();
01107 }
01108
01109
01110 template<class Type, template<class> class PatchField, class GeoMesh>
01111 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
01112 (
01113 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
01114 )
01115 {
01116 if (this == &(tgf()))
01117 {
01118 FatalErrorIn
01119 (
01120 "GeometricField<Type, PatchField, GeoMesh>::operator="
01121 "(const tmp<GeometricField<Type, PatchField, GeoMesh> >&)"
01122 ) << "attempted assignment to self"
01123 << abort(FatalError);
01124 }
01125
01126 const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
01127
01128 checkField(*this, gf, "=");
01129
01130
01131
01132 this->dimensions() = gf.dimensions();
01133
01134
01135 internalField().transfer
01136 (
01137 const_cast<Field<Type>&>(gf.internalField())
01138 );
01139
01140 boundaryField() = gf.boundaryField();
01141
01142 tgf.clear();
01143 }
01144
01145
01146 template<class Type, template<class> class PatchField, class GeoMesh>
01147 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
01148 (
01149 const dimensioned<Type>& dt
01150 )
01151 {
01152 dimensionedInternalField() = dt;
01153 boundaryField() = dt.value();
01154 }
01155
01156
01157 template<class Type, template<class> class PatchField, class GeoMesh>
01158 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
01159 (
01160 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
01161 )
01162 {
01163 const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
01164
01165 checkField(*this, gf, "==");
01166
01167
01168
01169 dimensionedInternalField() = gf.dimensionedInternalField();
01170 boundaryField() == gf.boundaryField();
01171
01172 tgf.clear();
01173 }
01174
01175
01176 template<class Type, template<class> class PatchField, class GeoMesh>
01177 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
01178 (
01179 const dimensioned<Type>& dt
01180 )
01181 {
01182 dimensionedInternalField() = dt;
01183 boundaryField() == dt.value();
01184 }
01185
01186
01187 #define COMPUTED_ASSIGNMENT(TYPE, op) \
01188 \
01189 template<class Type, template<class> class PatchField, class GeoMesh> \
01190 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
01191 ( \
01192 const GeometricField<TYPE, PatchField, GeoMesh>& gf \
01193 ) \
01194 { \
01195 checkField(*this, gf, #op); \
01196 \
01197 dimensionedInternalField() op gf.dimensionedInternalField(); \
01198 boundaryField() op gf.boundaryField(); \
01199 } \
01200 \
01201 template<class Type, template<class> class PatchField, class GeoMesh> \
01202 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
01203 ( \
01204 const tmp<GeometricField<TYPE, PatchField, GeoMesh> >& tgf \
01205 ) \
01206 { \
01207 operator op(tgf()); \
01208 tgf.clear(); \
01209 } \
01210 \
01211 template<class Type, template<class> class PatchField, class GeoMesh> \
01212 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
01213 ( \
01214 const dimensioned<TYPE>& dt \
01215 ) \
01216 { \
01217 dimensionedInternalField() op dt; \
01218 boundaryField() op dt.value(); \
01219 }
01220
01221 COMPUTED_ASSIGNMENT(Type, +=)
01222 COMPUTED_ASSIGNMENT(Type, -=)
01223 COMPUTED_ASSIGNMENT(scalar, *=)
01224 COMPUTED_ASSIGNMENT(scalar, /=)
01225
01226 #undef COMPUTED_ASSIGNMENT
01227
01228
01229
01230
01231 template<class Type, template<class> class PatchField, class GeoMesh>
01232 Foam::Ostream& Foam::operator<<
01233 (
01234 Ostream& os,
01235 const GeometricField<Type, PatchField, GeoMesh>& gf
01236 )
01237 {
01238 gf.dimensionedInternalField().writeData(os, "internalField");
01239 os << nl;
01240 gf.boundaryField().writeEntry("boundaryField", os);
01241
01242
01243 os.check
01244 (
01245 "Ostream& operator<<(Ostream&, "
01246 "const GeometricField<Type, PatchField, GeoMesh>&)"
01247 );
01248
01249 return (os);
01250 }
01251
01252
01253 template<class Type, template<class> class PatchField, class GeoMesh>
01254 Foam::Ostream& Foam::operator<<
01255 (
01256 Ostream& os,
01257 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
01258 )
01259 {
01260 os << tgf();
01261 tgf.clear();
01262 return os;
01263 }
01264
01265
01266
01267
01268 #undef checkField
01269
01270
01271
01272 #include "GeometricBoundaryField.C"
01273 #include "GeometricFieldFunctions.C"
01274
01275