FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

GeometricField.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
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 // check mesh for two fields
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 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
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         // Check compatibility between field and mesh
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     // Read the old time field if present
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 // * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
00193 
00194 // Constructor given a GeometricField and dimensionSet
00195 // This allocates storage for the field but not values.
00196 // Note : This constructor should only be used to
00197 //       construct TEMPORARY variables
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 // Constructor given a GeometricField and dimensionSet
00225 // This allocates storage for the field but not values.
00226 // Note : This constructor should only be used to
00227 //       construct TEMPORARY variables
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 // Constructor given a GeometricField and dimensioned<Type>
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 // Constructor given a GeometricField and dimensioned<Type>
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 //  construct from components
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     // Check compatibility between field and mesh
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     // Check compatibility between field and mesh
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     // Check compatibility between field and mesh
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 // construct as copy
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 // construct as copy of tmp<GeometricField> deleting argument
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 // construct as copy resetting IO parameters
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 // construct as copy resetting name
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 // construct as copy resetting name
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 // construct as copy resetting IO parameters and patch type
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 // construct as copy resetting IO parameters and boundary types
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 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
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 // Return reference to GeometricBoundaryField
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 // Store old-time field
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     // Correct time index
00749     timeIndex_ = this->time().timeIndex();
00750 }
00751 
00752 // Store old-time field
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 // Return the number of old time fields stored
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 // Return old time internal field
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 // Return old time internal field
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 // Store previous iteration field
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 // Return previous iteration field
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 // Correct the boundary conditions
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 // Does the field need a reference level for solution
00885 template<class Type, template<class> class PatchField, class GeoMesh>
00886 bool Foam::GeometricField<Type, PatchField, GeoMesh>::needReference() const
00887 {
00888     // Search all boundary conditions, if any are
00889     // fixed-value or mixed (Robin) do not set reference level for solution.
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 // writeData member function required by regIOobject
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 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
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 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
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     // only equate field contents not ID
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     // only equate field contents not ID
01131 
01132     this->dimensions() = gf.dimensions();
01133 
01134     // This is dodgy stuff, don't try it at home.
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     // only equate field contents not ID
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 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
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     // Check state of IOstream
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 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines