Fix tutorials: typo in tutorials/viscoelastic/viscoelasticFluidFoam/S-MDCPP/constant...
[OpenFOAM-1.6-ext.git] / src / POD / scalarTransportPOD / scalarTransportPOD.C
bloba62fbf83513ed2cb9a8b896292a0371bb73f13e8
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
25 Class
26     scalarTransportPOD
28 Description
30 \*---------------------------------------------------------------------------*/
32 #include "scalarTransportPOD.H"
33 #include "fvc.H"
34 #include "addToRunTimeSelectionTable.H"
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 namespace Foam
40     defineTypeNameAndDebug(scalarTransportPOD, 0);
42     addToRunTimeSelectionTable
43     (
44         PODODE,
45         scalarTransportPOD,
46         dictionary
47     );
51 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
53 void Foam::scalarTransportPOD::calcOrthoBase() const
55     if (orthoBasePtr_)
56     {
57         FatalErrorIn
58         (
59             "scalarTransportPOD::calcOrthoBase()"
60         )   << "Orthogonal base already calculated"
61             << abort(FatalError);
62     }
64     // Create ortho-normal base
65     scalar accuracy = readScalar(dict().lookup("accuracy"));
67     // Get times list
68     Time& runTime = const_cast<Time&>(mesh().time());
70     // Remember time index to restore it after the scan
71     label origTimeIndex = runTime.timeIndex();
73     instantList Times = runTime.times();
75     // Create a list of snapshots
76     PtrList<volScalarField> fields(Times.size());
78     label nSnapshots = 0;
80     forAll (Times, i)
81     {
82         if (Times[i].value() < SMALL || Times[i] == runTime.constant())
83         {
84             Info << "Skipping time " << Times[i] << endl;
86             continue;
87         }
89         runTime.setTime(Times[i], i);
91         Info<< "Time = " << runTime.timeName() << endl;
93         IOobject phiHeader
94         (
95             phiName_,
96             runTime.timeName(),
97             mesh(),
98             IOobject::MUST_READ
99         );
101         if (phiHeader.headerOk())
102         {
103             Info<< "    Reading " << phiName_ << endl;
105             fields.set(nSnapshots, new volScalarField(phiHeader, mesh()));
107             // Rename the field
108             fields[nSnapshots].rename(phiName_ + name(i));
109             nSnapshots++;
110         }
111         else
112         {
113             Info<< "    No " << phiName_ << endl;
114         }
115     }
117     // Reset time index to initial state
118     runTime.setTime(Times[origTimeIndex], origTimeIndex);
120     // Resize snapshots
121     if (nSnapshots < 2)
122     {
123         FatalErrorIn
124         (
125             "scalarTransportPOD::calcOrthoBase()"
126         )   << "Insufficient number of snapshots: " << nSnapshots
127             << abort(FatalError);
128     }
130     Info << "Number of snapshots: " << nSnapshots << endl;
132     fields.setSize(nSnapshots);
134     // Create ortho-normal base for transported variable
135     orthoBasePtr_ = new scalarPODOrthoNormalBase(fields, accuracy);
139 void Foam::scalarTransportPOD::calcDerivativeCoeffs() const
141     if (derivativeMatrixPtr_)
142     {
143         FatalErrorIn
144         (
145             "void scalarTransportPOD::calcDerivativeCoeffs() const"
146         )   << "Derivative matrix already calculated"
147             << abort(FatalError);
148     }
150     // Calculate coefficients for differential equation
151     // Get times list
152     Time& runTime = const_cast<Time&>(this->mesh().time());
154     // Remember time index to restore it
155     label origTimeIndex = runTime.timeIndex();
157     // Read diffusivity
159     IOdictionary transportProperties
160     (
161         IOobject
162         (
163             "transportProperties",
164             runTime.constant(),
165             this->mesh(),
166             IOobject::MUST_READ,
167             IOobject::NO_WRITE
168         )
169     );
171     Info<< "Reading diffusivity D\n" << endl;
173     dimensionedScalar DT
174     (
175         transportProperties.lookup("DT")
176     );
178     // Find velocity field
180     word Uname(this->dict().lookup("velocity"));
182     instantList Times = runTime.times();
184     volVectorField* Uptr = NULL;
186     forAll (Times, i)
187     {
188         runTime.setTime(Times[i], i);
190         Info<< "Time = " << runTime.timeName() << endl;
192         IOobject Uheader
193         (
194             Uname,
195             runTime.timeName(),
196             this->mesh(),
197             IOobject::MUST_READ
198         );
200         if (Uheader.headerOk())
201         {
202             Info<< "    Reading " << Uname << endl;
204             Uptr = new volVectorField(Uheader, this->mesh());
205             break;
206         }
207         else
208         {
209             Info<< "    No " << Uname << endl;
210         }
211     }
213     // Reset time index to initial state
214     runTime.setTime(Times[origTimeIndex], origTimeIndex);
216     if (!Uptr)
217     {
218         FatalErrorIn
219         (
220             "void scalarTransportPOD::calcDerivativeCoeffs() const"
221         )   << "Cannot find velocity: " << Uname
222             << abort(FatalError);
223     }
225     volVectorField& U = *Uptr;
227     // Create derivative matrix
229     const scalarPODOrthoNormalBase& b = orthoBase();
231     derivativeMatrixPtr_ = new scalarSquareMatrix(b.baseSize(), 0.0);
232     scalarSquareMatrix& derivative = *derivativeMatrixPtr_;
234     for (label i = 0; i < b.baseSize(); i++)
235     {
236         const volScalarField& snapI = b.orthoField(i);
238         volVectorField gradSnapI = fvc::grad(snapI);
240         for (label j = 0; j < b.baseSize(); j++)
241         {
242             const volScalarField& snapJ = b.orthoField(j);
244             volVectorField gradSnapJ = fvc::grad(snapJ);
246             derivative[i][j] =
247                 DT.value()*POD::projection(fvc::div(gradSnapJ), snapI)
248               - POD::projection((U & gradSnapJ), snapI);
249         }
250     }
253 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
255 // Construct from components
256 Foam::scalarTransportPOD::scalarTransportPOD
258     const fvMesh& mesh,
259     const dictionary& dict
262     PODODE(mesh, dict),
263     phiName_(dict.lookup("field")),
264     coeffs_(),
265     derivativeMatrixPtr_(NULL),
266     orthoBasePtr_(NULL),
267     fieldPtr_(NULL)
269     // Grab coefficients from the first snapshot of the ortho-normal base
270     coeffs_.setSize(orthoBase().baseSize());
272     const scalarRectangularMatrix& orthoBaseCoeffs =
273         orthoBase().interpolationCoeffs();
275     forAll (coeffs_, i)
276     {
277         coeffs_[i] = orthoBaseCoeffs[0][i];
278     }
282 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
284 Foam::scalarTransportPOD::~scalarTransportPOD()
286     deleteDemandDrivenData(derivativeMatrixPtr_);
288     clearBase();
289     clearFields();
293 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
295 Foam::label Foam::scalarTransportPOD::nEqns() const
297     return coeffs().size();
301 Foam::scalarField& Foam::scalarTransportPOD::coeffs()
303     return coeffs_;
307 const Foam::scalarField& Foam::scalarTransportPOD::coeffs() const
309     return coeffs_;
313 void Foam::scalarTransportPOD::derivatives
315     const scalar x,
316     const scalarField& y,
317     scalarField& dydx
318 ) const
320     if (!derivativeMatrixPtr_)
321     {
322         calcDerivativeCoeffs();
323     }
325    const scalarSquareMatrix& derivative = *derivativeMatrixPtr_;
327     forAll (dydx, i)
328     {
329         dydx[i] = 0;
331         forAll (y, j)
332         {
333             dydx[i] += derivative[i][j]*y[j];
334         }
335     }
339 void Foam::scalarTransportPOD::jacobian
341     const scalar x,
342     const scalarField& y,
343     scalarField& dfdx,
344     scalarSquareMatrix& dfdy
345 ) const
347     derivatives(x, y, dfdx);
348     dfdy = 0;
352 const Foam::scalarPODOrthoNormalBase&
353 Foam::scalarTransportPOD::orthoBase() const
355     if (!orthoBasePtr_)
356     {
357         calcOrthoBase();
358     }
360     return *orthoBasePtr_;
364 void Foam::scalarTransportPOD::clearBase() const
366     deleteDemandDrivenData(orthoBasePtr_);
370 const Foam::volScalarField& Foam::scalarTransportPOD::field() const
372     if (!fieldPtr_)
373     {
374         updateFields();
375     }
377     return *fieldPtr_;
381 void Foam::scalarTransportPOD::updateFields() const
383     if (!fieldPtr_)
384     {
385         // Allocate field
386         fieldPtr_ =
387             new volScalarField
388             (
389                 IOobject
390                 (
391                     phiName_ + "POD",
392                     mesh().time().timeName(),
393                     mesh(),
394                     IOobject::NO_READ,
395                     IOobject::NO_WRITE
396                 ),
397                 mesh(),
398                 dimensionedScalar
399                 (
400                     "zero",
401                     orthoBase().orthoField(0).dimensions(),
402                     0
403                 )
404             );
405     }
407     volScalarField& phi = *fieldPtr_;
409     const scalarPODOrthoNormalBase& b = orthoBase();
411     phi = dimensionedScalar("zero", b.orthoField(0).dimensions(), 0);
413     forAll (coeffs_, i)
414     {
415         phi += coeffs_[i]*b.orthoField(i);
416     }
420 void Foam::scalarTransportPOD::clearFields() const
422     deleteDemandDrivenData(fieldPtr_);
426 void Foam::scalarTransportPOD::write() const
428     // Recalculate field and force a write
429     updateFields();
430     field().write();
434 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
437 // ************************************************************************* //