Forward compatibility: flex
[foam-extend-3.2.git] / src / POD / PODOrthoNormalBase / scalarPODOrthoNormalBase.C
bloba79ef85d14f5838898aab13e7926c41d52656184
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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/>.
24 Class
25     PODOrthoNormalBase
27 Description
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 "scalarPODOrthoNormalBase.H"
35 #include "PODEigenBase.H"
36 #include "IOmanip.H"
37 #include "zeroGradientFvPatchFields.H"
39 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
41 template<>
42 void Foam::PODOrthoNormalBase<Foam::scalar>::calcOrthoBase
44     const PtrList<volScalarField>& snapshots,
45     const scalar accuracy
48     PODEigenBase eigenBase(snapshots);
50     label baseSize = 0;
52     const scalarField& cumEigenValues = eigenBase.cumulativeEigenValues();
54     forAll (cumEigenValues, i)
55     {
56         baseSize++;
58         if (cumEigenValues[i] > accuracy)
59         {
60             break;
61         }
62     }
64     Info<< "Cumulative eigen-values: "
65         << setprecision(14) << cumEigenValues << nl
66         << "Base size: " << baseSize << endl;
68     // Establish orthonormal base
69     orthoFields_.setSize(baseSize);
71     for (label baseI = 0; baseI < baseSize; baseI++)
72     {
73         const scalarField& eigenVector = eigenBase.eigenVectors()[baseI];
75         volScalarField* onBasePtr
76         (
77             new volScalarField
78             (
79                 IOobject
80                 (
81                     snapshots[0].name() + "POD" + name(baseI),
82                     snapshots[0].time().timeName(),
83                     snapshots[0].mesh(),
84                     IOobject::NO_READ,
85                     IOobject::NO_WRITE
86                 ),
87                 snapshots[0].mesh(),
88                 dimensionedScalar("zero", snapshots[0].dimensions(), 0)
89             )
90         );
91         volScalarField& onBase = *onBasePtr;
93         forAll (eigenVector, eigenI)
94         {
95             onBase += eigenVector[eigenI]*snapshots[eigenI];
96         }
98         // Re-normalise ortho-normal vector
99         scalar magSumSquare = Foam::sqrt(sumSqr(onBase));
100         if (magSumSquare > SMALL)
101         {
102             onBase /= magSumSquare;
103             onBase.correctBoundaryConditions();
104         }
106         orthoFields_.set(baseI, onBasePtr);
107     }
109     // Calculate interpolation coefficients
110     interpolationCoeffsPtr_ =
111         new RectangularMatrix<scalar>(snapshots.size(), orthoFields_.size());
112     RectangularMatrix<scalar>& coeffs = *interpolationCoeffsPtr_;
114     forAll (snapshots, snapshotI)
115     {
116         forAll (orthoFields_, baseI)
117         {
118             coeffs[snapshotI][baseI] =
119                 POD::projection
120                 (
121                     snapshots[snapshotI],
122                     orthoFields_[baseI]
123                 );
124         }
125     }
129 // ************************************************************************* //