From c9d1f741ce392acdab730544e7800c3937b0df12 Mon Sep 17 00:00:00 2001 From: Kutalmis Bercin <kutalmis.bercin@esi-group.com> Date: Mon, 30 Oct 2023 10:12:15 +0000 Subject: [PATCH] ENH: createROMfields: new reduced-order model utility to reconstruct fields --- .../miscellaneous/createROMfields/Make/files | 7 + .../createROMfields/Make/options | 7 + .../createROMfields/ROMmodels/DMD/DMD.C | 178 ++++++++++++++ .../createROMfields/ROMmodels/DMD/DMD.H | 232 ++++++++++++++++++ .../createROMfields/ROMmodels/DMD/DMDImpl.C | 106 ++++++++ .../ROMmodels/ROMmodel/ROMmodel.C | 59 +++++ .../ROMmodels/ROMmodel/ROMmodel.H | 163 ++++++++++++ .../ROMmodels/ROMmodel/ROMmodelNew.C | 60 +++++ .../createROMfields/createROMfields.C | 141 +++++++++++ .../createROMfields/readFields.H | 189 ++++++++++++++ etc/caseDicts/annotated/ROMfieldsDict | 59 +++++ 11 files changed, 1201 insertions(+) create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/Make/files create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/Make/options create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.C create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.H create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMDImpl.C create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.C create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.H create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodelNew.C create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/createROMfields.C create mode 100644 applications/utilities/postProcessing/miscellaneous/createROMfields/readFields.H create mode 100644 etc/caseDicts/annotated/ROMfieldsDict diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/files b/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/files new file mode 100644 index 00000000000..621a2bb0673 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/files @@ -0,0 +1,7 @@ +ROMmodels/ROMmodel/ROMmodel.C +ROMmodels/ROMmodel/ROMmodelNew.C +ROMmodels/DMD/DMD.C + +createROMfields.C + +EXE = $(FOAM_APPBIN)/createROMfields diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/options b/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/options new file mode 100644 index 00000000000..d27c95d033d --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.C b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.C new file mode 100644 index 00000000000..5f20cb392ab --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.C @@ -0,0 +1,178 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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 "DMD.H" +#include "readFields.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace ROMmodels +{ + defineTypeNameAndDebug(DMD, 0); + addToRunTimeSelectionTable(ROMmodel, DMD, dictionary); +} +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Implementation +#include "DMDImpl.C" + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::wordList Foam::ROMmodels::DMD::modeNames(const word& modeType) const +{ + wordList modeNames(modes_.size()); + for (const label modei : modes_) + { + modeNames[modei] = + word + ( + "mode"+modeType+"_"+name(modei)+"_"+fieldName_+"_"+objectName_ + ); + } + return modeNames; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::ROMmodels::DMD::DMD +( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times +) +: + ROMmodel(runTime, mesh, dict, times), + fieldName_(), + objectName_(), + deltaT_(), + time_(), + startTime_(), + modes_(), + dims_(), + amps_(), + evals_() +{ + read(dict); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +bool Foam::ROMmodels::DMD::read(const dictionary& dict) +{ + dict.readEntry("field", fieldName_); + dict.readEntry("object", objectName_); + dict.readEntry("deltaT", deltaT_); + dict.readEntry("time", time_); + dict.readIfPresent("startTime", startTime_); + + if (deltaT_ < SMALL || time_ < SMALL || startTime_ < 0) + { + FatalIOErrorInFunction(dict) + << "Out-of-range values for " << nl + << tab << "deltaT: " << deltaT_ + << tab << "time: " << time_ << nl + << tab << "startTime: " << startTime_ << nl + << exit(FatalIOError); + } + + dict.readEntry("modes", modes_); + + if (modes_.empty()) + { + FatalIOErrorInFunction(dict) + << "Empty list for the mode indices " << nl + << tab << "modes: " << modes_ << nl + << exit(FatalIOError); + } + + dims_.reset(dict.get<dimensionSet>("dimensions")); + + // Load complex amplitudes and eigenvalues + dict.readEntry("amplitudes", amps_); + dict.readEntry("eigenvalues", evals_); + + if ((amps_.size() != modes_.size()) || (evals_.size() != modes_.size())) + { + FatalIOErrorInFunction(dict) + << "Inconsistent input sizes for " + << tab << "modes: " << modes_.size() << nl + << tab << "amplitudes: " << amps_.size() << nl + << tab << "eigenvalues: " << evals_.size() << nl + << exit(FatalIOError); + } + + // Create mode-field names + const wordList modeReNames(modeNames(word("Re"))); + const wordList modeImNames(modeNames(word("Im"))); + + // Load mode fields + runTime_.setTime(time_, 0); + + readFieldsHandler(mesh_).execute(modeReNames); + readFieldsHandler(mesh_).execute(modeImNames); + + return true; +} + + +bool Foam::ROMmodels::DMD::createAndWrite() +{ + do + { + #undef doLocalCode + #define doLocalCode(InputType) \ + { \ + createAndWriteImpl<VolumeField<InputType>>(); \ + createAndWriteImpl<SurfaceField<InputType>>(); \ + } + + doLocalCode(scalar); + doLocalCode(vector); + doLocalCode(sphericalTensor); + doLocalCode(symmTensor); + doLocalCode(tensor); + + #undef doInnerLocalCode + #undef doLocalCode + } + while (false); + + return true; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.H b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.H new file mode 100644 index 00000000000..75a49acb7b6 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.H @@ -0,0 +1,232 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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::ROMmodels::DMD + +Description + Field creation model using the streaming total dynamic mode + decomposition method (STDMD). + + The governing equations of the field creation are as follows: + + \f[ + \mathbf{x}_\tau \approx + \tilde{\mathbf{x}_\tau} = + \left( \sum_{i=0}^{N-1} \phi_i \alpha_i v_i^\tau \right)_{real} + \f] + + with + + \f[ + \tau = \frac{t - t_o}{\Delta t} + \f] + + where: + + \vartable + \mathbf{x} | Field snapshot at time t + \tilde{\mathbf{x}} | Reconstructed field snapshot at time t (complex) + N | Number of modes + i | Mode index + \tau | Nondimensional time + t | Time [s] + t_o | Start time (of mode decomposition calculations) [s] + \Delta t | Time-step size of mode decomposition [s] + \phi | Mode (complex) + \alpha | Mode amplitude (complex) + v | Mode eigenvalue (complex) + \endvartable + + References: + \verbatim + Governing equations (tag:K): + Kiewat, M. (2019). + Streaming modal decomposition approaches for vehicle aerodynamics. + PhD thesis. Munich: Technical University of Munich. + URL:mediatum.ub.tum.de/doc/1482652/1482652.pdf + \endverbatim + + Operands: + \table + Operand | Type | Location + input | {vol,surface}\<Type\>Field | \<time\>/\<inpField\> + output file | - | - + output field | {vol,surface}\<Type\>Field | \<time\>/\<outField\> + \endtable + + where \c \<Type\>=Scalar/Vector/SphericalTensor/SymmTensor/Tensor. + +Usage + Minimal example by using \c system/ROMfieldsDict: + \verbatim + // Mandatory entries + field <word>; + object <word>; + deltaT <scalar>; + time <scalar>; + modes <labelList>; + amplitudes <complexList>; + eigenvalues <complexList>; + + // Optional entries + startTime <scalar>; + dimensions <dimensionSet>; + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + field | Name of reconstructed field | word | yes | - + object | Name of operand function object | word | yes | - + deltaT | Time-step size of mode decomposition | scalar | yes | - + time | Time instant where modes are located | scalar | yes | - + modes | List of mode indices | labelList | yes | - + amplitudes | Amplitude coefficients | complexList | yes | - + eigenvalues | Eigenvalues | complexList | yes | - + startTime | Start time for mode-information collection | scalar | no | 0 + dimensions | Dimensions of reconstructed fields | dimensionSet | no | - + \endtable + +SourceFiles + DMD.C + DMDImpl.C + +\*---------------------------------------------------------------------------*/ + +#ifndef ROMmodels_DMD_H +#define ROMmodels_DMD_H + +#include "ROMmodels/ROMmodel/ROMmodel.H" +#include "dimensionSet.H" +#include "complex.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace ROMmodels +{ +/*---------------------------------------------------------------------------*\ + Class DMD Declaration +\*---------------------------------------------------------------------------*/ + +class DMD +: + public ROMmodel +{ + // Private Typedefs + + typedef List<complex> complexList; + + + // Private Data + + //- Name of reconstructed field + word fieldName_; + + //- Name of operand function object + word objectName_; + + //- Time-step size of mode decomposition (not that of the simulation) + scalar deltaT_; + + //- Time instant where modes are located + scalar time_; + + //- Start time for mode-information collection + scalar startTime_; + + //- List of mode indices + labelList modes_; + + //- Dimensions of reconstructed fields + dimensionSet dims_; + + //- Amplitude coefficients + complexList amps_; + + //- Eigenvalues + complexList evals_; + + + // Private Member Functions + + //- Return names of mode fields + wordList modeNames(const word& modeType) const; + + //- Implementation for creating and writing fields + template<class GeoType> + bool createAndWriteImpl() const; + + +public: + + //- Runtime type information + TypeName("DMD"); + + + // Constructors + + //- Construct from components + DMD + ( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times + ); + + //- No copy construct + DMD(const DMD&) = delete; + + //- No copy assignment + void operator=(const DMD&) = delete; + + + //- Destructor + virtual ~DMD() = default; + + + // Member Functions + + //- Read model settings + virtual bool read(const dictionary& dict); + + //- Create and write fields + virtual bool createAndWrite(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace ROMmodels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMDImpl.C b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMDImpl.C new file mode 100644 index 00000000000..dd60c898759 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMDImpl.C @@ -0,0 +1,106 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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 "volFields.H" +#include "surfaceFields.H" +#include "zeroGradientFvPatchFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class GeoType> +bool Foam::ROMmodels::DMD::createAndWriteImpl() const +{ + typedef typename GeoType::value_type Type; + + const wordList modeReNames(modeNames(word("Re"))); + const wordList modeImNames(modeNames(word("Im"))); + + for (const label i : modes_) + { + const auto* modeRePtr = mesh_.cfindObject<GeoType>(modeReNames[i]); + + if (!modeRePtr) return false; + + const auto* modeImPtr = mesh_.cfindObject<GeoType>(modeImNames[i]); + + if (!modeImPtr) return false; + } + + + forAll(times_, timei) + { + runTime_.setTime(times_[timei], timei); + + Info<< "\nTime = " << runTime_.timeName() << endl; + + // Calculate the eigenvalue exponent corresponding to specified time + const scalar k = (times_[timei].value() - startTime_)/deltaT_; + + GeoType reconstructedFld + ( + IOobject + ( + IOobject::scopedName(fieldName_, "reconstructed"), + runTime_.timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh_, + dimensioned<Type>(dimless, Zero), + fvPatchFieldBase::zeroGradientType() + ); + + forAll(modes_, i) + { + const label j = modes_[i]; + const auto& modeRe = mesh_.lookupObject<GeoType>(modeReNames[j]); + const auto& modeIm = mesh_.lookupObject<GeoType>(modeImNames[j]); + + const complex evalk(pow(evals_[i], k)); + + // (K:Eq. 84) + reconstructedFld += + ( + (modeRe*amps_[i].Re() - modeIm*amps_[i].Im())*evalk.Re() + - (modeRe*amps_[i].Im() + modeIm*amps_[i].Re())*evalk.Im() + ); + } + + reconstructedFld.correctBoundaryConditions(); + + reconstructedFld.dimensions().reset(dims_); + + reconstructedFld.write(); + } + + return true; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.C b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.C new file mode 100644 index 00000000000..47f02798364 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.C @@ -0,0 +1,59 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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 "ROMmodel.H" +#include "Time.H" +#include "fvMesh.H" +#include "dictionary.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(ROMmodel, 0); + defineRunTimeSelectionTable(ROMmodel, dictionary); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::ROMmodel::ROMmodel +( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times +) +: + runTime_(runTime), + mesh_(mesh), + dict_(dict), + times_(times) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.H b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.H new file mode 100644 index 00000000000..dd973f67055 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodel.H @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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/>. + +Namespace + Foam::ROMmodels + +Description + A namespace for various implementations of + reduced-order (ROM) field creation models. + +Class + Foam::ROMmodel + +Description + Abstract base class for reduced-order models + to handle specific model characteristics. + +SourceFiles + ROMmodel.C + ROMmodelNew.C + +\*---------------------------------------------------------------------------*/ + +#ifndef Foam_ROMmodel_H +#define Foam_ROMmodel_H + +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward Declarations +class Time; +class fvMesh; +class dictionary; +class instant; +typedef class List<instant> instantList; + +/*---------------------------------------------------------------------------*\ + Class ROMmodel Declaration +\*---------------------------------------------------------------------------*/ + +class ROMmodel +{ +protected: + + // Protected Data + + //- Reference to the Time + // Need non-const access to use setTime + Time& runTime_; + + //- Reference to the fvMesh + // Need non-const access to use readFieldsHandler + fvMesh& mesh_; + + //- Const reference to the dictionary + const dictionary& dict_; + + //- Const reference to field times + const instantList& times_; + + +public: + + //- Runtime type information + TypeName("ROMmodel"); + + + // Declare runtime constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + ROMmodel, + dictionary, + ( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times + ), + (runTime, mesh, dict, times) + ); + + + // Selectors + + //- Return a reference to the selected ROMmodel + static autoPtr<ROMmodel> New + ( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times + ); + + + // Constructors + + //- Construct from components + ROMmodel + ( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times + ); + + //- No copy construct + ROMmodel(const ROMmodel&) = delete; + + //- No copy assignment + void operator=(const ROMmodel&) = delete; + + + //- Destructor + virtual ~ROMmodel() = default; + + + // Member Functions + + //- Read model settings + virtual bool read(const dictionary& dict) = 0; + + //- Create and write fields + virtual bool createAndWrite() = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodelNew.C b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodelNew.C new file mode 100644 index 00000000000..7c09aeed1db --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/ROMmodels/ROMmodel/ROMmodelNew.C @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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 "ROMmodel.H" +#include "dictionary.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::ROMmodel> Foam::ROMmodel::New +( + Time& runTime, + fvMesh& mesh, + const dictionary& dict, + const instantList& times +) +{ + const word modelType(dict.getWord("ROMmodel")); + + auto* ctorPtr = dictionaryConstructorTable(modelType); + + if (!ctorPtr) + { + FatalIOErrorInLookup + ( + dict, + "ROMmodel", + modelType, + *dictionaryConstructorTablePtr_ + ) << exit(FatalIOError); + } + + return autoPtr<ROMmodel>(ctorPtr(runTime, mesh, dict, times)); +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/createROMfields.C b/applications/utilities/postProcessing/miscellaneous/createROMfields/createROMfields.C new file mode 100644 index 00000000000..d9e7837ba84 --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/createROMfields.C @@ -0,0 +1,141 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 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/>. + +Application + createROMfields + +Group + grpPostProcessingUtilities + +Description + Create fields using reduced-order modelling (ROM) data + at specific time instants without requiring any CFD computations. + +Usage + Minimal example by using \c system/ROMfieldsDict: + \verbatim + // Mandatory entries + ROMmodel <word>; + + // Inherited entries + // See DMD.H for the 'DMD' ROMmodel + ... + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + ROMmodel | Type of reduced-order model | word | yes | - + \endtable + + Options for the \c ROMmodel entry: + \verbatim + DMD | Streaming total dynamic mode decomposition + \endverbatim + + The inherited entries are elaborated in: + - \link ROMmodel.H \endlink + - \link DMD.H \endlink + +Note + - The quality of results depends on the capabilities of the underlying + reduced-order model, and the quality of the input data. + - Warning: Reduced-order modelling is an active research area at the time of + writing; therefore, there could be cases whereat oddities can be seen. + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "timeSelector.H" +#include "fvCFD.H" +#include "ROMmodels/ROMmodel/ROMmodel.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + argList::addNote + ( + "Create fields using reduced-order modelling (ROM) data at specific " + "time instants without requiring any CFD computations." + ); + + argList::addOption + ( + "dict", + "file", + "Alternative dictionary for ROMfieldsDict" + ); + + // No -constant, no special treatment for 0/ + timeSelector::addOptions(false); + + // Remove treatments unnecessary for this utility + argList::noFunctionObjects(); + argList::removeOption("noZero"); + argList::removeOption("world"); + + + #include "addRegionOption.H" + + #include "setRootCase.H" + #include "createTime.H" + + const word dictName("ROMfieldsDict"); + #include "setSystemRunTimeDictionaryIO.H" + Info<< "Reading " << dictIO.name() << nl << endl; + IOdictionary dict(dictIO); + + instantList times = timeSelector::select0(runTime, args); + if (times.empty()) + { + FatalErrorInFunction + << "No times selected." << nl + << exit(FatalError); + } + + #include "createNamedMesh.H" + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + auto ROMptr = ROMmodel::New(runTime, mesh, dict, times); + + ROMptr->read(dict); + + ROMptr->createAndWrite(); + + + Info<< nl; + runTime.printExecutionTime(Info); + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/miscellaneous/createROMfields/readFields.H b/applications/utilities/postProcessing/miscellaneous/createROMfields/readFields.H new file mode 100644 index 00000000000..a1d345d1c8d --- /dev/null +++ b/applications/utilities/postProcessing/miscellaneous/createROMfields/readFields.H @@ -0,0 +1,189 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021-2022 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::readFieldsHandler + +Description + A simple field-loader, as per the readFields function object + +\*---------------------------------------------------------------------------*/ + +#ifndef Foam_readFields_H +#define Foam_readFields_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "messageStream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class readFieldsHandler Declaration +\*---------------------------------------------------------------------------*/ + +class readFieldsHandler +{ + // Private Data + + //- Mesh reference + fvMesh& mesh_; + + //- Output logging (verbosity) + bool log; + + + // Private Member Functions + + //- Attempt load from io, store on database if successful + template<class FieldType> + bool loadAndStore(const IOobject& io) + { + if (io.isHeaderClass<FieldType>()) + { + // Store field on mesh database + Log << " Reading " << io.name() + << " (" << FieldType::typeName << ')' << endl; + + mesh_.objectRegistry::store(new FieldType(io, mesh_)); + return true; + } + + return false; + } + + //- Forward to loadAndStore for supported types + template<class Type> + bool loadField(const IOobject& io) + { + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + typedef typename VolFieldType::Internal IntVolFieldType; + typedef GeometricField<Type, fvsPatchField, surfaceMesh> + SurfaceFieldType; + + return + ( + loadAndStore<VolFieldType>(io) + || loadAndStore<IntVolFieldType>(io) + || loadAndStore<SurfaceFieldType>(io) + ); + } + + + //- Load all fields + label loadFields(const UList<word>& fieldSet_) + { + label nLoaded = 0; + + for (const word& fieldName : fieldSet_) + { + // Already loaded? + const auto* ptr = mesh_.cfindObject<regIOobject>(fieldName); + + if (ptr) + { + ++nLoaded; + DebugInfo + << "readFields : " + << ptr->name() << " (" << ptr->type() + << ") already in database" << endl; + continue; + } + + // Load field as necessary + IOobject io + ( + fieldName, + mesh_.time().timeName(), + mesh_.thisDb(), + IOobject::MUST_READ, + IOobject::NO_WRITE + ); + + const bool ok = + ( + io.typeHeaderOk<regIOobject>(false) + && + ( + loadField<scalar>(io) + || loadField<vector>(io) + || loadField<sphericalTensor>(io) + || loadField<symmTensor>(io) + || loadField<tensor>(io) + ) + ); + + if (ok) + { + ++nLoaded; + } + else + { + DebugInfo + << "readFields : failed to load " << fieldName + << endl; + } + } + + return nLoaded; + } + + +public: + + static const bool debug = false; + + + // Constructors + + //- Construct + explicit readFieldsHandler(fvMesh& mesh, bool verbose=true) + : + mesh_(mesh), + log(verbose) + {} + + + // Member Functions + + bool execute(const UList<word>& fieldNames) + { + loadFields(fieldNames); + return true; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +#endif + +// ************************************************************************* // diff --git a/etc/caseDicts/annotated/ROMfieldsDict b/etc/caseDicts/annotated/ROMfieldsDict new file mode 100644 index 00000000000..9d22dbd7b50 --- /dev/null +++ b/etc/caseDicts/annotated/ROMfieldsDict @@ -0,0 +1,59 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2306 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object ROMfieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Mandatory entries + +// Type of reduced-order model +ROMmodel DMD; + +// Name of reconstructed field +field U; + +// Name of operand function object +object stdmd02; + +// Time-step size of DMD +deltaT 0.5; + +// Time instant in which modes are located +time 200; + +// List of mode indices +modes (0 1 2 3 4 5); + +// Amplitude coefficients (complex) +amplitudes +( + // real imag + // (1e-01 2e-02) +); + +// Eigenvalues (complex) +eigenvalues +( + // real imag + // (1e-01 2e-02) +); + +// Optional entries + +// Start time for mode-information collection +startTime 10; + +// Dimensions of reconstructed fields +dimensions [0 1 -1 0 0 0 0]; + +// ************************************************************************* // -- GitLab