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
25 \*---------------------------------------------------------------------------*/
29 #include "volFields.H"
30 #include "surfaceFields.H"
31 #include "slicedVolFields.H"
32 #include "slicedSurfaceFields.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 void fvMesh::makeSf() const
46 Info<< "void fvMesh::makeSf() const : "
47 << "assembling face areas"
51 // It is an error to attempt to recalculate
52 // if the pointer is already set
55 FatalErrorIn("fvMesh::makeSf() const")
56 << "face areas already exist"
60 SfPtr_ = new slicedSurfaceVectorField
76 void fvMesh::makeMagSf() const
80 Info<< "void fvMesh::makeMagSf() const : "
81 << "assembling mag face areas"
85 // It is an error to attempt to recalculate
86 // if the pointer is already set
89 FatalErrorIn("void fvMesh::makeMagSf() const")
90 << "mag face areas already exist"
94 // Note: Added stabilisation for faces with exactly zero area.
95 // These should be caught on mesh checking but at least this stops
96 // the code from producing Nans.
97 magSfPtr_ = new surfaceScalarField
109 mag(Sf()) + dimensionedScalar("vs", dimArea, VSMALL)
114 void fvMesh::makeC() const
118 Info<< "void fvMesh::makeC() const : "
119 << "assembling cell centres"
123 // It is an error to attempt to recalculate
124 // if the pointer is already set
127 FatalErrorIn("fvMesh::makeC() const")
128 << "cell centres already exist"
129 << abort(FatalError);
132 CPtr_ = new slicedVolVectorField
150 /* HJ, I think this is wrong. HJ, 6/Jul/2010
151 // Need to correct for cyclics transformation since absolute quantity.
152 // Ok on processor patches since hold opposite cell centre (no
154 slicedVolVectorField& C = *CPtr_;
156 forAll(C.boundaryField(), patchi)
158 if (isA<cyclicFvPatchVectorField>(C.boundaryField()[patchi]))
160 // Note: cyclic is not slice but proper field
161 C.boundaryField()[patchi] == static_cast<const vectorField&>
163 static_cast<const List<vector>&>
165 boundary_[patchi].patchSlice(faceCentres())
174 void fvMesh::makeCf() const
178 Info<< "void fvMesh::makeCf() const : "
179 << "assembling face centres"
183 // It is an error to attempt to recalculate
184 // if the pointer is already set
187 FatalErrorIn("fvMesh::makeCf() const")
188 << "face centres already exist"
189 << abort(FatalError);
192 CfPtr_ = new slicedSurfaceVectorField
211 void fvMesh::makePhi() const
215 Info<< "void fvMesh::makePhi() const : "
216 << "reading old time flux field if present and creating "
217 << "zero current time flux field"
221 // It is an error to attempt to recalculate
222 // if the pointer is already set
225 FatalErrorIn("fvMesh::makePhi() const")
226 << "flux field already exists"
227 << abort(FatalError);
230 // Reading old time mesh motion flux if it exists and
231 // creating zero current time mesh motion flux
233 scalar t0 = this->time().value() - this->time().deltaT().value();
235 IOobject meshPhiHeader
238 this->time().timeName(t0),
243 if (meshPhiHeader.headerOk())
247 InfoIn("void fvMesh::makePhi()")
248 << "Reading mesh fluxes" << endl;
251 phiPtr_ = new surfaceScalarField
256 this->time().timeName(t0),
266 (*phiPtr_) = dimensionedScalar("0", dimVolume/dimTime, 0.0);
268 // This mesh is moving: set the motion to true
274 InfoIn("void fvMesh::makePhi()")
275 << "Creating null mesh motion fluxes" << endl;
278 phiPtr_ = new surfaceScalarField
283 this->time().timeName(),
289 dimensionedScalar("0", dimVolume/dimTime, 0.0)
295 void fvMesh::updatePhi(const scalarField& sweptVols) const
297 // Fill in mesh motion fluxes given swept volumes for all faces
304 surfaceScalarField& phi = *phiPtr_;
306 scalar rDeltaT = 1.0/time().deltaT().value();
308 phi.internalField() = scalarField::subField(sweptVols, nInternalFaces());
309 phi.internalField() *= rDeltaT;
311 const fvPatchList& patches = boundary();
313 forAll (patches, patchI)
315 phi.boundaryField()[patchI] = patches[patchI].patchSlice(sweptVols);
316 phi.boundaryField()[patchI] *= rDeltaT;
321 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
323 const volScalarField::DimensionedInternalField& fvMesh::V() const
331 "const volScalarField::DimensionedInternalField& "
333 ) << "Calculating cell volumes." << endl;
336 VPtr_ = new DimensionedField<scalar, volMesh>
356 const volScalarField::DimensionedInternalField& fvMesh::V0() const
360 FatalErrorIn("fvMesh::V0() const")
361 << "V0 is not available"
362 << abort(FatalError);
369 DimensionedField<scalar, volMesh>& fvMesh::setV0()
373 FatalErrorIn("fvMesh::setV0()")
374 << "V0 is not available"
375 << abort(FatalError);
378 // Delete old volume and mesh motion fluxes. setV0() must be followed by
379 // another mesh motion. HJ, 25/Feb/2009
380 deleteDemandDrivenData(phiPtr_);
381 deleteDemandDrivenData(V0Ptr_);
385 InfoIn("DimensionedField<scalar, volMesh>& fvMesh::setV0()")
386 << "Setting old cell volumes" << endl;
389 V0Ptr_ = new DimensionedField<scalar, volMesh>
406 const volScalarField::DimensionedInternalField& fvMesh::V00() const
410 V00Ptr_ = new DimensionedField<scalar, volMesh>
423 // If V00 is used then V0 should be stored for restart
424 V0Ptr_->writeOpt() = IOobject::AUTO_WRITE;
431 tmp<volScalarField::DimensionedInternalField> fvMesh::Vsc() const
433 if (moving() && time().subCycling())
435 const TimeState& ts = time();
436 const TimeState& ts0 = time().prevTimeState();
440 ts.value() - (ts0.value() - ts0.deltaTValue())
443 if (tFrac < (1 - SMALL))
445 return V0() + tFrac*(V() - V0());
459 tmp<volScalarField::DimensionedInternalField> fvMesh::Vsc0() const
461 if (moving() && time().subCycling())
463 const TimeState& ts = time();
464 const TimeState& ts0 = time().prevTimeState();
468 (ts.value() - ts.deltaTValue())
469 - (ts0.value() - ts0.deltaTValue())
474 return V0() + t0Frac*(V() - V0());
488 const surfaceVectorField& fvMesh::Sf() const
499 const surfaceScalarField& fvMesh::magSf() const
510 const volVectorField& fvMesh::C() const
521 const surfaceVectorField& fvMesh::Cf() const
532 const surfaceScalarField& fvMesh::phi() const
539 // Set zero current time
540 // mesh motion fluxes if the time has been incremented
541 if (phiPtr_->timeIndex() != time().timeIndex())
547 InfoIn("const surfaceScalarField& fvMesh::phi() const")
548 << "Resetting mesh motion fluxes to zero" << endl;
551 (*phiPtr_) = dimensionedScalar("0", dimVolume/dimTime, 0.0);
558 surfaceScalarField& fvMesh::setPhi()
569 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
571 } // End namespace Foam
573 // ************************************************************************* //