1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Establish POD ortho-normal base and interpolation coefficients give a list
30 of fields. Size of ortho-normal base is calculated from the desired
31 accuracy, e.g. 0.99-0.99999 (in energy terms)
33 \*---------------------------------------------------------------------------*/
35 #include "PODOrthoNormalBase.H"
37 #include "PODEigenBase.H"
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 void Foam::PODOrthoNormalBase<Type>::calcOrthoBase
45 const PtrList<GeometricField<Type, fvPatchField, volMesh> >& snapshots,
49 // Calculate ortho-normal base for each component
50 PtrList<PODEigenBase> eigenBase(pTraits<Type>::nComponents);
52 const label nSnapshots = snapshots.size();
55 powProduct<Vector<label>, pTraits<Type>::rank>::type validComponents
59 snapshots[0].mesh().solutionD(),
62 typename powProduct<Vector<label>,
68 label nValidCmpts = 0;
70 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
72 // Component not valid, skipping
73 if (validComponents[cmpt] == -1) continue;
75 // Create a list of snapshots
76 PtrList<volScalarField> sf(nSnapshots);
80 sf.set(i, new volScalarField(snapshots[i].component(cmpt)));
84 eigenBase.set(cmpt, new PODEigenBase(sf));
86 Info<< "Cumulative eigen-values for component " << cmpt
87 << ": " << setprecision(14)
88 << eigenBase[nValidCmpts].cumulativeEigenValues() << endl;
93 eigenBase.setSize(nValidCmpts);
95 Info << "Number of valid eigen components: " << nValidCmpts << endl;
98 for (label snapI = 0; snapI < nSnapshots; snapI++)
102 // Get minimum cumulative eigen value for all valid components
103 scalar minCumEigen = 1.0;
107 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
109 // Skip invalid components
110 if (validComponents[cmpt] != -1)
116 eigenBase[nValidCmpts].cumulativeEigenValues()[snapI]
123 if (minCumEigen > accuracy)
129 Info << "Base size: " << baseSize << endl;
131 // Establish orthonormal base
132 orthoFields_.setSize(baseSize);
134 for (label baseI = 0; baseI < baseSize; baseI++)
136 GeometricField<Type, fvPatchField, volMesh>* onBasePtr
138 new GeometricField<Type, fvPatchField, volMesh>
142 snapshots[0].name() + "POD" + name(baseI),
143 snapshots[0].time().timeName(),
152 snapshots[0].dimensions(),
157 GeometricField<Type, fvPatchField, volMesh>& onBase = *onBasePtr;
161 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
163 if (validComponents[cmpt] != -1)
165 // Valid component, grab eigen-factors
167 const scalarField& eigenVector =
168 eigenBase[nValidCmpts].eigenVectors()[baseI];
171 volScalarField onBaseCmpt = onBase.component(cmpt);
173 forAll (eigenVector, eigenI)
176 eigenVector[eigenI]*snapshots[eigenI].component(cmpt);
179 // Re-normalise ortho-normal vector
180 onBaseCmpt /= Foam::sqrt(sumSqr(onBaseCmpt));
182 onBase.replace(cmpt, onBaseCmpt);
186 // Component invalid. Grab first snapshot.
190 snapshots[0].component(cmpt)
195 orthoFields_.set(baseI, onBasePtr);
198 // Calculate interpolation coefficients
199 interpolationCoeffsPtr_ =
200 new RectangularMatrix<Type>(snapshots.size(), orthoFields_.size());
201 RectangularMatrix<Type>& coeffs = *interpolationCoeffsPtr_;
203 forAll (snapshots, snapshotI)
205 forAll (orthoFields_, baseI)
207 coeffs[snapshotI][baseI] =
210 snapshots[snapshotI],
218 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
220 // given list of snapshots and accuracy
222 Foam::PODOrthoNormalBase<Type>::PODOrthoNormalBase
224 const PtrList<GeometricField<Type, fvPatchField, volMesh> >& snapshots,
225 const scalar accuracy
229 interpolationCoeffsPtr_(NULL)
231 calcOrthoBase(snapshots, accuracy);
235 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
238 Foam::PODOrthoNormalBase<Type>::~PODOrthoNormalBase()
240 deleteDemandDrivenData(interpolationCoeffsPtr_);
244 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
247 // ************************************************************************* //