ENH: Added GeometricField copy constructor with additional BC handling. See #1620

Often we want to copy a field and replace boundary conditions, e.g. change type
to calculated for some patches.  This has typically been achieved by creating a
word list of new patch types which are then fed through to the fvPatchField::New
factory method.  This is OK for types that require no additional input (usually
from dictionary) but leaves other more complex types partially
constructed/usable.

The new constructor clones all BCs except those with indices specified, for
which the fvPatchField::New method is called for the supplied patch field type.
This commit is contained in:
Andrew Heather
2020-03-11 15:16:52 +00:00
parent 149c1b66f3
commit 0eecec4811
3 changed files with 134 additions and 63 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,8 +32,7 @@ License
#include "cyclicPolyPatch.H" #include "cyclicPolyPatch.H"
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::readField
readField
( (
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
const dictionary& dict const dictionary& dict
@ -182,8 +181,7 @@ readField
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const BoundaryMesh& bmesh const BoundaryMesh& bmesh
) )
@ -194,8 +192,7 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
@ -224,8 +221,7 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
@ -289,8 +285,7 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
@ -310,12 +305,10 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
const typename GeometricField<Type, PatchField, GeoMesh>:: const typename GeometricField<Type, PatchField, GeoMesh>::Boundary& btf
Boundary& btf
) )
: :
FieldField<PatchField, Type>(btf.size()), FieldField<PatchField, Type>(btf.size()),
@ -331,11 +324,47 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const typename GeometricField<Type, PatchField, GeoMesh>:: const DimensionedField<Type, GeoMesh>& field,
Boundary& btf const typename GeometricField<Type, PatchField, GeoMesh>::Boundary& btf,
const labelList& patchIDs,
const word& patchFieldType
)
:
FieldField<PatchField, Type>(btf.size()),
bmesh_(btf.bmesh_)
{
DebugInFunction << nl;
for (const label patchi : patchIDs)
{
this->set
(
patchi,
PatchField<Type>::New
(
patchFieldType,
bmesh_[patchi],
field
)
);
}
forAll(bmesh_, patchi)
{
if (!this->set(patchi))
{
this->set(patchi, btf[patchi].clone(field));
}
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
(
const typename GeometricField<Type, PatchField, GeoMesh>::Boundary& btf
) )
: :
FieldField<PatchField, Type>(btf), FieldField<PatchField, Type>(btf),
@ -346,8 +375,7 @@ Boundary
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::Boundary
Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
const DimensionedField<Type, GeoMesh>& field, const DimensionedField<Type, GeoMesh>& field,
@ -364,8 +392,7 @@ Boundary
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::updateCoeffs()
updateCoeffs()
{ {
DebugInFunction << nl; DebugInFunction << nl;
@ -377,8 +404,7 @@ updateCoeffs()
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::evaluate()
evaluate()
{ {
DebugInFunction << nl; DebugInFunction << nl;
@ -441,8 +467,7 @@ evaluate()
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::wordList Foam::wordList
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::types() const
types() const
{ {
const FieldField<PatchField, Type>& pff = *this; const FieldField<PatchField, Type>& pff = *this;
@ -477,8 +502,7 @@ boundaryInternalField() const
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::LduInterfaceFieldPtrsList<Type> Foam::LduInterfaceFieldPtrsList<Type>
Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::interfaces() const
interfaces() const
{ {
LduInterfaceFieldPtrsList<Type> interfaces(this->size()); LduInterfaceFieldPtrsList<Type> interfaces(this->size());
@ -528,8 +552,11 @@ scalarInterfaces() const
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::writeEntry
writeEntry(const word& keyword, Ostream& os) const (
const word& keyword,
Ostream& os
) const
{ {
os.beginBlock(keyword); os.beginBlock(keyword);
this->writeEntries(os); this->writeEntries(os);
@ -540,8 +567,10 @@ writeEntry(const word& keyword, Ostream& os) const
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::writeEntries
writeEntries(Ostream& os) const (
Ostream& os
) const
{ {
forAll(*this, patchi) forAll(*this, patchi)
{ {
@ -555,8 +584,7 @@ writeEntries(Ostream& os) const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator=
operator=
( (
const typename GeometricField<Type, PatchField, GeoMesh>:: const typename GeometricField<Type, PatchField, GeoMesh>::
Boundary& bf Boundary& bf
@ -567,8 +595,7 @@ operator=
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator=
operator=
( (
const FieldField<PatchField, Type>& ptff const FieldField<PatchField, Type>& ptff
) )
@ -578,8 +605,7 @@ operator=
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator=
operator=
( (
const Type& t const Type& t
) )
@ -589,8 +615,7 @@ operator=
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator==
operator==
( (
const typename GeometricField<Type, PatchField, GeoMesh>:: const typename GeometricField<Type, PatchField, GeoMesh>::
Boundary& bf Boundary& bf
@ -604,8 +629,7 @@ operator==
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator==
operator==
( (
const FieldField<PatchField, Type>& ptff const FieldField<PatchField, Type>& ptff
) )
@ -618,8 +642,7 @@ operator==
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::operator==
operator==
( (
const Type& t const Type& t
) )

View File

@ -660,6 +660,37 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
} }
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const GeometricField<Type, PatchField, GeoMesh>& gf,
const labelList& patchIDs,
const word& patchFieldType
)
:
Internal(io, gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
boundaryField_(*this, gf.boundaryField_, patchIDs, patchFieldType)
{
DebugInFunction
<< "Copy construct, resetting IO params and setting patchFieldType "
<< "for patchIDs" << nl
<< this->info() << endl;
if (!readIfPresent() && gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
io.name() + "_0",
*gf.field0Ptr_
);
}
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
( (

View File

@ -100,15 +100,15 @@ public:
//- Type of mesh on which this GeometricField is instantiated //- Type of mesh on which this GeometricField is instantiated
typedef typename GeoMesh::Mesh Mesh; typedef typename GeoMesh::Mesh Mesh;
//- Type of boundary mesh on which this //- Type of boundary mesh on which this GeometricField::Boundary is
// GeometricField::Boundary is instantiated //- instantiated
typedef typename GeoMesh::BoundaryMesh BoundaryMesh; typedef typename GeoMesh::BoundaryMesh BoundaryMesh;
//- Type of the internal field from which this GeometricField is derived //- Type of the internal field from which this GeometricField is derived
typedef DimensionedField<Type, GeoMesh> Internal; typedef DimensionedField<Type, GeoMesh> Internal;
//- Type of the patch field of which the //- Type of the patch field of which the GeometricField::Boundary is
// GeometricField::Boundary is composed //- composed
typedef PatchField<Type> Patch; typedef PatchField<Type> Patch;
@ -129,9 +129,8 @@ public:
//- Construct from a BoundaryMesh //- Construct from a BoundaryMesh
Boundary(const BoundaryMesh& bmesh); Boundary(const BoundaryMesh& bmesh);
//- Construct from a BoundaryMesh, //- Construct from a BoundaryMesh, reference to the internal field
// reference to the internal field //- and a patch type
// and a patch type
Boundary Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
@ -139,10 +138,9 @@ public:
const word& patchFieldType const word& patchFieldType
); );
//- Construct from a BoundaryMesh, //- Construct from a BoundaryMesh, reference to the internal field
// reference to the internal field //- and a wordList of patch types and optional the actual patch
// and a wordList of patch types and optional the actual patch //- types (to override constraint patches)
// types (to override constraint patches)
Boundary Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
@ -151,9 +149,8 @@ public:
const wordList& actualPatchTypes = wordList() const wordList& actualPatchTypes = wordList()
); );
//- Construct from a BoundaryMesh, //- Construct from a BoundaryMesh, reference to the internal field
// reference to the internal field //- and a PtrList<PatchField<Type>>
// and a PtrList<PatchField<Type>>
Boundary Boundary
( (
const BoundaryMesh& bmesh, const BoundaryMesh& bmesh,
@ -168,6 +165,16 @@ public:
const Boundary& btf const Boundary& btf
); );
//- Construct as copy setting the reference to the internal field
//- and resetting type of field for given patch IDs
Boundary
(
const Internal& field,
const Boundary& btf,
const labelList& patchIDs,
const word& patchFieldName
);
//- Construct as copy //- Construct as copy
// Dangerous because Field may be set to a field which gets deleted // Dangerous because Field may be set to a field which gets deleted
// Need new type of BoundaryField, one which is part of a geometric // Need new type of BoundaryField, one which is part of a geometric
@ -206,15 +213,15 @@ public:
wordList types() const; wordList types() const;
//- Return BoundaryField of the cell values neighbouring //- Return BoundaryField of the cell values neighbouring
// the boundary //- the boundary
Boundary boundaryInternalField() const; Boundary boundaryInternalField() const;
//- Return a list of pointers for each patch field with only those //- Return a list of pointers for each patch field with only those
// pointing to interfaces being set //- pointing to interfaces being set
LduInterfaceFieldPtrsList<Type> interfaces() const; LduInterfaceFieldPtrsList<Type> interfaces() const;
//- Return a list of pointers for each patch field with only those //- Return a list of pointers for each patch field with only those
// pointing to interfaces being set //- pointing to interfaces being set
lduInterfaceFieldPtrsList scalarInterfaces() const; lduInterfaceFieldPtrsList scalarInterfaces() const;
//- Write boundary field as dictionary entry //- Write boundary field as dictionary entry
@ -259,7 +266,7 @@ private:
//- Pointer to old time field //- Pointer to old time field
mutable GeometricField<Type, PatchField, GeoMesh>* field0Ptr_; mutable GeometricField<Type, PatchField, GeoMesh>* field0Ptr_;
//- Pointer to previous iteration (used for under-relaxation) //- Pointer to previous iteration (used for under-relaxation)
mutable GeometricField<Type, PatchField, GeoMesh>* fieldPrevIterPtr_; mutable GeometricField<Type, PatchField, GeoMesh>* fieldPrevIterPtr_;
//- Boundary Type field containing boundary field values //- Boundary Type field containing boundary field values
@ -441,6 +448,16 @@ public:
const word& patchFieldType const word& patchFieldType
); );
//- Construct as copy resetting IO parameters and boundary type
//- for selected patchIDs
GeometricField
(
const IOobject& io,
const GeometricField<Type, PatchField, GeoMesh>& gf,
const labelList& patchIDs,
const word& patchFieldType
);
//- Construct as copy resetting IO parameters and boundary types //- Construct as copy resetting IO parameters and boundary types
GeometricField GeometricField
( (