1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Establish POD ortho-normal base and interpolation coefficients give a list
29 of fields. Size of ortho-normal base is calculated from the desired
30 accuracy, e.g. 0.99-0.99999 (in energy terms)
32 \*---------------------------------------------------------------------------*/
34 #include "PODOrthoNormalBase.H"
36 #include "PODEigenBase.H"
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 void Foam::PODOrthoNormalBase<Type>::calcOrthoBase
44 const PtrList<GeometricField<Type, fvPatchField, volMesh> >& snapshots,
48 // Calculate ortho-normal base for each component
49 PtrList<PODEigenBase> eigenBase(pTraits<Type>::nComponents);
51 const label nSnapshots = snapshots.size();
54 powProduct<Vector<label>, pTraits<Type>::rank>::type validComponents
58 snapshots[0].mesh().solutionD(),
61 typename powProduct<Vector<label>,
67 label nValidCmpts = 0;
69 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
71 // Component not valid, skipping
72 if (validComponents[cmpt] == -1) continue;
74 // Create a list of snapshots
75 PtrList<volScalarField> sf(nSnapshots);
79 sf.set(i, new volScalarField(snapshots[i].component(cmpt)));
83 eigenBase.set(cmpt, new PODEigenBase(sf));
85 Info<< "Cumulative eigen-values for component " << cmpt
86 << ": " << setprecision(14)
87 << eigenBase[nValidCmpts].cumulativeEigenValues() << endl;
92 eigenBase.setSize(nValidCmpts);
94 Info << "Number of valid eigen components: " << nValidCmpts << endl;
97 for (label snapI = 0; snapI < nSnapshots; snapI++)
101 // Get minimum cumulative eigen value for all valid components
102 scalar minCumEigen = 1.0;
106 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
108 // Skip invalid components
109 if (validComponents[cmpt] != -1)
115 eigenBase[nValidCmpts].cumulativeEigenValues()[snapI]
122 if (minCumEigen > accuracy)
128 Info << "Base size: " << baseSize << endl;
130 // Establish orthonormal base
131 orthoFields_.setSize(baseSize);
133 for (label baseI = 0; baseI < baseSize; baseI++)
135 GeometricField<Type, fvPatchField, volMesh>* onBasePtr
137 new GeometricField<Type, fvPatchField, volMesh>
141 snapshots[0].name() + "POD" + name(baseI),
142 snapshots[0].time().timeName(),
151 snapshots[0].dimensions(),
156 GeometricField<Type, fvPatchField, volMesh>& onBase = *onBasePtr;
160 for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
162 if (validComponents[cmpt] != -1)
164 // Valid component, grab eigen-factors
166 const scalarField& eigenVector =
167 eigenBase[nValidCmpts].eigenVectors()[baseI];
170 volScalarField onBaseCmpt = onBase.component(cmpt);
172 forAll (eigenVector, eigenI)
175 eigenVector[eigenI]*snapshots[eigenI].component(cmpt);
178 // Re-normalise ortho-normal vector
179 onBaseCmpt /= Foam::sqrt(sumSqr(onBaseCmpt));
181 onBase.replace(cmpt, onBaseCmpt);
185 // Component invalid. Grab first snapshot.
189 snapshots[0].component(cmpt)
194 orthoFields_.set(baseI, onBasePtr);
197 // Calculate interpolation coefficients
198 interpolationCoeffsPtr_ =
199 new RectangularMatrix<Type>(snapshots.size(), orthoFields_.size());
200 RectangularMatrix<Type>& coeffs = *interpolationCoeffsPtr_;
202 forAll (snapshots, snapshotI)
204 forAll (orthoFields_, baseI)
206 coeffs[snapshotI][baseI] =
209 snapshots[snapshotI],
217 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
219 // given list of snapshots and accuracy
221 Foam::PODOrthoNormalBase<Type>::PODOrthoNormalBase
223 const PtrList<GeometricField<Type, fvPatchField, volMesh> >& snapshots,
224 const scalar accuracy
228 interpolationCoeffsPtr_(NULL)
230 calcOrthoBase(snapshots, accuracy);
234 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
237 Foam::PODOrthoNormalBase<Type>::~PODOrthoNormalBase()
239 deleteDemandDrivenData(interpolationCoeffsPtr_);
243 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
246 // ************************************************************************* //