49 laminarTransportPtr_(nullptr),
50 turbulencePtr_(nullptr),
51 daTurbulenceModelPtr_(nullptr),
52 daFvSourcePtr_(nullptr),
53 fvSourcePtr_(nullptr),
71 Info <<
"Initializing fields for DAPimpleFoam" << endl;
78 const word turbModelName(
81 "turbulenceProperties",
82 mesh.time().constant(),
95 if (
allOptions.subDict(
"fvSource").toc().size() != 0)
98 Info <<
"Computing fvSource" << endl;
99 word sourceName =
allOptions.subDict(
"fvSource").toc()[0];
100 word fvSourceType =
allOptions.subDict(
"fvSource").subDict(sourceName).getWord(
"type");
107 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"inputInfo");
108 forAll(dvSubDict.toc(), idxI)
110 word dvName = dvSubDict.toc()[idxI];
111 if (dvSubDict.subDict(dvName).getWord(
"type") ==
"volCoord")
131 Info <<
"\nStarting time loop\n"
134 label pimplePrintToScreen = 0;
137 label reduceIO =
daOptionPtr_->getAllOptions().subDict(
"unsteadyAdjoint").getLabel(
"reduceIO");
138 wordList additionalOutput;
141 daOptionPtr_->getAllOptions().subDict(
"unsteadyAdjoint").readEntry<wordList>(
"additionalOutput", additionalOutput);
144 scalar endTime =
runTime.endTime().value();
145 scalar deltaT =
runTime.deltaT().value();
146 label nInstances = round(endTime / deltaT);
149 label regModelFail = 0;
151 for (label iter = 1; iter <= nInstances; iter++)
162 Info <<
"Time = " <<
runTime.timeName() << nl << endl;
163 #include "CourantNo.H"
171 pimplePrintToScreen = 1;
175 pimplePrintToScreen = 0;
198 regModelFail += fail;
213 if (reduceIO && iter < nInstances)
225 if (regModelFail != 0)
247 scalar adjResNorm = 0.0;
249 label localAdjSize =
daIndexPtr_->nLocalAdjointStates;
252 this->globalADTape_.evaluate();
256 this->globalADTape_.clearAdjoints();
257 for (label i = 0; i < localAdjSize; i++)
259 adjRes[i] -= dFdW[i];
260 adjResNorm += adjRes[i] * adjRes[i];
262 reduce(adjResNorm, sumOp<scalar>());
263 adjResNorm = sqrt(adjResNorm);
279 Info <<
"Solving adjoint using fixed-point iterations" << endl;
281 PetscScalar* psiArray;
282 PetscScalar* dFdWArray;
283 VecGetArray(
psi, &psiArray);
284 VecGetArray(dFdW, &dFdWArray);
286 const fvSolution& myFvSolution =
meshPtr_->thisDb().lookupObject<fvSolution>(
"fvSolution");
287 dictionary solverDictU = myFvSolution.subDict(
"solvers").subDict(
"U");
288 dictionary solverDictP = myFvSolution.subDict(
"solvers").subDict(
"p");
289 scalar fpRelaxU =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").lookupOrDefault<scalar>(
"fpRelaxU", 1.0);
290 scalar fpRelaxP =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").lookupOrDefault<scalar>(
"fpRelaxP", 1.0);
291 scalar fpRelaxPhi =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").lookupOrDefault<scalar>(
"fpRelaxPhi", 1.0);
292 label fpPrintInterval =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").lookupOrDefault<label>(
"fpPrintInterval", 10);
293 label useNonZeroInitGuess =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").getLabel(
"useNonZeroInitGuess");
294 label fpMaxIters =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").getLabel(
"fpMaxIters");
295 scalar fpRelTol =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").getScalar(
"fpRelTol");
297 label localAdjSize =
daIndexPtr_->nLocalAdjointStates;
298 double* adjRes =
new double[localAdjSize];
299 for (label i = 0; i < localAdjSize; i++)
302 if (!useNonZeroInitGuess)
308 volVectorField&
U =
const_cast<volVectorField&
>(
309 meshPtr_->thisDb().lookupObject<volVectorField>(
"U"));
311 volScalarField&
p =
const_cast<volScalarField&
>(
312 meshPtr_->thisDb().lookupObject<volScalarField>(
"p"));
314 surfaceScalarField&
phi =
const_cast<surfaceScalarField&
>(
315 meshPtr_->thisDb().lookupObject<surfaceScalarField>(
"phi"));
319 volVectorField dPsiU(
"dPsiU",
U);
320 volScalarField dPsiP(
"dPsiP",
p);
321 scalarList turbVar(
meshPtr_->nCells(), 0.0);
322 scalarList dPsiTurbVar(
meshPtr_->nCells(), 0.0);
326 fvVectorMatrix psiUPC(
328 + fvm::div(
phi, dPsiU,
"div(phi,U)")
329 - fvm::laplacian(daTurb.
nuEff(), dPsiU));
332 DAUtility::swapLists<scalar>(psiUPC.upper(), psiUPC.lower());
334 forAll(psiUPC.boundaryCoeffs(), patchI)
336 forAll(psiUPC.boundaryCoeffs()[patchI], faceI)
338 psiUPC.boundaryCoeffs()[patchI][faceI] = vector::zero;
343 volScalarField
rAU(1.0 / psiUPC.A());
344 fvScalarMatrix psiPPC(
345 fvm::laplacian(
rAU, dPsiP));
349 forAll(psiPPC.boundaryCoeffs(), patchI)
351 forAll(psiPPC.boundaryCoeffs()[patchI], faceI)
353 psiPPC.boundaryCoeffs()[patchI][faceI] = 0.0;
358 this->globalADTape_.reset();
359 this->globalADTape_.setActive();
365 this->globalADTape_.setPassive();
370 Info <<
"Iter: 0. L2 Norm Residual: " << adjResL2Norm0 <<
". "
373 for (label n = 1; n <= fpMaxIters; n++)
378 for (label comp = 0; comp < 3; comp++)
380 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(
"U", cellI, comp);
381 psiUPC.source()[cellI][comp] = adjRes[localIdx];
386 for (label comp = 0; comp < 3; comp++)
388 dPsiU[cellI][comp] = 0;
391 psiUPC.solve(solverDictU);
395 for (label comp = 0; comp < 3; comp++)
397 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(
"U", cellI, comp);
398 psiArray[localIdx] -= dPsiU[cellI][comp].value() * fpRelaxU.value();
402 for (label i = 0; i < 2; i++)
410 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(
"p", cellI);
411 psiPPC.source()[cellI] = adjRes[localIdx];
417 psiPPC.solve(solverDictP);
421 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(
"p", cellI);
422 psiArray[localIdx] -= dPsiP[cellI].value() * fpRelaxP.value();
430 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(
"phi", faceI);
431 psiArray[localIdx] += adjRes[localIdx] * fpRelaxPhi.value();
442 const word turbVarName =
stateInfo_[
"modelStates"][idxI];
443 scalar fpRelaxTurbVar =
daOptionPtr_->getAllOptions().subDict(
"adjEqnOption").lookupOrDefault<scalar>(
"fpRelax" + turbVarName, 1.0);
446 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(turbVarName, cellI);
447 turbVar[cellI] = adjRes[localIdx];
450 forAll(dPsiTurbVar, cellI)
452 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(turbVarName, cellI);
453 psiArray[localIdx] -= dPsiTurbVar[cellI].value() * fpRelaxTurbVar.value();
459 if (n % fpPrintInterval == 0 || n == fpMaxIters || (adjResL2Norm / adjResL2Norm0) < fpRelTol)
461 Info <<
"Iter: " << n <<
". L2 Norm Residual: " << adjResL2Norm <<
". "
464 if ((adjResL2Norm / adjResL2Norm0) < fpRelTol)
479 VecRestoreArray(
psi, &psiArray);
480 VecRestoreArray(dFdW, &dFdWArray);