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);