DAPimpleDyMFoam.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v4
5 
6  This class is modified from OpenFOAM's source code
7  applications/solvers/incompressible/pimpleFoam
8 
9  OpenFOAM: The Open Source CFD Toolbox
10 
11  Copyright (C): 2011-2016 OpenFOAM Foundation
12 
13  OpenFOAM License:
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "DAPimpleDyMFoam.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 
37 defineTypeNameAndDebug(DAPimpleDyMFoam, 0);
38 addToRunTimeSelectionTable(DASolver, DAPimpleDyMFoam, dictionary);
39 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 
42  char* argsAll,
43  PyObject* pyOptions)
44  : DASolver(argsAll, pyOptions),
45  pimplePtr_(nullptr),
46  pPtr_(nullptr),
47  UPtr_(nullptr),
48  phiPtr_(nullptr),
49  laminarTransportPtr_(nullptr),
50  turbulencePtr_(nullptr),
51  daTurbulenceModelPtr_(nullptr),
52  daFvSourcePtr_(nullptr),
53  fvSourcePtr_(nullptr),
54  PrPtr_(nullptr),
55  PrtPtr_(nullptr),
56  TPtr_(nullptr),
57  alphatPtr_(nullptr),
58  UfPtr_(nullptr)
59 {
60  // check whether the temperature field exists in the 0 folder
61  hasTField_ = DAUtility::isFieldReadable(meshPtr_(), "T", "volScalarField");
62 }
63 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
64 
66 {
67  /*
68  Description:
69  Initialize variables for DASolver
70  */
71  Info << "Initializing fields for DAPimpleDyMFoam" << endl;
72  Time& runTime = runTimePtr_();
73  fvMesh& mesh = meshPtr_();
75 #include "createFieldsPimpleDyM.H"
76  // read the RAS model from constant/turbulenceProperties
77  const word turbModelName(
78  IOdictionary(
79  IOobject(
80  "turbulenceProperties",
81  mesh.time().constant(),
82  mesh,
83  IOobject::MUST_READ,
84  IOobject::NO_WRITE,
85  false))
86  .subDict("RAS")
87  .lookup("RASModel"));
89 
90 #include "createAdjoint.H"
91 
92  // initialize fvSource and the source term
93  const dictionary& allOptions = daOptionPtr_->getAllOptions();
94  if (allOptions.subDict("fvSource").toc().size() != 0)
95  {
96  hasFvSource_ = 1;
97  Info << "Computing fvSource" << endl;
98  word sourceName = allOptions.subDict("fvSource").toc()[0];
99  word fvSourceType = allOptions.subDict("fvSource").subDict(sourceName).getWord("type");
101  fvSourceType, mesh, daOptionPtr_(), daModelPtr_(), daIndexPtr_()));
102  daFvSourcePtr_->calcFvSource(fvSource);
103  }
104 
105  // reduceIO does not write mesh, but if there is a shape variable, set writeMesh to 1
106  dictionary dvSubDict = daOptionPtr_->getAllOptions().subDict("inputInfo");
107  forAll(dvSubDict.toc(), idxI)
108  {
109  word dvName = dvSubDict.toc()[idxI];
110  if (dvSubDict.subDict(dvName).getWord("type") == "volCoord")
111  {
112  reduceIOWriteMesh_ = 1;
113  break;
114  }
115  }
116 }
117 
119 {
120  /*
121  Description:
122  Call the primal solver to get converged state variables
123 
124  Output:
125  state variable vector
126  */
127 
128 #include "createRefsPimpleDyM.H"
129 
130  // need to initialize the dynamic Mesh for each primal run
131  this->initDynamicMesh();
132 
133  // call correctNut, this is equivalent to turbulence->validate();
134  daTurbulenceModelPtr_->updateIntermediateVariables();
135 
136  Info << "\nStarting time loop\n"
137  << endl;
138 
139  label pimplePrintToScreen = 0;
140 
141  // we need to reduce the number of files written to the disk to minimize the file IO load
142  label reduceIO = daOptionPtr_->getAllOptions().subDict("unsteadyAdjoint").getLabel("reduceIO");
143  wordList additionalOutput;
144  if (reduceIO)
145  {
146  daOptionPtr_->getAllOptions().subDict("unsteadyAdjoint").readEntry<wordList>("additionalOutput", additionalOutput);
147  }
148 
149  scalar endTime = runTime.endTime().value();
150  scalar deltaT = runTime.deltaT().value();
151  label nInstances = round(endTime / deltaT);
152 
153  // main loop
154  label regModelFail = 0;
155  label fail = 0;
156  for (label iter = 1; iter <= nInstances; iter++)
157  {
158  ++runTime;
159 
160  // if we have unsteadyField in inputInfo, assign GlobalVar::inputFieldUnsteady to OF fields at each time step
161  this->updateInputFieldUnsteady();
162 
164 
165  if (printToScreen_)
166  {
167  Info << "Time = " << runTime.timeName() << nl << endl;
168 #include "CourantNo.H"
169  }
170 
171  // --- Pressure-velocity PIMPLE corrector loop
172  while (pimple.loop())
173  {
174  if (pimple.finalIter() && printToScreen_)
175  {
176  pimplePrintToScreen = 1;
177  }
178  else
179  {
180  pimplePrintToScreen = 0;
181  }
182 
183  if (pimple.firstIter() || moveMeshOuterCorrectors)
184  {
185  pointIOField readPoints(
186  IOobject(
187  "points",
188  runTime.timeName(),
189  "polyMesh",
190  mesh,
191  IOobject::MUST_READ,
192  IOobject::NO_WRITE),
193  mesh.points());
194 
195  mesh.movePoints(readPoints);
196  U.correctBoundaryConditions();
197 
198  if (mesh.changing())
199  {
200  if (correctPhi)
201  {
202  // Calculate absolute flux
203  // from the mapped surface velocity
204  phi = mesh.Sf() & Uf;
205 
206  CorrectPhiDF(
207  U,
208  phi,
209  p,
210  dimensionedScalar("rAUf", dimTime, 1),
211  pimple);
212 
213  // Make the flux relative to the mesh motion
215  }
216  }
217  }
218 
219 #include "UEqnPimpleDyM.H"
220 
221  // --- Pressure corrector loop
222  while (pimple.correct())
223  {
224 #include "pEqnPimpleDyM.H"
225  }
226 
227  if (hasTField_)
228  {
229 #include "TEqnPimpleDyM.H"
230  }
231 
232  laminarTransport.correct();
233  daTurbulenceModelPtr_->correct(pimplePrintToScreen);
234 
235  // update the output field value at each iteration, if the regression model is active
236  fail = daRegressionPtr_->compute();
237  }
238 
239  regModelFail += fail;
240 
241  if (this->validateStates())
242  {
243  // write data to files and quit
244  runTime.writeNow();
245  mesh.write();
246  return 1;
247  }
248 
250  daRegressionPtr_->printInputInfo(printToScreen_);
253 
254  if (reduceIO && iter < nInstances)
255  {
256  this->writeAdjStates(reduceIOWriteMesh_, additionalOutput);
257  daRegressionPtr_->writeFeatures();
258  }
259  else
260  {
261  runTime.write();
262  daRegressionPtr_->writeFeatures();
263  }
264  }
265 
266  if (regModelFail != 0)
267  {
268  return 1;
269  }
270 
271  // need to save primalFinalTimeIndex_.
272  primalFinalTimeIndex_ = runTime.timeIndex();
273 
274  // write the mesh to files
275  mesh.write();
276 
277  Info << "End\n"
278  << endl;
279 
280  return 0;
281 }
282 
285  surfaceVectorField& Uf,
286  const volVectorField& U,
287  const surfaceScalarField& phi)
288 {
289  const fvMesh& mesh = U.mesh();
290 
291  if (mesh.moving())
292  {
293  Uf = fvc::interpolate(U);
294  surfaceVectorField n(mesh.Sf() / mesh.magSf());
295  Uf += n * (phi / mesh.magSf() - (n & Uf));
296  }
297 }
298 
300  volVectorField& U,
301  surfaceScalarField& phi)
302 {
303  const fvMesh& mesh = U.mesh();
304 
305  if (mesh.changing())
306  {
307  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
308  surfaceScalarField::Boundary& phibf =
309  phi.boundaryFieldRef();
310 
311  forAll(Ubf, patchi)
312  {
313  if (Ubf[patchi].fixesValue())
314  {
315  Ubf[patchi].initEvaluate();
316  }
317  }
318 
319  forAll(Ubf, patchi)
320  {
321  if (Ubf[patchi].fixesValue())
322  {
323  Ubf[patchi].evaluate();
324 
325  phibf[patchi] = Ubf[patchi] & mesh.Sf().boundaryField()[patchi];
326  }
327  }
328  }
329 }
330 
332  volVectorField& U,
333  surfaceScalarField& phi,
334  const volScalarField& p,
335  const dimensionedScalar& rAUf,
337 {
338  // NOTE: we delete the divU input as it is zero
339 
340  const fvMesh& mesh = U.mesh();
341  const Time& runTime = mesh.time();
342 
343  this->correctUphiBCsDF(U, phi);
344 
345  // Initialize BCs list for pcorr to zero-gradient
346  wordList pcorrTypes(
347  p.boundaryField().size(),
348  zeroGradientFvPatchScalarField::typeName);
349 
350  // Set BCs of pcorr to fixed-value for patches at which p is fixed
351  forAll(p.boundaryField(), patchi)
352  {
353  if (p.boundaryField()[patchi].fixesValue())
354  {
355  pcorrTypes[patchi] = fixedValueFvPatchScalarField::typeName;
356  }
357  }
358 
359  volScalarField pcorr(
360  IOobject(
361  "pcorr",
362  runTime.timeName(),
363  mesh),
364  mesh,
365  dimensionedScalar(p.dimensions(), Zero),
366  pcorrTypes);
367 
368  if (pcorr.needReference())
369  {
371  adjustPhi(phi, U, pcorr);
372  fvc::makeAbsolute(phi, U);
373  }
374 
375  mesh.setFluxRequired(pcorr.name());
376 
377  while (pimple.correctNonOrthogonal())
378  {
379  // Solve for pcorr such that the divergence of the corrected flux
380  // matches the divU provided (from previous iteration, time-step...)
381  fvScalarMatrix pcorrEqn(
382  fvm::laplacian(rAUf, pcorr) == fvc::div(phi));
383 
384  pcorrEqn.setReference(0, 0);
385 
386  pcorrEqn.solve(
387  mesh.solver(pcorr.select(pimple.finalNonOrthogonalIter())));
388 
389  if (pimple.finalNonOrthogonalIter())
390  {
391  phi -= pcorrEqn.flux();
392  }
393  }
394 }
395 
396 } // End namespace Foam
397 
398 // ************************************************************************* //
UEqnPimpleDyM.H
U
volVectorField & U
Definition: createRefsPimpleDyM.H:7
Foam::DASolver::printToScreen_
label printToScreen_
whether to print primal information to the screen
Definition: DASolver.H:150
pimple
pimpleControlDF & pimple
Definition: createRefsPimpleDyM.H:5
Foam::DASolver::initDynamicMesh
void initDynamicMesh()
resetting internal info in fvMesh, which is needed for multiple primal runs
Definition: DASolver.C:3761
Foam::DASolver::daRegressionPtr_
autoPtr< DARegression > daRegressionPtr_
DARegression pointer.
Definition: DASolver.H:111
Foam::DASolver::daModelPtr_
autoPtr< DAModel > daModelPtr_
DAModel pointer.
Definition: DASolver.H:84
Foam::pimpleControlDF
Definition: pimpleControlDF.H:51
Foam::DASolver::daIndexPtr_
autoPtr< DAIndex > daIndexPtr_
DAIndex pointer.
Definition: DASolver.H:87
Foam::DASolver::primalFinalTimeIndex_
label primalFinalTimeIndex_
the final time index from the primal solve. for steady state cases it can converge before endTime
Definition: DASolver.H:168
createFieldsPimpleDyM.H
Foam::DASolver
Definition: DASolver.H:54
pEqnPimpleDyM.H
Foam::DAPimpleDyMFoam::correctUphiBCsDF
void correctUphiBCsDF(volVectorField &U, surfaceScalarField &phi)
custom correctUphiBCs for DAFoam
Definition: DAPimpleDyMFoam.C:299
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(DAFunction, DAFunctionForce, dictionary)
Foam::DAPimpleDyMFoam::correctPhi
bool correctPhi
Definition: DAPimpleDyMFoam.H:119
DAPimpleDyMFoam.H
TEqnPimpleDyM.H
Foam::DASolver::daOptionPtr_
autoPtr< DAOption > daOptionPtr_
DAOption pointer.
Definition: DASolver.H:81
fvSource
volScalarField & fvSource
Definition: createRefsHeatTransfer.H:7
Foam::DATurbulenceModel::New
static autoPtr< DATurbulenceModel > New(const word modelType, const fvMesh &mesh, const DAOption &daOption)
Definition: DATurbulenceModel.C:161
createAdjoint.H
Foam::DASolver::printIntervalUnsteady_
label printIntervalUnsteady_
how frequent do you want to print the primal info default is every 100 steps
Definition: DASolver.H:162
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::DASolver::isPrintTime
label isPrintTime(const Time &runTime, const label printInterval) const
Definition: DASolver.C:2508
Foam::DAPimpleDyMFoam::moveMeshOuterCorrectors
bool moveMeshOuterCorrectors
Definition: DAPimpleDyMFoam.H:123
Foam::DAPimpleDyMFoam::CorrectPhiDF
void CorrectPhiDF(volVectorField &U, surfaceScalarField &phi, const volScalarField &p, const dimensionedScalar &rAUf, pimpleControlDF &pimple)
custom CorrectPhi for DAFoam
Definition: DAPimpleDyMFoam.C:331
Foam::DAPimpleDyMFoam::daFvSourcePtr_
autoPtr< DAFvSource > daFvSourcePtr_
DASource pointer.
Definition: DAPimpleDyMFoam.H:79
Foam::DASolver::validateStates
label validateStates()
check if the state variables have valid values
Definition: DASolver.C:3382
p
volScalarField & p
Definition: createRefsPimpleDyM.H:6
Foam::DAPimpleDyMFoam::daTurbulenceModelPtr_
autoPtr< DATurbulenceModel > daTurbulenceModelPtr_
DATurbulenceModel pointer.
Definition: DAPimpleDyMFoam.H:76
Foam::DAPimpleDyMFoam::hasFvSource_
label hasFvSource_
whether to have fvSource term
Definition: DAPimpleDyMFoam.H:85
Foam::DAFvSource::New
static autoPtr< DAFvSource > New(const word modelType, const fvMesh &mesh, const DAOption &daOption, const DAModel &daModel, const DAIndex &daIndex)
Definition: DAFvSource.C:47
Foam::DAPimpleDyMFoam::initSolver
virtual void initSolver()
initialize fields and variables
Definition: DAPimpleDyMFoam.C:65
Foam::DAPimpleDyMFoam::solvePrimal
virtual label solvePrimal()
solve the primal equations
Definition: DAPimpleDyMFoam.C:118
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFunction, 0)
phi
surfaceScalarField & phi
Definition: createRefsPimpleDyM.H:8
Foam
Definition: checkGeometry.C:32
Foam::DAPimpleDyMFoam::correctUfPimpleDyM
void correctUfPimpleDyM(surfaceVectorField &Uf, const volVectorField &U, const surfaceScalarField &phi)
custom CorrectUf function for DAFoam
Definition: DAPimpleDyMFoam.C:284
makeRelative
MRF makeRelative(fvc::interpolate(rho), phiHbyA)
allOptions
const dictionary & allOptions
Definition: createRefsPimpleDyM.H:14
Foam::DAPimpleDyMFoam::DAPimpleDyMFoam
DAPimpleDyMFoam(char *argsAll, PyObject *pyOptions)
Definition: DAPimpleDyMFoam.C:41
laminarTransport
singlePhaseTransportModel & laminarTransport
Definition: createRefsPimpleDyM.H:9
Foam::DAPimpleDyMFoam::hasTField_
label hasTField_
whether to have the temperature field
Definition: DAPimpleDyMFoam.H:117
adjustPhi
adjustPhi(phiHbyA, U, p)
forAll
forAll(nuTilda1, cellI)
Definition: nuTilda1EqnIrkPimple.H:19
Foam::DAPimpleDyMFoam::reduceIOWriteMesh_
label reduceIOWriteMesh_
whether to write mesh for the reduceIO
Definition: DAPimpleDyMFoam.H:100
Foam::DASolver::runTimePtr_
autoPtr< Time > runTimePtr_
runTime pointer
Definition: DASolver.H:75
Foam::DASolver::meshPtr_
autoPtr< fvMesh > meshPtr_
fvMesh pointer
Definition: DASolver.H:78
Uf
surfaceVectorField & Uf
Definition: createRefsPimpleDyM.H:15
Foam::DAUtility::isFieldReadable
static label isFieldReadable(const fvMesh &mesh, const word fieldName, const word fieldType)
Definition: DAUtility.C:817
Foam::DASolver::updateInputFieldUnsteady
void updateInputFieldUnsteady()
assign the inputFieldUnsteady values to the OF field vars
Definition: DASolver.C:3924
runTime
Time & runTime
Definition: createRefsHeatTransfer.H:1
Foam::DASolver::writeAdjStates
void writeAdjStates(const label writeMesh, const wordList &additionalOutput)
write state variables that are NO_WRITE to disk
Definition: DASolver.C:2778
createRefsPimpleDyM.H
Foam::DASolver::printElapsedTime
void printElapsedTime(const Time &runTime, const label printToScreen)
Definition: DASolver.H:256
createPimpleControlPython.H
Foam::DASolver::calcAllFunctions
void calcAllFunctions(label print=0)
calculate the values of all objective functions and print them to screen
Definition: DASolver.C:204