1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "GeometricField.H"
28 #include "demandDrivenData.H"
29 #include "dictionary.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 // check mesh for two fields
36 #define checkField(gf1, gf2, op) \
37 if ((gf1).mesh() != (gf2).mesh()) \
39 FatalErrorIn("checkField(gf1, gf2, op)") \
40 << "different mesh for fields " \
41 << (gf1).name() << " and " << (gf2).name() \
42 << " during operatrion " << op \
43 << abort(FatalError); \
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
49 template<class Type, template<class> class PatchField, class GeoMesh>
52 typename Foam::GeometricField<Type, PatchField, GeoMesh>::
53 GeometricBoundaryField
55 Foam::GeometricField<Type, PatchField, GeoMesh>::readField
57 const dictionary& fieldDict
60 DimensionedField<Type, GeoMesh>::readField(fieldDict, "internalField");
62 tmp<GeometricBoundaryField> tboundaryField
64 new GeometricBoundaryField
66 this->mesh().boundary(),
68 fieldDict.subDict("boundaryField")
72 if (fieldDict.found("referenceLevel"))
74 Type fieldAverage(pTraits<Type>(fieldDict.lookup("referenceLevel")));
76 Field<Type>::operator+=(fieldAverage);
78 GeometricBoundaryField& boundaryField = tboundaryField();
80 forAll(boundaryField, patchi)
82 boundaryField[patchi] == boundaryField[patchi] + fieldAverage;
86 return tboundaryField;
90 template<class Type, template<class> class PatchField, class GeoMesh>
93 typename Foam::GeometricField<Type, PatchField, GeoMesh>::
94 GeometricBoundaryField
96 Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is)
105 this->time().timeName(),
117 template<class Type, template<class> class PatchField, class GeoMesh>
118 bool Foam::GeometricField<Type, PatchField, GeoMesh>::readIfPresent()
122 this->readOpt() == IOobject::MUST_READ
123 || this->readOpt() == IOobject::MUST_READ_IF_MODIFIED
128 "GeometricField<Type, PatchField, GeoMesh>::readIfPresent()"
129 ) << "read option IOobject::MUST_READ or MUST_READ_IF_MODIFIED"
130 << "suggests that a read constructor for field " << this->name()
131 << " would be more appropriate." << endl;
133 else if (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOk())
135 boundaryField_.transfer(readField(this->readStream(typeName))());
138 // Check compatibility between field and mesh
139 if (this->size() != GeoMesh::size(this->mesh()))
143 "GeometricField<Type, PatchField, GeoMesh>::"
145 this->readStream(typeName)
146 ) << " number of field elements = " << this->size()
147 << " number of mesh elements = "
148 << GeoMesh::size(this->mesh())
149 << exit(FatalIOError);
152 readOldTimeIfPresent();
161 template<class Type, template<class> class PatchField, class GeoMesh>
162 bool Foam::GeometricField<Type, PatchField, GeoMesh>::readOldTimeIfPresent()
164 // Read the old time field if present
168 this->time().timeName(),
170 IOobject::READ_IF_PRESENT,
174 if (field0.headerOk())
178 Info<< "Reading old time level for field"
179 << endl << this->info() << endl;
182 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
188 field0Ptr_->timeIndex_ = timeIndex_ - 1;
190 if (!field0Ptr_->readOldTimeIfPresent())
192 field0Ptr_->oldTime();
202 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
204 // Constructor given a GeometricField and dimensionSet
205 // This allocates storage for the field but not values.
206 // Note : This constructor should only be used to
207 // construct TEMPORARY variables
208 template<class Type, template<class> class PatchField, class GeoMesh>
209 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
213 const dimensionSet& ds,
214 const word& patchFieldType
217 DimensionedField<Type, GeoMesh>(io, mesh, ds, false),
218 timeIndex_(this->time().timeIndex()),
220 fieldPrevIterPtr_(NULL),
221 boundaryField_(mesh.boundary(), *this, patchFieldType)
225 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
227 << endl << this->info() << endl;
234 // Constructor given a GeometricField and dimensionSet
235 // This allocates storage for the field but not values.
236 // Note : This constructor should only be used to
237 // construct TEMPORARY variables
238 template<class Type, template<class> class PatchField, class GeoMesh>
239 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
243 const dimensionSet& ds,
244 const wordList& patchFieldTypes,
245 const wordList& actualPatchTypes
248 DimensionedField<Type, GeoMesh>(io, mesh, ds, false),
249 timeIndex_(this->time().timeIndex()),
251 fieldPrevIterPtr_(NULL),
252 boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes)
256 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
258 << endl << this->info() << endl;
265 // Constructor given a GeometricField and dimensioned<Type>
266 template<class Type, template<class> class PatchField, class GeoMesh>
267 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
271 const dimensioned<Type>& dt,
272 const word& patchFieldType
275 DimensionedField<Type, GeoMesh>(io, mesh, dt, false),
276 timeIndex_(this->time().timeIndex()),
278 fieldPrevIterPtr_(NULL),
279 boundaryField_(mesh.boundary(), *this, patchFieldType)
283 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
285 << endl << this->info() << endl;
288 boundaryField_ == dt.value();
294 // Constructor given a GeometricField and dimensioned<Type>
295 template<class Type, template<class> class PatchField, class GeoMesh>
296 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
300 const dimensioned<Type>& dt,
301 const wordList& patchFieldTypes,
302 const wordList& actualPatchTypes
305 DimensionedField<Type, GeoMesh>(io, mesh, dt, false),
306 timeIndex_(this->time().timeIndex()),
308 fieldPrevIterPtr_(NULL),
309 boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes)
313 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
315 << endl << this->info() << endl;
318 boundaryField_ == dt.value();
324 // construct from components
325 template<class Type, template<class> class PatchField, class GeoMesh>
326 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
330 const dimensionSet& ds,
331 const Field<Type>& iField,
332 const PtrList<PatchField<Type> >& ptfl
335 DimensionedField<Type, GeoMesh>(io, mesh, ds, iField),
336 timeIndex_(this->time().timeIndex()),
338 fieldPrevIterPtr_(NULL),
339 boundaryField_(mesh.boundary(), *this, ptfl)
343 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
344 "constructing from components"
345 << endl << this->info() << endl;
352 template<class Type, template<class> class PatchField, class GeoMesh>
353 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
359 DimensionedField<Type, GeoMesh>(io, mesh, dimless, false),
360 timeIndex_(this->time().timeIndex()),
362 fieldPrevIterPtr_(NULL),
363 boundaryField_(*this, readField(this->readStream(typeName)))
367 // Check compatibility between field and mesh
369 if (this->size() != GeoMesh::size(this->mesh()))
373 "GeometricField<Type, PatchField, GeoMesh>::GeometricField"
374 "(const IOobject&, const Mesh&)",
375 this->readStream(typeName)
376 ) << " number of field elements = " << this->size()
377 << " number of mesh elements = " << GeoMesh::size(this->mesh())
378 << exit(FatalIOError);
381 readOldTimeIfPresent();
385 Info<< "Finishing read-construct of "
386 "GeometricField<Type, PatchField, GeoMesh>"
387 << endl << this->info() << endl;
392 template<class Type, template<class> class PatchField, class GeoMesh>
393 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
397 const dictionary& dict
400 DimensionedField<Type, GeoMesh>(io, mesh, dimless, false),
401 timeIndex_(this->time().timeIndex()),
403 fieldPrevIterPtr_(NULL),
404 boundaryField_(*this, readField(dict))
406 // Check compatibility between field and mesh
408 if (this->size() != GeoMesh::size(this->mesh()))
412 "GeometricField<Type, PatchField, GeoMesh>::GeometricField"
413 "(const IOobject&, const Mesh&, const dictionary&)"
414 ) << " number of field elements = " << this->size()
415 << " number of mesh elements = " << GeoMesh::size(this->mesh())
416 << exit(FatalIOError);
419 readOldTimeIfPresent();
423 Info<< "Finishing dictionary-construct of "
424 "GeometricField<Type, PatchField, GeoMesh>"
425 << endl << this->info() << endl;
431 template<class Type, template<class> class PatchField, class GeoMesh>
432 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
434 const GeometricField<Type, PatchField, GeoMesh>& gf
437 DimensionedField<Type, GeoMesh>(gf),
438 timeIndex_(gf.timeIndex()),
440 fieldPrevIterPtr_(NULL),
441 boundaryField_(*this, gf.boundaryField_)
445 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
446 "constructing as copy"
447 << endl << this->info() << endl;
452 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
458 this->writeOpt() = IOobject::NO_WRITE;
461 // construct as copy of tmp<GeometricField> deleting argument
462 #ifdef ConstructFromTmp
463 template<class Type, template<class> class PatchField, class GeoMesh>
464 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
466 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
469 DimensionedField<Type, GeoMesh>
471 const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
474 timeIndex_(tgf().timeIndex()),
476 fieldPrevIterPtr_(NULL),
477 boundaryField_(*this, tgf().boundaryField_)
481 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
482 "constructing as copy"
483 << endl << this->info() << endl;
486 this->writeOpt() = IOobject::NO_WRITE;
493 // construct as copy resetting IO parameters
494 template<class Type, template<class> class PatchField, class GeoMesh>
495 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
498 const GeometricField<Type, PatchField, GeoMesh>& gf
501 DimensionedField<Type, GeoMesh>(io, gf),
502 timeIndex_(gf.timeIndex()),
504 fieldPrevIterPtr_(NULL),
505 boundaryField_(*this, gf.boundaryField_)
509 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
510 "constructing as copy resetting IO params"
511 << endl << this->info() << endl;
514 if (!readIfPresent() && gf.field0Ptr_)
516 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
525 // construct as copy resetting name
526 template<class Type, template<class> class PatchField, class GeoMesh>
527 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
530 const GeometricField<Type, PatchField, GeoMesh>& gf
533 DimensionedField<Type, GeoMesh>(newName, gf),
534 timeIndex_(gf.timeIndex()),
536 fieldPrevIterPtr_(NULL),
537 boundaryField_(*this, gf.boundaryField_)
541 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
542 "constructing as copy resetting name"
543 << endl << this->info() << endl;
546 if (!readIfPresent() && gf.field0Ptr_)
548 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
557 // construct as copy resetting name
558 #ifdef ConstructFromTmp
559 template<class Type, template<class> class PatchField, class GeoMesh>
560 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
563 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
566 DimensionedField<Type, GeoMesh>
569 const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
572 timeIndex_(tgf().timeIndex()),
574 fieldPrevIterPtr_(NULL),
575 boundaryField_(*this, tgf().boundaryField_)
579 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
580 "constructing from tmp resetting name"
581 << endl << this->info() << endl;
588 // construct as copy resetting IO parameters and patch type
589 template<class Type, template<class> class PatchField, class GeoMesh>
590 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
593 const GeometricField<Type, PatchField, GeoMesh>& gf,
594 const word& patchFieldType
597 DimensionedField<Type, GeoMesh>(io, gf),
598 timeIndex_(gf.timeIndex()),
600 fieldPrevIterPtr_(NULL),
601 boundaryField_(this->mesh().boundary(), *this, patchFieldType)
605 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
606 "constructing as copy resetting IO params"
607 << endl << this->info() << endl;
610 boundaryField_ == gf.boundaryField_;
612 if (!readIfPresent() && gf.field0Ptr_)
614 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
623 // construct as copy resetting IO parameters and boundary types
624 template<class Type, template<class> class PatchField, class GeoMesh>
625 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
628 const GeometricField<Type, PatchField, GeoMesh>& gf,
629 const wordList& patchFieldTypes,
630 const wordList& actualPatchTypes
634 DimensionedField<Type, GeoMesh>(io, gf),
635 timeIndex_(gf.timeIndex()),
637 fieldPrevIterPtr_(NULL),
640 this->mesh().boundary(),
648 Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
649 "constructing as copy resetting IO params"
650 << endl << this->info() << endl;
653 boundaryField_ == gf.boundaryField_;
655 if (!readIfPresent() && gf.field0Ptr_)
657 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
666 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
668 template<class Type, template<class> class PatchField, class GeoMesh>
669 Foam::GeometricField<Type, PatchField, GeoMesh>::~GeometricField()
671 deleteDemandDrivenData(field0Ptr_);
672 deleteDemandDrivenData(fieldPrevIterPtr_);
676 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
678 template<class Type, template<class> class PatchField, class GeoMesh>
680 Foam::GeometricField<Type, PatchField, GeoMesh>::DimensionedInternalField&
681 Foam::GeometricField<Type, PatchField, GeoMesh>::dimensionedInternalField()
689 template<class Type, template<class> class PatchField, class GeoMesh>
691 Foam::GeometricField<Type, PatchField, GeoMesh>::InternalField&
692 Foam::GeometricField<Type, PatchField, GeoMesh>::internalField()
700 // Return reference to GeometricBoundaryField
701 template<class Type, template<class> class PatchField, class GeoMesh>
703 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField&
704 Foam::GeometricField<Type, PatchField, GeoMesh>::boundaryField()
708 return boundaryField_;
712 // Store old-time field
713 template<class Type, template<class> class PatchField, class GeoMesh>
714 void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTimes() const
719 && timeIndex_ != this->time().timeIndex()
721 this->name().size() > 2
722 && this->name()(this->name().size()-2, 2) == "_0"
729 // Correct time index
730 timeIndex_ = this->time().timeIndex();
733 // Store old-time field
734 template<class Type, template<class> class PatchField, class GeoMesh>
735 void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTime() const
739 field0Ptr_->storeOldTime();
743 Info<< "Storing old time field for field" << endl
744 << this->info() << endl;
747 *field0Ptr_ == *this;
748 field0Ptr_->timeIndex_ = timeIndex_;
750 if (field0Ptr_->field0Ptr_)
752 field0Ptr_->writeOpt() = this->writeOpt();
757 // Return the number of old time fields stored
758 template<class Type, template<class> class PatchField, class GeoMesh>
759 Foam::label Foam::GeometricField<Type, PatchField, GeoMesh>::nOldTimes() const
763 return field0Ptr_->nOldTimes() + 1;
771 // Return old time internal field
772 template<class Type, template<class> class PatchField, class GeoMesh>
773 const Foam::GeometricField<Type, PatchField, GeoMesh>&
774 Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime() const
778 field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
783 this->time().timeName(),
797 // Return old time internal field
798 template<class Type, template<class> class PatchField, class GeoMesh>
799 Foam::GeometricField<Type, PatchField, GeoMesh>&
800 Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime()
802 static_cast<const GeometricField<Type, PatchField, GeoMesh>&>(*this)
809 // Store previous iteration field
810 template<class Type, template<class> class PatchField, class GeoMesh>
811 void Foam::GeometricField<Type, PatchField, GeoMesh>::storePrevIter() const
813 if (!fieldPrevIterPtr_)
817 Info<< "Allocating previous iteration field" << endl
818 << this->info() << endl;
821 fieldPrevIterPtr_ = new GeometricField<Type, PatchField, GeoMesh>
823 this->name() + "PrevIter",
829 *fieldPrevIterPtr_ == *this;
834 // Return previous iteration field
835 template<class Type, template<class> class PatchField, class GeoMesh>
836 const Foam::GeometricField<Type, PatchField, GeoMesh>&
837 Foam::GeometricField<Type, PatchField, GeoMesh>::prevIter() const
839 if (!fieldPrevIterPtr_)
843 "GeometricField<Type, PatchField, GeoMesh>::prevIter() const"
844 ) << "previous iteration field" << endl << this->info() << endl
846 << " Use field.storePrevIter() at start of iteration."
847 << abort(FatalError);
850 return *fieldPrevIterPtr_;
854 // Correct the boundary conditions
855 template<class Type, template<class> class PatchField, class GeoMesh>
856 void Foam::GeometricField<Type, PatchField, GeoMesh>::
857 correctBoundaryConditions()
861 boundaryField_.evaluate();
865 // Does the field need a reference level for solution
866 template<class Type, template<class> class PatchField, class GeoMesh>
867 bool Foam::GeometricField<Type, PatchField, GeoMesh>::needReference() const
869 // Search all boundary conditions, if any are
870 // fixed-value or mixed (Robin) do not set reference level for solution.
874 forAll(boundaryField_, patchi)
876 if (boundaryField_[patchi].fixesValue())
883 reduce(needRef, andOp<bool>());
889 template<class Type, template<class> class PatchField, class GeoMesh>
890 void Foam::GeometricField<Type, PatchField, GeoMesh>::relax(const scalar alpha)
896 "GeometricField<Type, PatchField, GeoMesh>::relax"
897 "(const scalar alpha)"
898 ) << "Relaxing" << endl << this->info() << " by " << alpha << endl;
901 operator==(prevIter() + alpha*(*this - prevIter()));
905 template<class Type, template<class> class PatchField, class GeoMesh>
906 void Foam::GeometricField<Type, PatchField, GeoMesh>::relax()
908 word name = this->name();
912 this->mesh().data::template lookupOrDefault<bool>
922 if (this->mesh().relax(name))
924 relax(this->mesh().relaxationFactor(name));
929 template<class Type, template<class> class PatchField, class GeoMesh>
930 Foam::word Foam::GeometricField<Type, PatchField, GeoMesh>::select
937 return this->name() + "Final";
946 // writeData member function required by regIOobject
947 template<class Type, template<class> class PatchField, class GeoMesh>
948 bool Foam::GeometricField<Type, PatchField, GeoMesh>::
949 writeData(Ostream& os) const
956 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
958 template<class Type, template<class> class PatchField, class GeoMesh>
959 Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh> >
960 Foam::GeometricField<Type, PatchField, GeoMesh>::T() const
962 tmp<GeometricField<Type, PatchField, GeoMesh> > result
964 new GeometricField<Type, PatchField, GeoMesh>
968 this->name() + ".T()",
977 Foam::T(result().internalField(), internalField());
978 Foam::T(result().boundaryField(), boundaryField());
984 template<class Type, template<class> class PatchField, class GeoMesh>
989 typename Foam::GeometricField<Type, PatchField, GeoMesh>::cmptType,
994 Foam::GeometricField<Type, PatchField, GeoMesh>::component
999 tmp<GeometricField<cmptType, PatchField, GeoMesh> > Component
1001 new GeometricField<cmptType, PatchField, GeoMesh>
1005 this->name() + ".component(" + Foam::name(d) + ')',
1014 Foam::component(Component().internalField(), internalField(), d);
1015 Foam::component(Component().boundaryField(), boundaryField(), d);
1021 template<class Type, template<class> class PatchField, class GeoMesh>
1022 void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
1025 const GeometricField
1027 typename GeometricField<Type, PatchField, GeoMesh>::cmptType,
1033 internalField().replace(d, gcf.internalField());
1034 boundaryField().replace(d, gcf.boundaryField());
1038 template<class Type, template<class> class PatchField, class GeoMesh>
1039 void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
1042 const dimensioned<cmptType>& ds
1045 internalField().replace(d, ds.value());
1046 boundaryField().replace(d, ds.value());
1050 template<class Type, template<class> class PatchField, class GeoMesh>
1051 void Foam::GeometricField<Type, PatchField, GeoMesh>::max
1053 const dimensioned<Type>& dt
1056 Foam::max(internalField(), internalField(), dt.value());
1057 Foam::max(boundaryField(), boundaryField(), dt.value());
1061 template<class Type, template<class> class PatchField, class GeoMesh>
1062 void Foam::GeometricField<Type, PatchField, GeoMesh>::min
1064 const dimensioned<Type>& dt
1067 Foam::min(internalField(), internalField(), dt.value());
1068 Foam::min(boundaryField(), boundaryField(), dt.value());
1072 template<class Type, template<class> class PatchField, class GeoMesh>
1073 void Foam::GeometricField<Type, PatchField, GeoMesh>::negate()
1075 internalField().negate();
1076 boundaryField().negate();
1080 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1082 template<class Type, template<class> class PatchField, class GeoMesh>
1083 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
1085 const GeometricField<Type, PatchField, GeoMesh>& gf
1092 "GeometricField<Type, PatchField, GeoMesh>::operator="
1093 "(const GeometricField<Type, PatchField, GeoMesh>&)"
1094 ) << "attempted assignment to self"
1095 << abort(FatalError);
1098 checkField(*this, gf, "=");
1100 // only equate field contents not ID
1102 dimensionedInternalField() = gf.dimensionedInternalField();
1103 boundaryField() = gf.boundaryField();
1107 template<class Type, template<class> class PatchField, class GeoMesh>
1108 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
1110 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
1113 if (this == &(tgf()))
1117 "GeometricField<Type, PatchField, GeoMesh>::operator="
1118 "(const tmp<GeometricField<Type, PatchField, GeoMesh> >&)"
1119 ) << "attempted assignment to self"
1120 << abort(FatalError);
1123 const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
1125 checkField(*this, gf, "=");
1127 // only equate field contents not ID
1129 this->dimensions() = gf.dimensions();
1131 // This is dodgy stuff, don't try it at home.
1132 internalField().transfer
1134 const_cast<Field<Type>&>(gf.internalField())
1137 boundaryField() = gf.boundaryField();
1143 template<class Type, template<class> class PatchField, class GeoMesh>
1144 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
1146 const dimensioned<Type>& dt
1149 dimensionedInternalField() = dt;
1150 boundaryField() = dt.value();
1154 template<class Type, template<class> class PatchField, class GeoMesh>
1155 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
1157 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
1160 const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
1162 checkField(*this, gf, "==");
1164 // only equate field contents not ID
1166 dimensionedInternalField() = gf.dimensionedInternalField();
1167 boundaryField() == gf.boundaryField();
1173 template<class Type, template<class> class PatchField, class GeoMesh>
1174 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
1176 const dimensioned<Type>& dt
1179 dimensionedInternalField() = dt;
1180 boundaryField() == dt.value();
1184 #define COMPUTED_ASSIGNMENT(TYPE, op) \
1186 template<class Type, template<class> class PatchField, class GeoMesh> \
1187 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
1189 const GeometricField<TYPE, PatchField, GeoMesh>& gf \
1192 checkField(*this, gf, #op); \
1194 dimensionedInternalField() op gf.dimensionedInternalField(); \
1195 boundaryField() op gf.boundaryField(); \
1198 template<class Type, template<class> class PatchField, class GeoMesh> \
1199 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
1201 const tmp<GeometricField<TYPE, PatchField, GeoMesh> >& tgf \
1204 operator op(tgf()); \
1208 template<class Type, template<class> class PatchField, class GeoMesh> \
1209 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
1211 const dimensioned<TYPE>& dt \
1214 dimensionedInternalField() op dt; \
1215 boundaryField() op dt.value(); \
1218 COMPUTED_ASSIGNMENT(Type, +=)
1219 COMPUTED_ASSIGNMENT(Type, -=)
1220 COMPUTED_ASSIGNMENT(scalar, *=)
1221 COMPUTED_ASSIGNMENT(scalar, /=)
1223 #undef COMPUTED_ASSIGNMENT
1226 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1228 template<class Type, template<class> class PatchField, class GeoMesh>
1229 Foam::Ostream& Foam::operator<<
1232 const GeometricField<Type, PatchField, GeoMesh>& gf
1235 gf.dimensionedInternalField().writeData(os, "internalField");
1237 gf.boundaryField().writeEntry("boundaryField", os);
1239 // Check state of IOstream
1242 "Ostream& operator<<(Ostream&, "
1243 "const GeometricField<Type, PatchField, GeoMesh>&)"
1250 template<class Type, template<class> class PatchField, class GeoMesh>
1251 Foam::Ostream& Foam::operator<<
1254 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
1263 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1267 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1269 #include "GeometricBoundaryField.C"
1270 #include "GeometricFieldFunctions.C"
1272 // ************************************************************************* //