diff --git a/src/Allwmake b/src/Allwmake index a2109cae24d40c5231193c55bd517a433e84942f..e488f9397822ef92eef76442a0ac7560ed00db3f 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -55,6 +55,7 @@ wmake $targetType finiteVolume wmake $targetType mesh/blockMesh wmake $targetType mesh/extrudeModel # Requires: blockMesh wmake $targetType dynamicMesh # Requires: extrudeModel +wmake $targetType genericPatchFields wmake $targetType parallel/decompose/decompositionMethods @@ -100,8 +101,6 @@ wmake $targetType waveModels wmake $targetType engine -wmake $targetType genericPatchFields - conversion/Allwmake $targetType $* functionObjects/Allwmake $targetType $* diff --git a/src/genericPatchFields/Make/files b/src/genericPatchFields/Make/files index 2210ca7cdc31fa22b285c9a0a83b6988d294ac2f..17ebcb95faab1884eb34b820f719c818c41bab59 100644 --- a/src/genericPatchFields/Make/files +++ b/src/genericPatchFields/Make/files @@ -1,6 +1,8 @@ +genericPatchFieldBase/genericPatchFieldBase.C + genericFaPatchField/genericFaPatchFields.C genericFvPatchField/genericFvPatchFields.C -genericPointPatchField/genericPointPatchFields.C genericFvsPatchField/genericFvsPatchFields.C +genericPointPatchField/genericPointPatchFields.C LIB = $(FOAM_LIBBIN)/libgenericPatchFields diff --git a/src/genericPatchFields/genericFaPatchField/genericFaPatchField.C b/src/genericPatchFields/genericFaPatchField/genericFaPatchField.C index fc9f319ccc197df0db52c5a9e5074ba1c2071cde..00bfded5d76761855268f3b418198a9e4fceea05 100644 --- a/src/genericPatchFields/genericFaPatchField/genericFaPatchField.C +++ b/src/genericPatchFields/genericFaPatchField/genericFaPatchField.C @@ -38,12 +38,12 @@ Foam::genericFaPatchField<Type>::genericFaPatchField const DimensionedField<Type, areaMesh>& iF ) : - calculatedFaPatchField<Type>(p, iF) + parent_bctype(p, iF) { FatalErrorInFunction - << "Trying to construct an genericFaPatchField on patch " + << "Trying to construct genericFaPatchField on patch " << this->patch().name() - << " of field " << this->internalField().name() + << " of field " << this->internalField().name() << nl << abort(FatalError); } @@ -56,545 +56,86 @@ Foam::genericFaPatchField<Type>::genericFaPatchField const dictionary& dict ) : - calculatedFaPatchField<Type>(p, iF, dict), - actualTypeName_(dict.get<word>("type")), - dict_(dict) + parent_bctype(p, iF, dict), + genericPatchFieldBase(dict) { const label patchSize = this->size(); + const word& patchName = this->patch().name(); + const IOobject& io = this->internalField(); if (!dict.found("value")) { - FatalIOErrorInFunction(dict) - << nl << " Cannot find 'value' entry" - << " on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() << nl - << " which is required to set the" - " values of the generic patch field." << nl - << " (Actual type " << actualTypeName_ << ')' << nl << nl - << " Please add the 'value' entry to the write function" - " of the user-defined boundary-condition" << nl - << exit(FatalIOError); + reportMissingEntry("value", patchName, io); } - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if - ( - key == "type" - || key == "value" - || !dEntry.isStream() || dEntry.stream().empty() - ) - { - continue; - } - - - ITstream& is = dEntry.stream(); - - // Read first token - token firstToken(is); - - if (firstToken.isWord("nonuniform")) - { - token fieldToken(is); - - if (!fieldToken.isCompound()) - { - if - ( - fieldToken.isLabel() - && fieldToken.labelToken() == 0 - ) - { - scalarFields_.insert(key, autoPtr<scalarField>::New()); - } - else - { - FatalIOErrorInFunction(dict) - << "\n token following 'nonuniform' " - "is not a compound" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<scalar>>::typeName - ) - { - auto fPtr = autoPtr<scalarField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<scalar>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - scalarFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<vector>>::typeName - ) - { - auto fPtr = autoPtr<vectorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<vector>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - vectorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<sphericalTensor>>::typeName - ) - { - auto fPtr = autoPtr<sphericalTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<sphericalTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - sphTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<symmTensor>>::typeName - ) - { - auto fPtr = autoPtr<symmTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<symmTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - symmTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<tensor>>::typeName - ) - { - auto fPtr = autoPtr<tensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<tensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - tensorFields_.insert(key, fPtr); - } - else - { - FatalIOErrorInFunction(dict) - << "\n compound " << fieldToken.compoundToken() - << " not supported" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if (firstToken.isWord("uniform")) - { - token fieldToken(is); - - if (!fieldToken.isPunctuation()) - { - scalarFields_.insert - ( - key, - autoPtr<scalarField>::New - ( - patchSize, - fieldToken.number() - ) - ); - } - else - { - // Read as scalarList. - is.putBack(fieldToken); - - scalarList l(is); - - if (l.size() == vector::nComponents) - { - vector vs(l[0], l[1], l[2]); - - vectorFields_.insert - ( - key, - autoPtr<vectorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == sphericalTensor::nComponents) - { - sphericalTensor vs(l[0]); - - sphTensorFields_.insert - ( - key, - autoPtr<sphericalTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == symmTensor::nComponents) - { - symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]); - - symmTensorFields_.insert - ( - key, - autoPtr<symmTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == tensor::nComponents) - { - tensor vs - ( - l[0], l[1], l[2], - l[3], l[4], l[5], - l[6], l[7], l[8] - ); - - tensorFields_.insert - ( - key, - autoPtr<tensorField>::New - ( - patchSize, - vs - ) - ); - } - else - { - FatalIOErrorInFunction(dict) - << "\n unrecognised native type " << l - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - } - } + // Handle "value" separately + processGeneric(patchSize, patchName, io, true); } template<class Type> Foam::genericFaPatchField<Type>::genericFaPatchField ( - const genericFaPatchField<Type>& ptf, + const genericFaPatchField<Type>& rhs, const faPatch& p, const DimensionedField<Type, areaMesh>& iF, const faPatchFieldMapper& mapper ) : - calculatedFaPatchField<Type>(ptf, p, iF, mapper), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_) + parent_bctype(rhs, p, iF, mapper), + genericPatchFieldBase(zero{}, rhs) { - forAllConstIters(ptf.scalarFields_, iter) - { - scalarFields_.insert - ( - iter.key(), - autoPtr<scalarField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.vectorFields_, iter) - { - vectorFields_.insert - ( - iter.key(), - autoPtr<vectorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.sphTensorFields_, iter) - { - sphTensorFields_.insert - ( - iter.key(), - autoPtr<sphericalTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.symmTensorFields_, iter) - { - symmTensorFields_.insert - ( - iter.key(), - autoPtr<symmTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.tensorFields_, iter) - { - tensorFields_.insert - ( - iter.key(), - autoPtr<tensorField>::New(*iter(), mapper) - ); - } + this->mapGeneric(rhs, mapper); } template<class Type> Foam::genericFaPatchField<Type>::genericFaPatchField ( - const genericFaPatchField<Type>& ptf -) -: - calculatedFaPatchField<Type>(ptf), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) -{} - - -template<class Type> -Foam::genericFaPatchField<Type>::genericFaPatchField -( - const genericFaPatchField<Type>& ptf, + const genericFaPatchField<Type>& rhs, const DimensionedField<Type, areaMesh>& iF ) : - calculatedFaPatchField<Type>(ptf, iF), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) + parent_bctype(rhs, iF), + genericPatchFieldBase(rhs) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class Type> +void Foam::genericFaPatchField<Type>::write(Ostream& os) const +{ + // Handle "value" separately + genericPatchFieldBase::writeGeneric(os, true); + this->writeEntry("value", os); +} + + template<class Type> void Foam::genericFaPatchField<Type>::autoMap ( const faPatchFieldMapper& m ) { - calculatedFaPatchField<Type>::autoMap(m); - - forAllIters(scalarFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(vectorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(sphTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(symmTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(tensorFields_, iter) - { - (*iter)->autoMap(m); - } + parent_bctype::autoMap(m); + this->autoMapGeneric(m); } template<class Type> void Foam::genericFaPatchField<Type>::rmap ( - const faPatchField<Type>& ptf, + const faPatchField<Type>& rhs, const labelList& addr ) { - calculatedFaPatchField<Type>::rmap(ptf, addr); - - const genericFaPatchField<Type>& dptf = - refCast<const genericFaPatchField<Type>>(ptf); - - forAllIters(scalarFields_, iter ) - { - const auto iter2 = dptf.scalarFields_.cfind(iter.key()); - - if (iter.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(vectorFields_, iter) - { - const auto iter2 = dptf.vectorFields_.cfind(iter.key()); - - if (iter.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(sphTensorFields_, iter) - { - const auto iter2 = dptf.sphTensorFields_.cfind(iter.key()); - - if (iter.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } + parent_bctype::rmap(rhs, addr); - forAllIters(symmTensorFields_, iter) + const auto* base = isA<genericPatchFieldBase>(rhs); + if (base) { - const auto iter2 = dptf.symmTensorFields_.cfind(iter.key()); - - if (iter.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(tensorFields_, iter) - { - const auto iter2 = dptf.tensorFields_.find(iter.key()); - - if (iter.found()) - { - (*iter)->rmap(*iter2(), addr); - } + this->rmapGeneric(*base, addr); } } @@ -607,14 +148,14 @@ Foam::genericFaPatchField<Type>::valueInternalCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFaPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFaPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -628,14 +169,14 @@ Foam::genericFaPatchField<Type>::valueBoundaryCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFaPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFaPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -646,92 +187,34 @@ Foam::tmp<Foam::Field<Type>> Foam::genericFaPatchField<Type>::gradientInternalCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFaPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFaPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } + template<class Type> Foam::tmp<Foam::Field<Type>> Foam::genericFaPatchField<Type>::gradientBoundaryCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFaPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); - - return *this; -} - - -template<class Type> -const Foam::word& Foam::genericFaPatchField<Type>::actualType() const -{ - return actualTypeName_; -} - + << "Cannot be called for a genericFaPatchField"; -template<class Type> -void Foam::genericFaPatchField<Type>::write(Ostream& os) const -{ - os.writeEntry("type", actualTypeName_); + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if (key == "type" || key == "value") - { - // NB: "type" written first, "value" written last - continue; - } - else if - ( - dEntry.isStream() - && dEntry.stream().size() - && dEntry.stream()[0].isWord("nonuniform") - ) - { - if (scalarFields_.found(key)) - { - scalarFields_.cfind(key)()->writeEntry(key, os); - } - else if (vectorFields_.found(key)) - { - vectorFields_.cfind(key)()->writeEntry(key, os); - } - else if (sphTensorFields_.found(key)) - { - sphTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (symmTensorFields_.found(key)) - { - symmTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (tensorFields_.found(key)) - { - tensorFields_.cfind(key)()->writeEntry(key, os); - } - } - else - { - dEntry.write(os); - } - } - - this->writeEntry("value", os); + return *this; } diff --git a/src/genericPatchFields/genericFaPatchField/genericFaPatchField.H b/src/genericPatchFields/genericFaPatchField/genericFaPatchField.H index b4e05daaeedc214ca0f76f39efd7e6088df357bc..fece0812dad8b00b1cf56eb561ce2ffd7c68126c 100644 --- a/src/genericPatchFields/genericFaPatchField/genericFaPatchField.H +++ b/src/genericPatchFields/genericFaPatchField/genericFaPatchField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,7 +44,7 @@ SourceFiles #define genericFaPatchField_H #include "calculatedFaPatchField.H" -#include "HashPtrTable.H" +#include "genericPatchFieldBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,19 +58,11 @@ namespace Foam template<class Type> class genericFaPatchField : - public calculatedFaPatchField<Type> + public calculatedFaPatchField<Type>, + public genericPatchFieldBase { - // Private Data - - const word actualTypeName_; - - dictionary dict_; - - HashPtrTable<scalarField> scalarFields_; - HashPtrTable<vectorField> vectorFields_; - HashPtrTable<sphericalTensorField> sphTensorFields_; - HashPtrTable<symmTensorField> symmTensorFields_; - HashPtrTable<tensorField> tensorFields_; + //- The parent boundary condition type + typedef calculatedFaPatchField<Type> parent_bctype; public: @@ -105,12 +97,6 @@ public: const faPatchFieldMapper& ); - //- Construct as copy - genericFaPatchField - ( - const genericFaPatchField<Type>& - ); - //- Construct and return a clone virtual tmp<faPatchField<Type>> clone() const { @@ -120,6 +106,9 @@ public: ); } + //- Default construct + genericFaPatchField(const genericFaPatchField<Type>&) = default; + //- Construct as copy setting internal field reference genericFaPatchField ( @@ -142,52 +131,38 @@ public: // Member Functions - // Mapping Functions - - //- Map (and resize as needed) from self given a mapping object - virtual void autoMap - ( - const faPatchFieldMapper& - ); + //- Write + virtual void write(Ostream&) const; - //- Reverse map the given faPatchField onto this faPatchField - virtual void rmap - ( - const faPatchField<Type>&, - const labelList& - ); + // Mapping Functions - // Evaluation Functions + //- Map (and resize as needed) from self given a mapping object + virtual void autoMap(const faPatchFieldMapper&); - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueInternalCoeffs - ( - const tmp<scalarField>& - ) const; + //- Reverse map the given faPatchField onto this faPatchField + virtual void rmap + ( + const faPatchField<Type>&, + const labelList& + ); - //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueBoundaryCoeffs - ( - const tmp<scalarField>& - ) const; - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientInternalCoeffs() const; + // Evaluation Functions - //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientBoundaryCoeffs() const; + //- Fatal + virtual tmp<Field<Type>> + valueInternalCoeffs(const tmp<scalarField>&) const; + //- Fatal + virtual tmp<Field<Type>> + valueBoundaryCoeffs(const tmp<scalarField>&) const; - //- Return the actual type - const word& actualType() const; + //- Fatal + tmp<Field<Type>> gradientInternalCoeffs() const; - //- Write - virtual void write(Ostream&) const; + //- Fatal + tmp<Field<Type>> gradientBoundaryCoeffs() const; }; diff --git a/src/genericPatchFields/genericFvPatchField/genericFvPatchField.C b/src/genericPatchFields/genericFvPatchField/genericFvPatchField.C index 3ce915e5ec60c21dafea89b83840efd920cd372f..0f72c34600b40662d12e45a2ae7442232ee2c302 100644 --- a/src/genericPatchFields/genericFvPatchField/genericFvPatchField.C +++ b/src/genericPatchFields/genericFvPatchField/genericFvPatchField.C @@ -38,7 +38,7 @@ Foam::genericFvPatchField<Type>::genericFvPatchField const DimensionedField<Type, volMesh>& iF ) : - calculatedFvPatchField<Type>(p, iF) + parent_bctype(p, iF) { FatalErrorInFunction << "Trying to construct an genericFvPatchField on patch " @@ -56,545 +56,86 @@ Foam::genericFvPatchField<Type>::genericFvPatchField const dictionary& dict ) : - calculatedFvPatchField<Type>(p, iF, dict), - actualTypeName_(dict.get<word>("type")), - dict_(dict) + parent_bctype(p, iF, dict), + genericPatchFieldBase(dict) { const label patchSize = this->size(); + const word& patchName = this->patch().name(); + const IOobject& io = this->internalField(); if (!dict.found("value")) { - FatalIOErrorInFunction(dict) - << nl << " Cannot find 'value' entry" - << " on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() << nl - << " which is required to set the" - " values of the generic patch field." << nl - << " (Actual type " << actualTypeName_ << ')' << nl << nl - << " Please add the 'value' entry to the write function" - " of the user-defined boundary-condition" << nl - << exit(FatalIOError); + reportMissingEntry("value", patchName, io); } - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if - ( - key == "type" - || key == "value" - || !dEntry.isStream() || dEntry.stream().empty() - ) - { - continue; - } - - - ITstream& is = dEntry.stream(); - - // Read first token - token firstToken(is); - - if (firstToken.isWord("nonuniform")) - { - token fieldToken(is); - - if (!fieldToken.isCompound()) - { - if - ( - fieldToken.isLabel() - && fieldToken.labelToken() == 0 - ) - { - scalarFields_.insert(key, autoPtr<scalarField>::New()); - } - else - { - FatalIOErrorInFunction(dict) - << "\n token following 'nonuniform' " - "is not a compound" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<scalar>>::typeName - ) - { - auto fPtr = autoPtr<scalarField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<scalar>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - scalarFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<vector>>::typeName - ) - { - auto fPtr = autoPtr<vectorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<vector>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - vectorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<sphericalTensor>>::typeName - ) - { - auto fPtr = autoPtr<sphericalTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<sphericalTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - sphTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<symmTensor>>::typeName - ) - { - auto fPtr = autoPtr<symmTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<symmTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - symmTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<tensor>>::typeName - ) - { - auto fPtr = autoPtr<tensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<tensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - tensorFields_.insert(key, fPtr); - } - else - { - FatalIOErrorInFunction(dict) - << "\n compound " << fieldToken.compoundToken() - << " not supported" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if (firstToken.isWord("uniform")) - { - token fieldToken(is); - - if (!fieldToken.isPunctuation()) - { - scalarFields_.insert - ( - key, - autoPtr<scalarField>::New - ( - patchSize, - fieldToken.number() - ) - ); - } - else - { - // Read as scalarList. - is.putBack(fieldToken); - - scalarList l(is); - - if (l.size() == vector::nComponents) - { - vector vs(l[0], l[1], l[2]); - - vectorFields_.insert - ( - key, - autoPtr<vectorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == sphericalTensor::nComponents) - { - sphericalTensor vs(l[0]); - - sphTensorFields_.insert - ( - key, - autoPtr<sphericalTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == symmTensor::nComponents) - { - symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]); - - symmTensorFields_.insert - ( - key, - autoPtr<symmTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == tensor::nComponents) - { - tensor vs - ( - l[0], l[1], l[2], - l[3], l[4], l[5], - l[6], l[7], l[8] - ); - - tensorFields_.insert - ( - key, - autoPtr<tensorField>::New - ( - patchSize, - vs - ) - ); - } - else - { - FatalIOErrorInFunction(dict) - << "\n unrecognised native type " << l - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - } - } + // Handle "value" separately + processGeneric(patchSize, patchName, io, true); } template<class Type> Foam::genericFvPatchField<Type>::genericFvPatchField ( - const genericFvPatchField<Type>& ptf, + const genericFvPatchField<Type>& rhs, const fvPatch& p, const DimensionedField<Type, volMesh>& iF, const fvPatchFieldMapper& mapper ) : - calculatedFvPatchField<Type>(ptf, p, iF, mapper), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_) + parent_bctype(rhs, p, iF, mapper), + genericPatchFieldBase(zero{}, rhs) { - forAllConstIters(ptf.scalarFields_, iter) - { - scalarFields_.insert - ( - iter.key(), - autoPtr<scalarField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.vectorFields_, iter) - { - vectorFields_.insert - ( - iter.key(), - autoPtr<vectorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.sphTensorFields_, iter) - { - sphTensorFields_.insert - ( - iter.key(), - autoPtr<sphericalTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.symmTensorFields_, iter) - { - symmTensorFields_.insert - ( - iter.key(), - autoPtr<symmTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.tensorFields_, iter) - { - tensorFields_.insert - ( - iter.key(), - autoPtr<tensorField>::New(*iter(), mapper) - ); - } + this->mapGeneric(rhs, mapper); } template<class Type> Foam::genericFvPatchField<Type>::genericFvPatchField ( - const genericFvPatchField<Type>& ptf -) -: - calculatedFvPatchField<Type>(ptf), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) -{} - - -template<class Type> -Foam::genericFvPatchField<Type>::genericFvPatchField -( - const genericFvPatchField<Type>& ptf, + const genericFvPatchField<Type>& rhs, const DimensionedField<Type, volMesh>& iF ) : - calculatedFvPatchField<Type>(ptf, iF), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) + parent_bctype(rhs, iF), + genericPatchFieldBase(rhs) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class Type> +void Foam::genericFvPatchField<Type>::write(Ostream& os) const +{ + // Handle "value" separately + genericPatchFieldBase::writeGeneric(os, true); + this->writeEntry("value", os); +} + + template<class Type> void Foam::genericFvPatchField<Type>::autoMap ( const fvPatchFieldMapper& m ) { - calculatedFvPatchField<Type>::autoMap(m); - - forAllIters(scalarFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(vectorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(sphTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(symmTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(tensorFields_, iter) - { - (*iter)->autoMap(m); - } + parent_bctype::autoMap(m); + this->autoMapGeneric(m); } template<class Type> void Foam::genericFvPatchField<Type>::rmap ( - const fvPatchField<Type>& ptf, + const fvPatchField<Type>& rhs, const labelList& addr ) { - calculatedFvPatchField<Type>::rmap(ptf, addr); + parent_bctype::rmap(rhs, addr); - const genericFvPatchField<Type>& dptf = - refCast<const genericFvPatchField<Type>>(ptf); - - forAllIters(scalarFields_, iter) - { - const auto iter2 = dptf.scalarFields_.cfind(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(vectorFields_, iter) - { - const auto iter2 = dptf.vectorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(sphTensorFields_, iter) + const auto* base = isA<genericPatchFieldBase>(rhs); + if (base) { - const auto iter2 = dptf.sphTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(symmTensorFields_, iter) - { - const auto iter2 = dptf.symmTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(tensorFields_, iter) - { - const auto iter2 = dptf.tensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } + this->rmapGeneric(*base, addr); } } @@ -607,14 +148,14 @@ Foam::genericFvPatchField<Type>::valueInternalCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFvPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -628,14 +169,14 @@ Foam::genericFvPatchField<Type>::valueBoundaryCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFvPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -646,14 +187,14 @@ Foam::tmp<Foam::Field<Type>> Foam::genericFvPatchField<Type>::gradientInternalCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFvPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -663,74 +204,16 @@ Foam::tmp<Foam::Field<Type>> Foam::genericFvPatchField<Type>::gradientBoundaryCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFvPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); - - return *this; -} + << "Cannot be called for a genericFvPatchField"; + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); -template<class Type> -const Foam::word& Foam::genericFvPatchField<Type>::actualType() const -{ - return actualTypeName_; -} - - -template<class Type> -void Foam::genericFvPatchField<Type>::write(Ostream& os) const -{ - os.writeEntry("type", actualTypeName_); - - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if (key == "type" || key == "value") - { - continue; - } - else if - ( - dEntry.isStream() - && dEntry.stream().size() - && dEntry.stream()[0].isWord("nonuniform") - ) - { - if (scalarFields_.found(key)) - { - scalarFields_.cfind(key)()->writeEntry(key, os); - } - else if (vectorFields_.found(key)) - { - vectorFields_.cfind(key)()->writeEntry(key, os); - } - else if (sphTensorFields_.found(key)) - { - sphTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (symmTensorFields_.found(key)) - { - symmTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (tensorFields_.found(key)) - { - tensorFields_.cfind(key)()->writeEntry(key, os); - } - } - else - { - dEntry.write(os); - } - } - - this->writeEntry("value", os); + return *this; } diff --git a/src/genericPatchFields/genericFvPatchField/genericFvPatchField.H b/src/genericPatchFields/genericFvPatchField/genericFvPatchField.H index 7adff19164733b4aa55a485c38736abbc062ce3f..7c527fe050f86ca8d40c7b17cea0ff746c9c9909 100644 --- a/src/genericPatchFields/genericFvPatchField/genericFvPatchField.H +++ b/src/genericPatchFields/genericFvPatchField/genericFvPatchField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,7 +44,7 @@ SourceFiles #define genericFvPatchField_H #include "calculatedFvPatchField.H" -#include "HashPtrTable.H" +#include "genericPatchFieldBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,19 +58,11 @@ namespace Foam template<class Type> class genericFvPatchField : - public calculatedFvPatchField<Type> + public calculatedFvPatchField<Type>, + public genericPatchFieldBase { - // Private Data - - const word actualTypeName_; - - dictionary dict_; - - HashPtrTable<scalarField> scalarFields_; - HashPtrTable<vectorField> vectorFields_; - HashPtrTable<sphericalTensorField> sphTensorFields_; - HashPtrTable<symmTensorField> symmTensorFields_; - HashPtrTable<tensorField> tensorFields_; + //- The parent boundary condition type + typedef calculatedFvPatchField<Type> parent_bctype; public: @@ -105,12 +97,6 @@ public: const fvPatchFieldMapper& ); - //- Construct as copy - genericFvPatchField - ( - const genericFvPatchField<Type>& - ); - //- Construct and return a clone virtual tmp<fvPatchField<Type>> clone() const { @@ -120,6 +106,9 @@ public: ); } + //- Default copy construct + genericFvPatchField(const genericFvPatchField<Type>&) = default; + //- Construct as copy setting internal field reference genericFvPatchField ( @@ -142,52 +131,38 @@ public: // Member Functions - // Mapping Functions - - //- Map (and resize as needed) from self given a mapping object - virtual void autoMap - ( - const fvPatchFieldMapper& - ); + //- Write + virtual void write(Ostream&) const; - //- Reverse map the given fvPatchField onto this fvPatchField - virtual void rmap - ( - const fvPatchField<Type>&, - const labelList& - ); + // Mapping Functions - // Evaluation Functions + //- Map (and resize as needed) from self given a mapping object + virtual void autoMap(const fvPatchFieldMapper&); - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueInternalCoeffs - ( - const tmp<scalarField>& - ) const; + //- Reverse map the given fvPatchField onto this fvPatchField + virtual void rmap + ( + const fvPatchField<Type>&, + const labelList& + ); - //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueBoundaryCoeffs - ( - const tmp<scalarField>& - ) const; - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientInternalCoeffs() const; + // Evaluation Functions - //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientBoundaryCoeffs() const; + //- Fatal + virtual tmp<Field<Type>> + valueInternalCoeffs(const tmp<scalarField>&) const; + //- Fatal + virtual tmp<Field<Type>> + valueBoundaryCoeffs(const tmp<scalarField>&) const; - //- Return the actual type - const word& actualType() const; + //- Fatal + tmp<Field<Type>> gradientInternalCoeffs() const; - //- Write - virtual void write(Ostream&) const; + //- Fatal + tmp<Field<Type>> gradientBoundaryCoeffs() const; }; diff --git a/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.C b/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.C index 8b3af677ff6954fc4785ae89b56b7d425ff56b7c..a982f110cd75b306cc74f9ea34a1341bc299bf8c 100644 --- a/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.C +++ b/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.C @@ -37,7 +37,7 @@ Foam::genericFvsPatchField<Type>::genericFvsPatchField const DimensionedField<Type, surfaceMesh>& iF ) : - calculatedFvsPatchField<Type>(p, iF) + parent_bctype(p, iF) { FatalErrorInFunction << "Trying to construct an genericFvsPatchField on patch " @@ -55,545 +55,87 @@ Foam::genericFvsPatchField<Type>::genericFvsPatchField const dictionary& dict ) : - calculatedFvsPatchField<Type>(p, iF, dict), - actualTypeName_(dict.get<word>("type")), - dict_(dict) + parent_bctype(p, iF, dict), + genericPatchFieldBase(dict) { const label patchSize = this->size(); + const word& patchName = this->patch().name(); + const IOobject& io = this->internalField(); if (!dict.found("value")) { - FatalIOErrorInFunction(dict) - << nl << " Cannot find 'value' entry" - << " on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() << nl - << " which is required to set the" - " values of the generic patch field." << nl - << " (Actual type " << actualTypeName_ << ')' << nl << nl - << " Please add the 'value' entry to the write function" - " of the user-defined boundary-condition" << nl - << exit(FatalIOError); + reportMissingEntry("value", patchName, io); } - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if - ( - key == "type" - || key == "value" - || !dEntry.isStream() || dEntry.stream().empty() - ) - { - continue; - } - - - ITstream& is = dEntry.stream(); - - // Read first token - token firstToken(is); - - if (firstToken.isWord("nonuniform")) - { - token fieldToken(is); - - if (!fieldToken.isCompound()) - { - if - ( - fieldToken.isLabel() - && fieldToken.labelToken() == 0 - ) - { - scalarFields_.insert(key, autoPtr<scalarField>::New()); - } - else - { - FatalIOErrorInFunction(dict) - << "\n token following 'nonuniform' " - "is not a compound" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<scalar>>::typeName - ) - { - auto fPtr = autoPtr<scalarField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<scalar>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - scalarFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<vector>>::typeName - ) - { - auto fPtr = autoPtr<vectorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<vector>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - vectorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<sphericalTensor>>::typeName - ) - { - auto fPtr = autoPtr<sphericalTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<sphericalTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - sphTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<symmTensor>>::typeName - ) - { - auto fPtr = autoPtr<symmTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<symmTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - symmTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<tensor>>::typeName - ) - { - auto fPtr = autoPtr<tensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<tensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - tensorFields_.insert(key, fPtr); - } - else - { - FatalIOErrorInFunction(dict) - << "\n compound " << fieldToken.compoundToken() - << " not supported" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if (firstToken.isWord("uniform")) - { - token fieldToken(is); - - if (!fieldToken.isPunctuation()) - { - scalarFields_.insert - ( - key, - autoPtr<scalarField>::New - ( - patchSize, - fieldToken.number() - ) - ); - } - else - { - // Read as scalarList. - is.putBack(fieldToken); - - scalarList l(is); - - if (l.size() == vector::nComponents) - { - vector vs(l[0], l[1], l[2]); - - vectorFields_.insert - ( - key, - autoPtr<vectorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == sphericalTensor::nComponents) - { - sphericalTensor vs(l[0]); - - sphTensorFields_.insert - ( - key, - autoPtr<sphericalTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == symmTensor::nComponents) - { - symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]); - - symmTensorFields_.insert - ( - key, - autoPtr<symmTensorField>::New - ( - patchSize, - vs - ) - ); - } - else if (l.size() == tensor::nComponents) - { - tensor vs - ( - l[0], l[1], l[2], - l[3], l[4], l[5], - l[6], l[7], l[8] - ); - - tensorFields_.insert - ( - key, - autoPtr<tensorField>::New - ( - patchSize, - vs - ) - ); - } - else - { - FatalIOErrorInFunction(dict) - << "\n unrecognised native type " << l - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - } - } + // Handle "value" separately + processGeneric(patchSize, patchName, io, true); } template<class Type> Foam::genericFvsPatchField<Type>::genericFvsPatchField ( - const genericFvsPatchField<Type>& ptf, + const genericFvsPatchField<Type>& rhs, const fvPatch& p, const DimensionedField<Type, surfaceMesh>& iF, const fvPatchFieldMapper& mapper ) : - calculatedFvsPatchField<Type>(ptf, p, iF, mapper), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_) + parent_bctype(rhs, p, iF, mapper), + genericPatchFieldBase(zero{}, rhs) { - forAllConstIters(ptf.scalarFields_, iter) - { - scalarFields_.insert - ( - iter.key(), - autoPtr<scalarField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.vectorFields_, iter) - { - vectorFields_.insert - ( - iter.key(), - autoPtr<vectorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.sphTensorFields_, iter) - { - sphTensorFields_.insert - ( - iter.key(), - autoPtr<sphericalTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.symmTensorFields_, iter) - { - symmTensorFields_.insert - ( - iter.key(), - autoPtr<symmTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.tensorFields_, iter) - { - tensorFields_.insert - ( - iter.key(), - autoPtr<tensorField>::New(*iter(), mapper) - ); - } + this->mapGeneric(rhs, mapper); } template<class Type> Foam::genericFvsPatchField<Type>::genericFvsPatchField ( - const genericFvsPatchField<Type>& ptf -) -: - calculatedFvsPatchField<Type>(ptf), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) -{} - - -template<class Type> -Foam::genericFvsPatchField<Type>::genericFvsPatchField -( - const genericFvsPatchField<Type>& ptf, + const genericFvsPatchField<Type>& rhs, const DimensionedField<Type, surfaceMesh>& iF ) : - calculatedFvsPatchField<Type>(ptf, iF), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) + parent_bctype(rhs, iF), + genericPatchFieldBase(rhs) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +void Foam::genericFvsPatchField<Type>::write(Ostream& os) const +{ + // Handle "value" separately + genericPatchFieldBase::writeGeneric(os, true); + this->writeEntry("value", os); +} + + template<class Type> void Foam::genericFvsPatchField<Type>::autoMap ( const fvPatchFieldMapper& m ) { - calculatedFvsPatchField<Type>::autoMap(m); - - forAllIters(scalarFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(vectorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(sphTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(symmTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(tensorFields_, iter) - { - (*iter)->autoMap(m); - } + parent_bctype::autoMap(m); + this->autoMapGeneric(m); } template<class Type> void Foam::genericFvsPatchField<Type>::rmap ( - const fvsPatchField<Type>& ptf, + const fvsPatchField<Type>& rhs, const labelList& addr ) { - calculatedFvsPatchField<Type>::rmap(ptf, addr); + parent_bctype::rmap(rhs, addr); - const genericFvsPatchField<Type>& dptf = - refCast<const genericFvsPatchField<Type>>(ptf); - - forAllIters(scalarFields_, iter) - { - const auto iter2 = dptf.scalarFields_.cfind(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(vectorFields_, iter) - { - const auto iter2 = dptf.vectorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(sphTensorFields_, iter) + const auto* base = isA<genericPatchFieldBase>(rhs); + if (base) { - const auto iter2 = dptf.sphTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(symmTensorFields_, iter) - { - const auto iter2 = dptf.symmTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(tensorFields_, iter) - { - const auto iter2 = dptf.tensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } + this->rmapGeneric(*base, addr); } } @@ -606,14 +148,14 @@ Foam::genericFvsPatchField<Type>::valueInternalCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFvsPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvsPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -627,14 +169,14 @@ Foam::genericFvsPatchField<Type>::valueBoundaryCoeffs ) const { FatalErrorInFunction - << "cannot be called for a genericFvsPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvsPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -645,14 +187,14 @@ Foam::tmp<Foam::Field<Type>> Foam::genericFvsPatchField<Type>::gradientInternalCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFvsPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); + << "Cannot be called for a genericFvsPatchField"; + + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); return *this; } @@ -662,75 +204,16 @@ Foam::tmp<Foam::Field<Type>> Foam::genericFvsPatchField<Type>::gradientBoundaryCoeffs() const { FatalErrorInFunction - << "cannot be called for a genericFvsPatchField" - " (actual type " << actualTypeName_ << ")" - << "\n on patch " << this->patch().name() - << " of field " << this->internalField().name() - << " in file " << this->internalField().objectPath() - << "\n You are probably trying to solve for a field with a " - "generic boundary condition." - << abort(FatalError); - - return *this; -} + << "Cannot be called for a genericFvsPatchField"; + genericFatalSolveError + ( + this->patch().name(), + this->internalField() + ); + FatalError << abort(FatalError); -template<class Type> -const Foam::word& Foam::genericFvsPatchField<Type>::actualType() const -{ - return actualTypeName_; -} - - -template<class Type> -void Foam::genericFvsPatchField<Type>::write(Ostream& os) const -{ - os.writeEntry("type", actualTypeName_); - - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if (key == "type" || key == "value") - { - // NB: "type" written first, "value" written last - continue; - } - else if - ( - dEntry.isStream() - && dEntry.stream().size() - && dEntry.stream()[0].isWord("nonuniform") - ) - { - if (scalarFields_.found(key)) - { - scalarFields_.cfind(key)()->writeEntry(key, os); - } - else if (vectorFields_.found(key)) - { - vectorFields_.cfind(key)()->writeEntry(key, os); - } - else if (sphTensorFields_.found(key)) - { - sphTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (symmTensorFields_.found(key)) - { - symmTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (tensorFields_.found(key)) - { - tensorFields_.cfind(key)()->writeEntry(key, os); - } - } - else - { - dEntry.write(os); - } - } - - this->writeEntry("value", os); + return *this; } diff --git a/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.H b/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.H index b5d3b942f87126e04a9b85b259960622fcf96986..3fe2a26c57e989661c1c0e8d69a2faa727516dc8 100644 --- a/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.H +++ b/src/genericPatchFields/genericFvsPatchField/genericFvsPatchField.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,7 +43,7 @@ SourceFiles #define genericFvsPatchField_H #include "calculatedFvsPatchField.H" -#include "HashPtrTable.H" +#include "genericPatchFieldBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -57,19 +57,11 @@ namespace Foam template<class Type> class genericFvsPatchField : - public calculatedFvsPatchField<Type> + public calculatedFvsPatchField<Type>, + public genericPatchFieldBase { - // Private Data - - const word actualTypeName_; - - dictionary dict_; - - HashPtrTable<scalarField> scalarFields_; - HashPtrTable<vectorField> vectorFields_; - HashPtrTable<sphericalTensorField> sphTensorFields_; - HashPtrTable<symmTensorField> symmTensorFields_; - HashPtrTable<tensorField> tensorFields_; + //- The parent boundary condition type + typedef calculatedFvsPatchField<Type> parent_bctype; public: @@ -104,12 +96,6 @@ public: const fvPatchFieldMapper& ); - //- Construct as copy - genericFvsPatchField - ( - const genericFvsPatchField<Type>& - ); - //- Construct and return a clone virtual tmp<fvsPatchField<Type>> clone() const { @@ -119,6 +105,9 @@ public: ); } + //- Default copy construct + genericFvsPatchField(const genericFvsPatchField<Type>&) = default; + //- Construct as copy setting internal field reference genericFvsPatchField ( @@ -141,52 +130,38 @@ public: // Member Functions - // Mapping Functions - - //- Map (and resize as needed) from self given a mapping object - virtual void autoMap - ( - const fvPatchFieldMapper& - ); + //- Write + virtual void write(Ostream&) const; - //- Reverse map the given fvsPatchField onto this fvsPatchField - virtual void rmap - ( - const fvsPatchField<Type>&, - const labelList& - ); + // Mapping Functions - // Evaluation Functions + //- Map (and resize as needed) from self given a mapping object + virtual void autoMap(const fvPatchFieldMapper&); - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueInternalCoeffs - ( - const tmp<scalarField>& - ) const; + //- Reverse map the given faPatchField onto this faPatchField + virtual void rmap + ( + const fvsPatchField<Type>&, + const labelList& + ); - //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights - virtual tmp<Field<Type>> valueBoundaryCoeffs - ( - const tmp<scalarField>& - ) const; - //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientInternalCoeffs() const; + // Evaluation Functions - //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField - tmp<Field<Type>> gradientBoundaryCoeffs() const; + //- Fatal + virtual tmp<Field<Type>> + valueInternalCoeffs(const tmp<scalarField>&) const; + //- Fatal + virtual tmp<Field<Type>> + valueBoundaryCoeffs(const tmp<scalarField>&) const; - //- Return the actual type - const word& actualType() const; + //- Fatal + tmp<Field<Type>> gradientInternalCoeffs() const; - //- Write - virtual void write(Ostream&) const; + //- Fatal + tmp<Field<Type>> gradientBoundaryCoeffs() const; }; diff --git a/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.C b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.C new file mode 100644 index 0000000000000000000000000000000000000000..5108533f98860cdcfa1edf885a37b518cd74c0e5 --- /dev/null +++ b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.C @@ -0,0 +1,547 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "genericPatchFieldBase.H" +#include "messageStream.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::genericPatchFieldBase::checkFieldSize +( + const label fieldSize, + const label patchSize, + const word& patchName, + const keyType& key, + const IOobject& io +) const +{ + const bool ok = (fieldSize == patchSize); + + if (!ok) + { + FatalIOErrorInFunction(dict_) + << "\n size of field " << key + << " (" << fieldSize << ") != patch size (" << patchSize << ')' + << "\n on patch " << patchName + << " of field " << io.name() << " in file " + << io.objectPath() << nl + << exit(FatalIOError); + } + + return ok; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::genericPatchFieldBase::genericPatchFieldBase +( + const dictionary& dict +) +: + actualTypeName_(dict.get<word>("type")), + dict_(dict) +{} + + +Foam::genericPatchFieldBase::genericPatchFieldBase +( + const Foam::zero, + const genericPatchFieldBase& rhs +) +: + actualTypeName_(rhs.actualTypeName_), + dict_(rhs.dict_) +{} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::genericPatchFieldBase::genericFatalSolveError +( + const word& patchName, + const IOobject& io +) const +{ + FatalError + << " (actual type " << actualTypeName_ << ')' + << "\n on patch " << patchName + << " of field " << io.name() << " in file " << io.objectPath() << nl + << nl + << " You are probably trying to solve for a field with a " + "generic boundary condition." << nl; +} + + +void Foam::genericPatchFieldBase::reportMissingEntry +( + const word& entryName, + const word& patchName, + const IOobject& io +) const +{ + FatalIOErrorInFunction(dict_) + << nl + << " Missing required '" << entryName << "' entry" + << " on patch " << patchName + << " of field " << io.name() << " in file " << io.objectPath() << nl + << " (Actual type " << actualTypeName_ << ')' << nl << nl + << " Please add the '" << entryName << "' entry to the" + " write function of the user-defined boundary-condition" << nl + << exit(FatalIOError); +} + + +void Foam::genericPatchFieldBase::processGeneric +( + const label patchSize, + const word& patchName, + const IOobject& io, + const bool separateValue +) +{ + for (const entry& dEntry : dict_) + { + const keyType& key = dEntry.keyword(); + + if (key == "type" || (separateValue && key == "value")) + { + // "type" and possibly "value" handled differently + } + else + { + processEntry(dEntry, patchSize, patchName, io); + } + } +} + + +bool Foam::genericPatchFieldBase::processEntry +( + const entry& dEntry, + const label patchSize, + const word& patchName, + const IOobject& io +) +{ + if (!dEntry.isStream()) + { + return false; + } + + const keyType& key = dEntry.keyword(); + ITstream& is = dEntry.stream(); + + if (is.empty()) + { + return false; + } + + #undef FIELDSIZE_CHECK + #define FIELDSIZE_CHECK(fieldLen) \ + checkFieldSize(fieldLen, patchSize, patchName, key, io) + + + // First token + token tok(is); + + if (tok.isWord("nonuniform")) + { + is >> tok; + + if (tok.isLabel(0)) + { + // For v2006 and earlier, could have a plain untyped 0 + // without a compound type. + // Just treat as scalar and hope for the best. + scalarFields_.insert(key, autoPtr<scalarField>::New()); + } + else if (!tok.isCompound()) + { + FatalIOErrorInFunction(dict_) + << "\n non-compound token following 'nonuniform'" + << "\n on patch " << patchName << " field " + << io.name() << " in file " + << io.objectPath() << nl + << exit(FatalIOError); + return false; + } + else if + ( + tok.compoundToken().type() + == token::Compound<List<scalar>>::typeName + ) + { + auto fPtr = autoPtr<scalarField>::New(); + + fPtr->transfer + ( + dynamicCast<token::Compound<List<scalar>>> + ( + tok.transferCompoundToken(is) + ) + ); + + if (!FIELDSIZE_CHECK(fPtr->size())) + { + return false; + } + + scalarFields_.insert(key, fPtr); + } + else if + ( + tok.compoundToken().type() + == token::Compound<List<vector>>::typeName + ) + { + auto fPtr = autoPtr<vectorField>::New(); + + fPtr->transfer + ( + dynamicCast<token::Compound<List<vector>>> + ( + tok.transferCompoundToken(is) + ) + ); + + if (!FIELDSIZE_CHECK(fPtr->size())) + { + return false; + } + vectorFields_.insert(key, fPtr); + } + else if + ( + tok.compoundToken().type() + == token::Compound<List<sphericalTensor>>::typeName + ) + { + auto fPtr = autoPtr<sphericalTensorField>::New(); + + fPtr->transfer + ( + dynamicCast<token::Compound<List<sphericalTensor>>> + ( + tok.transferCompoundToken(is) + ) + ); + + if (!FIELDSIZE_CHECK(fPtr->size())) + { + return false; + } + + sphTensorFields_.insert(key, fPtr); + } + else if + ( + tok.compoundToken().type() + == token::Compound<List<symmTensor>>::typeName + ) + { + auto fPtr = autoPtr<symmTensorField>::New(); + + fPtr->transfer + ( + dynamicCast<token::Compound<List<symmTensor>>> + ( + tok.transferCompoundToken(is) + ) + ); + + if (!FIELDSIZE_CHECK(fPtr->size())) + { + return false; + } + + symmTensorFields_.insert(key, fPtr); + } + else if + ( + tok.compoundToken().type() + == token::Compound<List<tensor>>::typeName + ) + { + auto fPtr = autoPtr<tensorField>::New(); + + fPtr->transfer + ( + dynamicCast<token::Compound<List<tensor>>> + ( + tok.transferCompoundToken(is) + ) + ); + + if (!FIELDSIZE_CHECK(fPtr->size())) + { + return false; + } + + tensorFields_.insert(key, fPtr); + } + else + { + FatalIOErrorInFunction(dict_) + << "\n unsupported compound " << tok.compoundToken() + << "\n on patch " << patchName << " of field " + << io.name() << " in file " + << io.objectPath() << nl + << exit(FatalIOError); + return false; + } + } + else if (tok.isWord("uniform")) + { + is >> tok; + + if (!tok.isPunctuation()) + { + scalarFields_.insert + ( + key, + autoPtr<scalarField>::New(patchSize, tok.number()) + ); + } + else + { + // Read vector-space as list of scalars + is.putBack(tok); + + scalarList list(is); + + if (list.size() == vector::nComponents) + { + vector vs(list[0], list[1], list[2]); + + vectorFields_.insert + ( + key, + autoPtr<vectorField>::New + ( + patchSize, + vs + ) + ); + } + else if (list.size() == sphericalTensor::nComponents) + { + sphericalTensor vs(list[0]); + + sphTensorFields_.insert + ( + key, + autoPtr<sphericalTensorField>::New + ( + patchSize, + vs + ) + ); + } + else if (list.size() == symmTensor::nComponents) + { + symmTensor vs + ( + list[0], list[1], list[2], + list[3], list[4], + list[5] + ); + + symmTensorFields_.insert + ( + key, + autoPtr<symmTensorField>::New + ( + patchSize, + vs + ) + ); + } + else if (list.size() == tensor::nComponents) + { + tensor vs + ( + list[0], list[1], list[2], + list[3], list[4], list[5], + list[6], list[7], list[8] + ); + + tensorFields_.insert + ( + key, + autoPtr<tensorField>::New + ( + patchSize, + vs + ) + ); + } + else + { + FatalIOErrorInFunction(dict_) + << "\n unrecognised native type " << flatOutput(list) + << "\n on patch " << patchName << " of field " + << io.name() << " in file " + << io.objectPath() << nl + << exit(FatalIOError); + return false; + } + } + } + + #undef FIELDSIZE_CHECK + + return true; +} + + +void Foam::genericPatchFieldBase::putEntry +( + const entry& e, + Ostream& os +) const +{ + const keyType& key = e.keyword(); + + if + ( + e.isStream() + && e.stream().size() + && e.stream()[0].isWord("nonuniform") + ) + { + if (scalarFields_.found(key)) + { + scalarFields_.cfind(key)()->writeEntry(key, os); + } + else if (vectorFields_.found(key)) + { + vectorFields_.cfind(key)()->writeEntry(key, os); + } + else if (sphTensorFields_.found(key)) + { + sphTensorFields_.cfind(key)()->writeEntry(key, os); + } + else if (symmTensorFields_.found(key)) + { + symmTensorFields_.cfind(key)()->writeEntry(key, os); + } + else if (tensorFields_.found(key)) + { + tensorFields_.cfind(key)()->writeEntry(key, os); + } + } + else + { + e.write(os); + } +} + + +void Foam::genericPatchFieldBase::writeGeneric +( + Ostream& os, + const bool separateValue +) const +{ + os.writeEntry("type", actualTypeName_); + + for (const entry& dEntry : dict_) + { + const keyType& key = dEntry.keyword(); + + if (key == "type" || (separateValue && key == "value")) + { + // NB: "type" written first, "value" possibly separately + } + else + { + putEntry(dEntry, os); + } + } +} + + +void Foam::genericPatchFieldBase::rmapGeneric +( + const genericPatchFieldBase& rhs, + const labelList& addr +) +{ + forAllIters(scalarFields_, iter) + { + const auto iter2 = rhs.scalarFields_.cfind(iter.key()); + + if (iter2.found()) + { + (*iter)->rmap(*iter2(), addr); + } + } + + forAllIters(vectorFields_, iter) + { + const auto iter2 = rhs.vectorFields_.cfind(iter.key()); + + if (iter2.found()) + { + (*iter)->rmap(*iter2(), addr); + } + } + + forAllIters(sphTensorFields_, iter) + { + const auto iter2 = rhs.sphTensorFields_.cfind(iter.key()); + + if (iter2.found()) + { + (*iter)->rmap(*iter2(), addr); + } + } + + forAllIters(symmTensorFields_, iter) + { + const auto iter2 = rhs.symmTensorFields_.cfind(iter.key()); + + if (iter2.found()) + { + (*iter)->rmap(*iter2(), addr); + } + } + + forAllIters(tensorFields_, iter) + { + const auto iter2 = rhs.tensorFields_.find(iter.key()); + + if (iter2.found()) + { + (*iter)->rmap(*iter2(), addr); + } + } +} + + +// ************************************************************************* // diff --git a/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.H b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.H new file mode 100644 index 0000000000000000000000000000000000000000..f22346c7de1b71e32d258d3c3f1498f5798a23b8 --- /dev/null +++ b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBase.H @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::genericPatchFieldBase + +Description + Generic infrastructure for reading/writing unknown patch types. + +SourceFiles + genericPatchFieldBase.C + genericPatchFieldBaseTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef genericPatchFieldBase_H +#define genericPatchFieldBase_H + +#include "dictionary.H" +#include "primitiveFields.H" +#include "HashPtrTable.H" +#include "IOobject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class genericPatchFieldBase Declaration +\*---------------------------------------------------------------------------*/ + +class genericPatchFieldBase +{ + // Private Member Functions + + bool checkFieldSize + ( + const label fieldSize, + const label patchSize, + const word& patchName, + const keyType& key, + const IOobject& io + ) const; + + +protected: + + // Protected Data + + //- The non-generic patch name + word actualTypeName_; + + dictionary dict_; + + HashPtrTable<scalarField> scalarFields_; + HashPtrTable<vectorField> vectorFields_; + HashPtrTable<sphericalTensorField> sphTensorFields_; + HashPtrTable<symmTensorField> symmTensorFields_; + HashPtrTable<tensorField> tensorFields_; + + + // Protected Member Functions + + //- Add error message to FatalError about solving with + //- generic condition + void genericFatalSolveError + ( + const word& patchName, + const IOobject& io + ) const; + + //- FatalError for missing entry + void reportMissingEntry + ( + const word& entryName, + const word& patchName, + const IOobject& io + ) const; + + void processGeneric + ( + const label patchSize, + const word& patchName, + const IOobject& io, + const bool separateValue + ); + + bool processEntry + ( + const entry& dEntry, + const label patchSize, + const word& patchName, + const IOobject& io + ); + + //- Write a single entry, with lookup of hashed values + void putEntry(const entry& e, Ostream& os) const; + + //- Write all generic entries from dictionary, + //- optionally treating the "value" entry separately + void writeGeneric(Ostream& os, const bool separateValue) const; + + //- Implementation for construct with mapper + template<class MapperType> + void mapGeneric + ( + const genericPatchFieldBase& rhs, + const MapperType& mapper + ); + + //- Implementation for autoMap of self given a mapping object + template<class MapperType> + void autoMapGeneric(const MapperType& mapper); + + //- Implementation for reverse map given patch field onto this + //- patch field + void rmapGeneric + ( + const genericPatchFieldBase& rhs, + const labelList& addr + ); + + + // Constructors + + //- Partial copy construct. Only copy type and dictionary + genericPatchFieldBase(const Foam::zero, const genericPatchFieldBase&); + + +public: + + // Constructors + + //- Default construct, generally not useful. + genericPatchFieldBase() = default; + + //- Copy construct + genericPatchFieldBase(const genericPatchFieldBase&) = default; + + //- Move construct + genericPatchFieldBase(genericPatchFieldBase&&) = default; + + //- Initialize from dictionary + explicit genericPatchFieldBase(const dictionary& dict); + + + // Member Functions + + //- The actual patch type + const word& actualType() const noexcept + { + return actualTypeName_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "genericPatchFieldBaseTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBaseTemplates.C b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBaseTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..9b1041ab456f71726428ea16daca5b24f07714f9 --- /dev/null +++ b/src/genericPatchFields/genericPatchFieldBase/genericPatchFieldBaseTemplates.C @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "genericPatchFieldBase.H" + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class MapperType> +void Foam::genericPatchFieldBase::mapGeneric +( + const genericPatchFieldBase& rhs, + const MapperType& mapper +) +{ + forAllConstIters(rhs.scalarFields_, iter) + { + scalarFields_.insert + ( + iter.key(), + autoPtr<scalarField>::New(*iter(), mapper) + ); + } + + forAllConstIters(rhs.vectorFields_, iter) + { + vectorFields_.insert + ( + iter.key(), + autoPtr<vectorField>::New(*iter(), mapper) + ); + } + + forAllConstIters(rhs.sphTensorFields_, iter) + { + sphTensorFields_.insert + ( + iter.key(), + autoPtr<sphericalTensorField>::New(*iter(), mapper) + ); + } + + forAllConstIters(rhs.symmTensorFields_, iter) + { + symmTensorFields_.insert + ( + iter.key(), + autoPtr<symmTensorField>::New(*iter(), mapper) + ); + } + + forAllConstIters(rhs.tensorFields_, iter) + { + tensorFields_.insert + ( + iter.key(), + autoPtr<tensorField>::New(*iter(), mapper) + ); + } +} + + +template<class MapperType> +void Foam::genericPatchFieldBase::autoMapGeneric +( + const MapperType& mapper +) +{ + forAllIters(scalarFields_, iter) + { + (*iter)->autoMap(mapper); + } + + forAllIters(vectorFields_, iter) + { + (*iter)->autoMap(mapper); + } + + forAllIters(sphTensorFields_, iter) + { + (*iter)->autoMap(mapper); + } + + forAllIters(symmTensorFields_, iter) + { + (*iter)->autoMap(mapper); + } + + forAllIters(tensorFields_, iter) + { + (*iter)->autoMap(mapper); + } +} + + +// ************************************************************************* // diff --git a/src/genericPatchFields/genericPointPatchField/genericPointPatchField.C b/src/genericPatchFields/genericPointPatchField/genericPointPatchField.C index a4ccaecb18916040a32b275addc51320058284b0..7352d82c5cdc4e78f00cea06c134726592f10ffe 100644 --- a/src/genericPatchFields/genericPointPatchField/genericPointPatchField.C +++ b/src/genericPatchFields/genericPointPatchField/genericPointPatchField.C @@ -38,9 +38,13 @@ Foam::genericPointPatchField<Type>::genericPointPatchField const DimensionedField<Type, pointMesh>& iF ) : - calculatedPointPatchField<Type>(p, iF) + parent_bctype(p, iF) { - NotImplemented; + FatalErrorInFunction + << "Trying to construct genericPointPatchField on patch " + << this->patch().name() + << " of field " << this->internalField().name() << nl + << abort(FatalError); } @@ -52,468 +56,77 @@ Foam::genericPointPatchField<Type>::genericPointPatchField const dictionary& dict ) : - calculatedPointPatchField<Type>(p, iF, dict), - actualTypeName_(dict.get<word>("type")), - dict_(dict) + parent_bctype(p, iF, dict), + genericPatchFieldBase(dict) { const label patchSize = this->size(); + const word& patchName = this->patch().name(); + const IOobject& io = this->internalField(); - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if - ( - key == "type" - || !dEntry.isStream() || dEntry.stream().empty() - ) - { - continue; - } - - - ITstream& is = dEntry.stream(); - - // Read first token - token firstToken(is); - - if (firstToken.isWord("nonuniform")) - { - token fieldToken(is); - - if (!fieldToken.isCompound()) - { - if - ( - fieldToken.isLabel() - && fieldToken.labelToken() == 0 - ) - { - scalarFields_.insert(key, autoPtr<scalarField>::New()); - } - else - { - FatalIOErrorInFunction(dict) - << "\n token following 'nonuniform' " - "is not a compound" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<scalar>>::typeName - ) - { - auto fPtr = autoPtr<scalarField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<scalar>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - scalarFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<vector>>::typeName - ) - { - auto fPtr = autoPtr<vectorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<vector>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - vectorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<sphericalTensor>>::typeName - ) - { - auto fPtr = autoPtr<sphericalTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<sphericalTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - sphTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<symmTensor>>::typeName - ) - { - auto fPtr = autoPtr<symmTensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<symmTensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - symmTensorFields_.insert(key, fPtr); - } - else if - ( - fieldToken.compoundToken().type() - == token::Compound<List<tensor>>::typeName - ) - { - auto fPtr = autoPtr<tensorField>::New(); - - fPtr->transfer - ( - dynamicCast<token::Compound<List<tensor>>> - ( - fieldToken.transferCompoundToken(is) - ) - ); - - if (fPtr->size() != patchSize) - { - FatalIOErrorInFunction(dict) - << "\n size of field " << key - << " (" << fPtr->size() << ')' - << " is not the same size as the patch (" - << patchSize << ')' - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - - tensorFields_.insert(key, fPtr); - } - else - { - FatalIOErrorInFunction(dict) - << "\n compound " << fieldToken.compoundToken() - << " not supported" - << "\n on patch " << this->patch().name() - << " of field " - << this->internalField().name() - << " in file " - << this->internalField().objectPath() << nl - << exit(FatalIOError); - } - } - } + // No separate "value" + processGeneric(patchSize, patchName, io, false); } template<class Type> Foam::genericPointPatchField<Type>::genericPointPatchField ( - const genericPointPatchField<Type>& ptf, + const genericPointPatchField<Type>& rhs, const pointPatch& p, const DimensionedField<Type, pointMesh>& iF, const pointPatchFieldMapper& mapper ) : - calculatedPointPatchField<Type>(ptf, p, iF, mapper), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_) + parent_bctype(rhs, p, iF, mapper), + genericPatchFieldBase(zero{}, rhs) { - forAllConstIters(ptf.scalarFields_, iter) - { - scalarFields_.insert - ( - iter.key(), - autoPtr<scalarField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.vectorFields_, iter) - { - vectorFields_.insert - ( - iter.key(), - autoPtr<vectorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.sphTensorFields_, iter) - { - sphTensorFields_.insert - ( - iter.key(), - autoPtr<sphericalTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.symmTensorFields_, iter) - { - symmTensorFields_.insert - ( - iter.key(), - autoPtr<symmTensorField>::New(*iter(), mapper) - ); - } - - forAllConstIters(ptf.tensorFields_, iter) - { - tensorFields_.insert - ( - iter.key(), - autoPtr<tensorField>::New(*iter(), mapper) - ); - } + this->mapGeneric(rhs, mapper); } template<class Type> Foam::genericPointPatchField<Type>::genericPointPatchField ( - const genericPointPatchField<Type>& ptf, + const genericPointPatchField<Type>& rhs, const DimensionedField<Type, pointMesh>& iF ) : - calculatedPointPatchField<Type>(ptf, iF), - actualTypeName_(ptf.actualTypeName_), - dict_(ptf.dict_), - scalarFields_(ptf.scalarFields_), - vectorFields_(ptf.vectorFields_), - sphTensorFields_(ptf.sphTensorFields_), - symmTensorFields_(ptf.symmTensorFields_), - tensorFields_(ptf.tensorFields_) + parent_bctype(rhs, iF), + genericPatchFieldBase(rhs) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class Type> +void Foam::genericPointPatchField<Type>::write(Ostream& os) const +{ + // No separate treatment for "value" + genericPatchFieldBase::writeGeneric(os, false); +} + + template<class Type> void Foam::genericPointPatchField<Type>::autoMap ( const pointPatchFieldMapper& m ) { - forAllIters(scalarFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(vectorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(sphTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(symmTensorFields_, iter) - { - (*iter)->autoMap(m); - } - - forAllIters(tensorFields_, iter) - { - (*iter)->autoMap(m); - } + this->autoMapGeneric(m); } template<class Type> void Foam::genericPointPatchField<Type>::rmap ( - const pointPatchField<Type>& ptf, + const pointPatchField<Type>& rhs, const labelList& addr ) { - const genericPointPatchField<Type>& dptf = - refCast<const genericPointPatchField<Type>>(ptf); - - forAllIters(scalarFields_, iter) - { - const auto iter2 = dptf.scalarFields_.cfind(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(vectorFields_, iter) + const auto* base = isA<genericPatchFieldBase>(rhs); + if (base) { - const auto iter2 = dptf.vectorFields_.cfind(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(sphTensorFields_, iter) - { - const auto iter2 = dptf.sphTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(symmTensorFields_, iter) - { - const auto iter2 = dptf.symmTensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } - - forAllIters(tensorFields_, iter) - { - const auto iter2 = dptf.tensorFields_.find(iter.key()); - - if (iter2.found()) - { - (*iter)->rmap(*iter2(), addr); - } - } -} - - -template<class Type> -const Foam::word& Foam::genericPointPatchField<Type>::actualType() const -{ - return actualTypeName_; -} - - -template<class Type> -void Foam::genericPointPatchField<Type>::write(Ostream& os) const -{ - os.writeEntry("type", actualTypeName_); - - for (const entry& dEntry : dict_) - { - const keyType& key = dEntry.keyword(); - - if (key == "type") - { - // NB: "type" written first, no special treatment for "value" - continue; - } - else if - ( - dEntry.isStream() - && dEntry.stream().size() - && dEntry.stream()[0].isWord("nonuniform") - ) - { - if (scalarFields_.found(key)) - { - scalarFields_.cfind(key)()->writeEntry(key, os); - } - else if (vectorFields_.found(key)) - { - vectorFields_.cfind(key)()->writeEntry(key, os); - } - else if (sphTensorFields_.found(key)) - { - sphTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (symmTensorFields_.found(key)) - { - symmTensorFields_.cfind(key)()->writeEntry(key, os); - } - else if (tensorFields_.found(key)) - { - tensorFields_.cfind(key)()->writeEntry(key, os); - } - } - else - { - dEntry.write(os); - } + this->rmapGeneric(*base, addr); } } diff --git a/src/genericPatchFields/genericPointPatchField/genericPointPatchField.H b/src/genericPatchFields/genericPointPatchField/genericPointPatchField.H index 065a1751577dbca347b6028104f144fc358ca3f2..59b3be11f4b11bf0fbb24dd091a06a877ecff223 100644 --- a/src/genericPatchFields/genericPointPatchField/genericPointPatchField.H +++ b/src/genericPatchFields/genericPointPatchField/genericPointPatchField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,7 +40,7 @@ SourceFiles #define genericPointPatchField_H #include "calculatedPointPatchField.H" -#include "HashPtrTable.H" +#include "genericPatchFieldBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -54,19 +54,11 @@ namespace Foam template<class Type> class genericPointPatchField : - public calculatedPointPatchField<Type> + public calculatedPointPatchField<Type>, + public genericPatchFieldBase { - // Private Data - - const word actualTypeName_; - - dictionary dict_; - - HashPtrTable<scalarField> scalarFields_; - HashPtrTable<vectorField> vectorFields_; - HashPtrTable<sphericalTensorField> sphTensorFields_; - HashPtrTable<symmTensorField> symmTensorFields_; - HashPtrTable<tensorField> tensorFields_; + //- The parent boundary condition type + typedef calculatedPointPatchField<Type> parent_bctype; public: @@ -113,6 +105,9 @@ public: ); } + //- Default copy construct + genericPointPatchField(const genericPointPatchField<Type>&) = default; + //- Construct as copy setting internal field reference genericPointPatchField ( @@ -139,27 +134,21 @@ public: // Member Functions - // Mapping Functions - - //- Map (and resize as needed) from self given a mapping object - virtual void autoMap - ( - const pointPatchFieldMapper& - ); + //- Write + virtual void write(Ostream&) const; - //- Reverse map the given pointPatchField onto this pointPatchField - virtual void rmap - ( - const pointPatchField<Type>&, - const labelList& - ); + // Mapping Functions - //- Return the actual type - const word& actualType() const; + //- Map (and resize as needed) from self given a mapping object + virtual void autoMap(const pointPatchFieldMapper&); - //- Write - virtual void write(Ostream&) const; + //- Reverse map the given pointPatchField onto this pointPatchField + virtual void rmap + ( + const pointPatchField<Type>&, + const labelList& + ); };