39 pyOptions_(pyOptions),
43 daOptionPtr_(nullptr),
47 daCheckMeshPtr_(nullptr),
48 daLinearEqnPtr_(nullptr),
49 daResidualPtr_(nullptr),
50 daRegressionPtr_(nullptr),
51 daGlobalVarPtr_(nullptr),
55 globalADTape_(codi::RealReverse::getTape())
63 Info <<
"Initializing mesh and runtime for DASolver" << endl;
69 if (
allOptions.subDict(
"dynamicMesh").getLabel(
"active"))
99 Info <<
"DAOpton initialized " << endl;
114 allOptions.readEntry<word>(
"solverName", modelType);
116 if (
allOptions.lookupOrDefault<label>(
"debug", 0))
118 Info <<
"Selecting " << modelType <<
" for DASolver" << endl;
121 dictionaryConstructorTable::iterator cstrIter =
122 dictionaryConstructorTablePtr_->find(modelType);
125 if (cstrIter == dictionaryConstructorTablePtr_->end())
133 <<
"Unknown DASolver type "
134 << modelType << nl << nl
135 <<
"Valid DASolver types:" << endl
136 << dictionaryConstructorTablePtr_->sortedToc()
141 return autoPtr<DASolver>(
142 cstrIter()(argsAll, pyOptions));
155 scalar endTime =
runTime.endTime().value();
156 scalar deltaT =
runTime.deltaT().value();
157 scalar t =
runTime.timeOutputValue();
160 functionObjectList& funcObj =
const_cast<functionObjectList&
>(
runTime.functionObjects());
173 Info <<
"Time = " << t << endl;
186 else if (t > endTime - 0.5 * deltaT)
215 if (
daOptionPtr_->getAllOptions().subDict(
"function").toc().size() != 0)
217 FatalErrorIn(
"printAllFunctions") <<
"daFunctionPtrList_.size() ==0... "
218 <<
"Forgot to call setDAFunctionList?"
219 << abort(FatalError);
228 label listIndex = timeIndex - 1;
240 const dictionary& functionDict =
daOptionPtr_->getAllOptions().subDict(
"function").subDict(functionName);
241 label timeOpStartIndex = functionDict.lookupOrDefault<label>(
"timeOpStartIndex", 0);
242 scalar timeOpVal = 0.0;
244 if (timeOpStartIndex <= listIndex)
251 <<
": " << functionVal
252 <<
" " << timeOpType <<
": " << timeOpVal;
254 Info <<
" ADF-Deriv: " << timeOpVal.getGradient();
265 scalar funcVal = 0.0;
271 if (functionName1 == functionName)
273 const dictionary& functionDict =
daOptionPtr_->getAllOptions().subDict(
"function").subDict(functionName);
274 label timeOpStartIndex = functionDict.lookupOrDefault<label>(
"timeOpStartIndex", 0);
276 if (timeOpStartIndex <= listFinalIndex)
283 FatalErrorIn(
"") <<
"timeOpStartIndex can not be larger than listFinalIndex!"
284 << abort(FatalError);
289 return funcVal.getGradient();
293 return funcVal.getValue();
303 const word functionName,
306 scalar scaling = 0.0;
312 if (functionName1 == functionName)
314 const dictionary& functionDict =
daOptionPtr_->getAllOptions().subDict(
"function").subDict(functionName);
315 label timeOpStartIndex = functionDict.lookupOrDefault<label>(
"timeOpStartIndex", 0);
317 if (timeIdx >= timeOpStartIndex && timeIdx <= listFinalIndex)
325 FatalErrorIn(
"getdFScaling") <<
"functionName not found! "
326 << abort(FatalError);
371 const dictionary& functionDict =
allOptions.subDict(
"function");
375 label nFunctions = 0;
376 forAll(functionDict.toc(), idxI)
386 forAll(functionDict.toc(), idxI)
388 word functionName = functionDict.toc()[idxI];
389 dictionary funcSubDict = functionDict.subDict(functionName);
410 label nSteps = round(endTime / deltaT);
423 const dictionary& maxResConLv4JacPCMat,
424 HashTable<List<List<word>>>& stateResConInfo)
const
475 if (maxResConLv4JacPCMat.toc().size() == 0)
477 Info <<
"maxResConLv4JacPCMat is empty, just return" << endl;
483 forAll(stateResConInfo.toc(), idxJ)
485 word key1 = stateResConInfo.toc()[idxJ];
486 bool keyFound =
false;
487 forAll(maxResConLv4JacPCMat.toc(), idxI)
489 word key = maxResConLv4JacPCMat.toc()[idxI];
493 label maxLv = maxResConLv4JacPCMat.getLabel(key);
494 label maxLv1 = stateResConInfo[key1].size() - 1;
497 FatalErrorIn(
"") <<
"maxResConLv4JacPCMat maxLevel"
498 << maxLv <<
" for " << key
499 <<
" larger than stateResConInfo maxLevel "
500 << maxLv1 <<
" for " << key1
501 << abort(FatalError);
507 FatalErrorIn(
"") << key1 <<
" not found in maxResConLv4JacPCMat"
508 << abort(FatalError);
514 Info <<
"Reducing max connectivity level of Jacobian PC Mat to : ";
515 Info << maxResConLv4JacPCMat << endl;
519 HashTable<List<List<word>>> stateResConInfoBK;
520 forAll(stateResConInfo.toc(), idxI)
522 word key = stateResConInfo.toc()[idxI];
523 stateResConInfoBK.set(key, stateResConInfo[key]);
527 stateResConInfo.clearStorage();
530 forAll(stateResConInfoBK.toc(), idxI)
532 word key = stateResConInfoBK.toc()[idxI];
533 label maxConLevel = maxResConLv4JacPCMat.getLabel(key);
534 label conSize = stateResConInfoBK[key].size();
535 if (conSize > maxConLevel + 1)
537 List<List<word>> conList;
538 conList.setSize(maxConLevel + 1);
539 for (label i = 0; i <= maxConLevel; i++)
541 conList[i] = stateResConInfoBK[key][i];
543 stateResConInfo.set(key, conList);
547 stateResConInfo.set(key, stateResConInfoBK[key]);
567 const HashTable<List<List<word>>>& stateResConInfo =
daStateInfoPtr_->getStateResConInfo();
568 options.set(
"stateResConInfo", stateResConInfo);
579 Info <<
"dRdWCon Created. " <<
meshPtr_->time().elapsedCpuTime() <<
" s" << endl;
582 Info <<
"Calculating dRdW Coloring... " <<
meshPtr_->time().elapsedCpuTime() <<
" s" << endl;
584 Info <<
"Calculating dRdW Coloring... Completed! " <<
meshPtr_->time().elapsedCpuTime() <<
" s" << endl;
593 const label writeRes)
603 Info <<
"Printing Primal Residual Statistics." << endl;
605 else if (
mode ==
"calc")
611 FatalErrorIn(
"") <<
"mode not valid" << abort(FatalError);
618 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
619 const word resName = stateName +
"Res";
620 const volVectorField& stateRes =
meshPtr_->thisDb().lookupObject<volVectorField>(resName);
622 vector vecResMax(0, 0, 0);
623 vector vecResNorm2(0, 0, 0);
624 vector vecResMean(0, 0, 0);
627 vecResNorm2.x() += pow(stateRes[cellI].x(), 2.0);
628 vecResNorm2.y() += pow(stateRes[cellI].y(), 2.0);
629 vecResNorm2.z() += pow(stateRes[cellI].z(), 2.0);
630 vecResMean.x() += fabs(stateRes[cellI].x());
631 vecResMean.y() += fabs(stateRes[cellI].y());
632 vecResMean.z() += fabs(stateRes[cellI].z());
633 if (fabs(stateRes[cellI].x()) > vecResMax.x())
635 vecResMax.x() = fabs(stateRes[cellI].x());
637 if (fabs(stateRes[cellI].y()) > vecResMax.y())
639 vecResMax.y() = fabs(stateRes[cellI].y());
641 if (fabs(stateRes[cellI].z()) > vecResMax.z())
643 vecResMax.z() = fabs(stateRes[cellI].z());
646 vecResMean = vecResMean / stateRes.size();
647 reduce(vecResMean, sumOp<vector>());
648 vecResMean = vecResMean / Pstream::nProcs();
649 reduce(vecResNorm2, sumOp<vector>());
650 reduce(vecResMax, maxOp<vector>());
651 vecResNorm2.x() = pow(vecResNorm2.x(), 0.5);
652 vecResNorm2.y() = pow(vecResNorm2.y(), 0.5);
653 vecResNorm2.z() = pow(vecResNorm2.z(), 0.5);
656 Info << stateName <<
" Residual Norm2: " << vecResNorm2 << endl;
657 Info << stateName <<
" Residual Mean: " << vecResMean << endl;
658 Info << stateName <<
" Residual Max: " << vecResMax << endl;
669 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
670 const word resName = stateName +
"Res";
671 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
673 scalar scalarResMax = 0, scalarResNorm2 = 0, scalarResMean = 0;
676 scalarResNorm2 += pow(stateRes[cellI], 2.0);
677 scalarResMean += fabs(stateRes[cellI]);
678 if (fabs(stateRes[cellI]) > scalarResMax)
679 scalarResMax = fabs(stateRes[cellI]);
681 scalarResMean = scalarResMean / stateRes.size();
682 reduce(scalarResMean, sumOp<scalar>());
683 scalarResMean = scalarResMean / Pstream::nProcs();
684 reduce(scalarResNorm2, sumOp<scalar>());
685 reduce(scalarResMax, maxOp<scalar>());
686 scalarResNorm2 = pow(scalarResNorm2, 0.5);
689 Info << stateName <<
" Residual Norm2: " << scalarResNorm2 << endl;
690 Info << stateName <<
" Residual Mean: " << scalarResMean << endl;
691 Info << stateName <<
" Residual Max: " << scalarResMax << endl;
702 const word stateName =
stateInfo_[
"modelStates"][idxI];
703 const word resName = stateName +
"Res";
704 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
706 scalar scalarResMax = 0, scalarResNorm2 = 0, scalarResMean = 0;
709 scalarResNorm2 += pow(stateRes[cellI], 2.0);
710 scalarResMean += fabs(stateRes[cellI]);
711 if (fabs(stateRes[cellI]) > scalarResMax)
712 scalarResMax = fabs(stateRes[cellI]);
714 scalarResMean = scalarResMean / stateRes.size();
715 reduce(scalarResMean, sumOp<scalar>());
716 scalarResMean = scalarResMean / Pstream::nProcs();
717 reduce(scalarResNorm2, sumOp<scalar>());
718 reduce(scalarResMax, maxOp<scalar>());
719 scalarResNorm2 = pow(scalarResNorm2, 0.5);
722 Info << stateName <<
" Residual Norm2: " << scalarResNorm2 << endl;
723 Info << stateName <<
" Residual Mean: " << scalarResMean << endl;
724 Info << stateName <<
" Residual Max: " << scalarResMax << endl;
735 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
736 const word resName = stateName +
"Res";
737 const surfaceScalarField& stateRes =
meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName);
739 scalar phiResMax = 0, phiResNorm2 = 0, phiResMean = 0;
742 phiResNorm2 += pow(stateRes[faceI], 2.0);
743 phiResMean += fabs(stateRes[faceI]);
744 if (fabs(stateRes[faceI]) > phiResMax)
745 phiResMax = fabs(stateRes[faceI]);
747 forAll(stateRes.boundaryField(), patchI)
749 forAll(stateRes.boundaryField()[patchI], faceI)
751 scalar bPhiRes = stateRes.boundaryField()[patchI][faceI];
752 phiResNorm2 += pow(bPhiRes, 2.0);
753 phiResMean += fabs(bPhiRes);
754 if (fabs(bPhiRes) > phiResMax)
755 phiResMax = fabs(bPhiRes);
758 phiResMean = phiResMean /
meshPtr_->nFaces();
759 reduce(phiResMean, sumOp<scalar>());
760 phiResMean = phiResMean / Pstream::nProcs();
761 reduce(phiResNorm2, sumOp<scalar>());
762 reduce(phiResMax, maxOp<scalar>());
763 phiResNorm2 = pow(phiResNorm2, 0.5);
766 Info << stateName <<
" Residual Norm2: " << phiResNorm2 << endl;
767 Info << stateName <<
" Residual Mean: " << phiResMean << endl;
768 Info << stateName <<
" Residual Max: " << phiResMax << endl;
803 VecCreate(PETSC_COMM_WORLD, &wVec);
804 VecSetSizes(wVec,
daIndexPtr_->nLocalAdjointStates, PETSC_DECIDE);
805 VecSetFromOptions(wVec);
808 VecCreate(PETSC_COMM_WORLD, &xvVec);
809 VecSetSizes(xvVec, nXvs, PETSC_DECIDE);
810 VecSetFromOptions(xvVec);
826 FatalErrorIn(
"") <<
"isPC " << isPC <<
" not supported! "
827 <<
"Options are: 0 (for dRdWT) and 1 (for dRdWTPC)." << abort(FatalError);
835 Info <<
"Computing " << matName <<
" " <<
runTimePtr_->elapsedCpuTime() <<
" s" << endl;
836 Info <<
"Initializing dRdWCon. " <<
runTimePtr_->elapsedCpuTime() <<
" s" << endl;
839 word modelType =
"dRdW";
848 const HashTable<List<List<word>>>& stateResConInfo =
daStateInfoPtr_->getStateResConInfo();
853 HashTable<List<List<word>>> stateResConInfoReduced = stateResConInfo;
855 dictionary maxResConLv4JacPCMat =
daOptionPtr_->getAllOptions().subDict(
"maxResConLv4JacPCMat");
858 options.set(
"stateResConInfo", stateResConInfoReduced);
862 options.set(
"stateResConInfo", stateResConInfo);
874 Info <<
"dRdWCon Created. " <<
runTimePtr_->elapsedCpuTime() <<
" s" << endl;
891 options1.set(
"transposed", 1);
892 options1.set(
"isPC", isPC);
896 options1.set(
"lowerBound",
daOptionPtr_->getSubDictOption<scalar>(
"jacLowerBounds",
"dRdWPC"));
900 options1.set(
"lowerBound",
daOptionPtr_->getSubDictOption<scalar>(
"jacLowerBounds",
"dRdW"));
914 wordList writeJacobians;
915 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
916 if (writeJacobians.found(
"dRdWT") || writeJacobians.found(
"all"))
933 KSPSetOperators(ksp,
dRdWTMF_, PCMat);
994 pointField meshPoints(
meshPtr_->points());
996 forAll(meshPoints, pointI)
998 for (label i = 0; i < 3; i++)
1007 const word fieldName,
1008 const word fieldType,
1016 if (fieldType ==
"scalar")
1018 const volScalarField& field =
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName);
1024 else if (fieldType ==
"vector")
1026 const volVectorField& field =
meshPtr_->thisDb().lookupObject<volVectorField>(fieldName);
1030 for (label comp = 0; comp < 3; comp++)
1039 FatalErrorIn(
"getField") <<
" fieldType not valid. Options: scalar or vector"
1040 << abort(FatalError);
1046 label printInfo = 0;
1049 Info <<
"Updating the OpenFOAM field..." << endl;
1071 Info <<
"Updating the OpenFOAM mesh..." << endl;
1093 Info <<
"In initializedRdWTMatrixFree" << endl;
1099 label localSize =
daIndexPtr_->nLocalAdjointStates;
1100 MatCreateShell(PETSC_COMM_WORLD, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE,
this, &
dRdWTMF_);
1103 Info <<
"dRdWT Jacobian Free created!" << endl;
1130 MatShellGetContext(dRdWTMF, (
void**)&ctx);
1138 if (!ctx->globalADTape4dRdWTInitialized)
1140 ctx->initializeGlobalADTape4dRdWT();
1141 ctx->globalADTape4dRdWTInitialized = 1;
1144 PetscScalar* vecArray;
1145 const PetscScalar* vecArrayRead;
1147 VecGetArrayRead(vecX, &vecArrayRead);
1148 ctx->assignVec2ResidualGradient(vecArrayRead);
1149 VecRestoreArrayRead(vecX, &vecArrayRead);
1151 ctx->globalADTape_.evaluate();
1153 VecGetArray(vecY, &vecArray);
1154 ctx->assignStateGradient2Vec(vecArray);
1156 ctx->normalizeGradientVec(vecArray);
1157 VecRestoreArray(vecY, &vecArray);
1159 ctx->globalADTape_.clearAdjoints();
1180 this->globalADTape_.reset();
1182 this->globalADTape_.setActive();
1192 this->globalADTape_.setPassive();
1199 const word inputName,
1203 #if defined(CODI_ADF) || defined(CODI_ADR)
1220 if (inputName ==
"stateVar")
1223 dictionary normStateDict =
daOptionPtr_->getAllOptions().subDict(
"normalizeStates");
1227 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
1229 if (normStateDict.found(stateName))
1231 scalar scalingFactor = normStateDict.getScalar(stateName);
1235 for (label i = 0; i < 3; i++)
1237 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
1238 product[localIdx] *= scalingFactor.getValue();
1246 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
1248 if (normStateDict.found(stateName))
1250 scalar scalingFactor = normStateDict.getScalar(stateName);
1254 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
1255 product[localIdx] *= scalingFactor.getValue();
1262 const word stateName =
stateInfo_[
"modelStates"][idxI];
1264 if (normStateDict.found(stateName))
1267 scalar scalingFactor = normStateDict.getScalar(stateName);
1271 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
1272 product[localIdx] *= scalingFactor.getValue();
1279 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
1281 if (normStateDict.found(stateName))
1283 scalar scalingFactor = normStateDict.getScalar(stateName);
1287 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
1289 if (faceI < daIndexPtr_->nLocalInternalFaces)
1291 scalar meshSf =
meshPtr_->magSf()[faceI];
1292 product[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
1296 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
1297 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
1299 scalar meshSf =
meshPtr_->magSf().boundaryField()[patchIdx][faceIdx];
1300 product[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
1311 const word inputName,
1312 const word inputType,
1313 const int inputSize,
1314 const double* input,
1323 autoPtr<DAInput> daInput(
1332 scalarList inputList(inputSize, 0.0);
1338 inputList[idxI] = input[idxI];
1340 inputList[idxI].gradient() = seed[idxI];
1345 daInput->run(inputList);
1349 const word inputName,
1350 const word inputType)
1352 autoPtr<DAInput> daInput(
1361 return daInput->size();
1365 const word outputName,
1366 const word outputType)
1368 autoPtr<DAOutput> daOutput(
1379 return daOutput->size();
1384 const word outputName,
1385 const word outputType,
1388 autoPtr<DAOutput> daOutput(
1399 label outputSize = daOutput->size();
1401 scalarList outputList(outputSize, 0.0);
1403 daOutput->run(outputList);
1412 const word inputName,
1413 const word inputType)
1415 autoPtr<DAInput> daInput(
1424 return daInput->distributed();
1428 const word outputName,
1429 const word outputType)
1431 autoPtr<DAOutput> daOutput(
1442 return daOutput->distributed();
1446 const word inputName,
1447 const word inputType,
1448 const double* input,
1449 const word outputName,
1450 const word outputType,
1476 Info <<
"Computing d[" << outputName <<
"]/d[" << inputName <<
"]^T * psi " <<
runTimePtr_->elapsedCpuTime() <<
" s" << endl;
1479 autoPtr<DAInput> daInput(
1488 autoPtr<DAOutput> daOutput(
1499 label inputSize = daInput->size();
1500 label outputSize = daOutput->size();
1503 scalarList inputList(inputSize, 0.0);
1504 scalarList outputList(outputSize, 0.0);
1510 inputList[idxI] = input[idxI];
1514 this->globalADTape_.reset();
1516 this->globalADTape_.setActive();
1520 this->globalADTape_.registerInput(inputList[idxI]);
1523 daInput->run(inputList);
1527 daOutput->run(outputList);
1531 this->globalADTape_.registerOutput(outputList[idxI]);
1534 this->globalADTape_.setPassive();
1541 if (daOutput().distributed())
1544 outputList[idxI].setGradient(seed[idxI]);
1549 if (Pstream::master())
1551 outputList[idxI].setGradient(seed[idxI]);
1556 this->globalADTape_.evaluate();
1561 product[idxI] = inputList[idxI].getGradient();
1564 if (!daInput().distributed())
1566 reduce(product[idxI], sumOp<double>());
1574 this->globalADTape_.clearAdjoints();
1575 this->globalADTape_.reset();
1583 this->globalADTape_.deactivateValue(inputList[idxI]);
1585 daInput->run(inputList);
1587 daOutput->run(outputList);
1593 const scalar* volCoords,
1610 wordList components;
1611 dictionary outputInfo =
daOptionPtr_->getAllOptions().subDict(
"outputInfo");
1612 forAll(outputInfo.toc(), idxI)
1614 word outputName = outputInfo.toc()[idxI];
1615 outputInfo.subDict(outputName).readEntry(
"components", components);
1616 if (components.found(
"thermalCoupling"))
1618 outputInfo.subDict(outputName).readEntry(
"patches", patches);
1626 label counterFaceI = 0;
1630 label patchI =
meshPtr_->boundaryMesh().findPatchID(patches[cI]);
1633 for (label i = 0; i < 3; i++)
1635 surfCoords[counterFaceI] =
meshPtr_->Cf().boundaryField()[patchI][faceI][i];
1649 label patchI =
meshPtr_->boundaryMesh().findPatchID(patches[cI]);
1652 for (label i = 0; i < 3; i++)
1654 surfCoords[counterFaceI] =
meshPtr_->Cf().boundaryField()[patchI][faceI][i] + 1000.0;
1662 const label oldTimeLevel,
1664 double* dRdWOldTPsi)
1687 Info <<
"Computing [dRdWOld]^T * psi: level " << oldTimeLevel <<
". " <<
runTimePtr_->elapsedCpuTime() <<
" s" << endl;
1689 this->globalADTape_.reset();
1690 this->globalADTape_.setActive();
1699 this->globalADTape_.setPassive();
1702 this->globalADTape_.evaluate();
1710 this->globalADTape_.clearAdjoints();
1711 this->globalADTape_.reset();
1737 if (oldTimeLevel < 0 || oldTimeLevel > 2)
1739 FatalErrorIn(
"") <<
"oldTimeLevel not valid. Options: 0, 1, or 2"
1740 << abort(FatalError);
1745 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
1746 volVectorField& state =
const_cast<volVectorField&
>(
1747 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
1749 label maxOldTimes = state.nOldTimes();
1751 if (maxOldTimes >= oldTimeLevel)
1755 for (label i = 0; i < 3; i++)
1757 if (oldTimeLevel == 0)
1759 this->globalADTape_.registerInput(state[cellI][i]);
1761 else if (oldTimeLevel == 1)
1763 this->globalADTape_.registerInput(state.oldTime()[cellI][i]);
1765 else if (oldTimeLevel == 2)
1767 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI][i]);
1776 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
1777 volScalarField& state =
const_cast<volScalarField&
>(
1778 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
1780 label maxOldTimes = state.nOldTimes();
1782 if (maxOldTimes >= oldTimeLevel)
1786 if (oldTimeLevel == 0)
1788 this->globalADTape_.registerInput(state[cellI]);
1790 else if (oldTimeLevel == 1)
1792 this->globalADTape_.registerInput(state.oldTime()[cellI]);
1794 else if (oldTimeLevel == 2)
1796 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI]);
1804 const word stateName =
stateInfo_[
"modelStates"][idxI];
1805 volScalarField& state =
const_cast<volScalarField&
>(
1806 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
1808 label maxOldTimes = state.nOldTimes();
1810 if (maxOldTimes >= oldTimeLevel)
1814 if (oldTimeLevel == 0)
1816 this->globalADTape_.registerInput(state[cellI]);
1818 else if (oldTimeLevel == 1)
1820 this->globalADTape_.registerInput(state.oldTime()[cellI]);
1822 else if (oldTimeLevel == 2)
1824 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI]);
1832 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
1833 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
1834 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
1836 label maxOldTimes = state.nOldTimes();
1838 if (maxOldTimes >= oldTimeLevel)
1842 if (oldTimeLevel == 0)
1844 this->globalADTape_.registerInput(state[faceI]);
1846 else if (oldTimeLevel == 1)
1848 this->globalADTape_.registerInput(state.oldTime()[faceI]);
1850 else if (oldTimeLevel == 2)
1852 this->globalADTape_.registerInput(state.oldTime().oldTime()[faceI]);
1855 forAll(state.boundaryField(), patchI)
1857 forAll(state.boundaryField()[patchI], faceI)
1859 if (oldTimeLevel == 0)
1861 this->globalADTape_.registerInput(state.boundaryFieldRef()[patchI][faceI]);
1863 else if (oldTimeLevel == 1)
1865 this->globalADTape_.registerInput(state.oldTime().boundaryFieldRef()[patchI][faceI]);
1867 else if (oldTimeLevel == 2)
1869 this->globalADTape_.registerInput(state.oldTime().oldTime().boundaryFieldRef()[patchI][faceI]);
1893 if (oldTimeLevel < 0 || oldTimeLevel > 2)
1895 FatalErrorIn(
"") <<
"oldTimeLevel not valid. Options: 0, 1, or 2"
1896 << abort(FatalError);
1901 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
1902 volVectorField& state =
const_cast<volVectorField&
>(
1903 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
1905 label maxOldTimes = state.nOldTimes();
1907 if (maxOldTimes >= oldTimeLevel)
1911 for (label i = 0; i < 3; i++)
1913 if (oldTimeLevel == 0)
1915 this->globalADTape_.deactivateValue(state[cellI][i]);
1917 else if (oldTimeLevel == 1)
1919 this->globalADTape_.deactivateValue(state.oldTime()[cellI][i]);
1921 else if (oldTimeLevel == 2)
1923 this->globalADTape_.deactivateValue(state.oldTime().oldTime()[cellI][i]);
1932 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
1933 volScalarField& state =
const_cast<volScalarField&
>(
1934 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
1936 label maxOldTimes = state.nOldTimes();
1938 if (maxOldTimes >= oldTimeLevel)
1942 if (oldTimeLevel == 0)
1944 this->globalADTape_.deactivateValue(state[cellI]);
1946 else if (oldTimeLevel == 1)
1948 this->globalADTape_.deactivateValue(state.oldTime()[cellI]);
1950 else if (oldTimeLevel == 2)
1952 this->globalADTape_.deactivateValue(state.oldTime().oldTime()[cellI]);
1960 const word stateName =
stateInfo_[
"modelStates"][idxI];
1961 volScalarField& state =
const_cast<volScalarField&
>(
1962 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
1964 label maxOldTimes = state.nOldTimes();
1966 if (maxOldTimes >= oldTimeLevel)
1970 if (oldTimeLevel == 0)
1972 this->globalADTape_.deactivateValue(state[cellI]);
1974 else if (oldTimeLevel == 1)
1976 this->globalADTape_.deactivateValue(state.oldTime()[cellI]);
1978 else if (oldTimeLevel == 2)
1980 this->globalADTape_.deactivateValue(state.oldTime().oldTime()[cellI]);
1988 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
1989 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
1990 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
1992 label maxOldTimes = state.nOldTimes();
1994 if (maxOldTimes >= oldTimeLevel)
1998 if (oldTimeLevel == 0)
2000 this->globalADTape_.deactivateValue(state[faceI]);
2002 else if (oldTimeLevel == 1)
2004 this->globalADTape_.deactivateValue(state.oldTime()[faceI]);
2006 else if (oldTimeLevel == 2)
2008 this->globalADTape_.deactivateValue(state.oldTime().oldTime()[faceI]);
2011 forAll(state.boundaryField(), patchI)
2013 forAll(state.boundaryField()[patchI], faceI)
2015 if (oldTimeLevel == 0)
2017 this->globalADTape_.deactivateValue(state.boundaryFieldRef()[patchI][faceI]);
2019 else if (oldTimeLevel == 1)
2021 this->globalADTape_.deactivateValue(state.oldTime().boundaryFieldRef()[patchI][faceI]);
2023 else if (oldTimeLevel == 2)
2025 this->globalADTape_.deactivateValue(state.oldTime().oldTime().boundaryFieldRef()[patchI][faceI]);
2045 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2046 const word stateResName = stateName +
"Res";
2047 volVectorField& stateRes =
const_cast<volVectorField&
>(
2048 meshPtr_->thisDb().lookupObject<volVectorField>(stateResName));
2052 for (label i = 0; i < 3; i++)
2054 this->globalADTape_.registerOutput(stateRes[cellI][i]);
2061 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2062 const word stateResName = stateName +
"Res";
2063 volScalarField& stateRes =
const_cast<volScalarField&
>(
2064 meshPtr_->thisDb().lookupObject<volScalarField>(stateResName));
2068 this->globalADTape_.registerOutput(stateRes[cellI]);
2074 const word stateName =
stateInfo_[
"modelStates"][idxI];
2075 const word stateResName = stateName +
"Res";
2076 volScalarField& stateRes =
const_cast<volScalarField&
>(
2077 meshPtr_->thisDb().lookupObject<volScalarField>(stateResName));
2081 this->globalADTape_.registerOutput(stateRes[cellI]);
2087 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2088 const word stateResName = stateName +
"Res";
2089 surfaceScalarField& stateRes =
const_cast<surfaceScalarField&
>(
2090 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateResName));
2094 this->globalADTape_.registerOutput(stateRes[faceI]);
2096 forAll(stateRes.boundaryField(), patchI)
2098 forAll(stateRes.boundaryField()[patchI], faceI)
2100 this->globalADTape_.registerOutput(stateRes.boundaryFieldRef()[patchI][faceI]);
2109 #if defined(CODI_ADF) || defined(CODI_ADR)
2121 dictionary normStateDict =
daOptionPtr_->getAllOptions().subDict(
"normalizeStates");
2125 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2127 if (normStateDict.found(stateName))
2130 scalar scalingFactor = normStateDict.getScalar(stateName);
2134 for (label i = 0; i < 3; i++)
2136 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
2137 vecArray[localIdx] *= scalingFactor.getValue();
2145 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2147 if (normStateDict.found(stateName))
2149 scalar scalingFactor = normStateDict.getScalar(stateName);
2153 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2154 vecArray[localIdx] *= scalingFactor.getValue();
2161 const word stateName =
stateInfo_[
"modelStates"][idxI];
2163 if (normStateDict.found(stateName))
2166 scalar scalingFactor = normStateDict.getScalar(stateName);
2170 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2171 vecArray[localIdx] *= scalingFactor.getValue();
2178 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2180 if (normStateDict.found(stateName))
2182 scalar scalingFactor = normStateDict.getScalar(stateName);
2186 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
2188 if (faceI < daIndexPtr_->nLocalInternalFaces)
2190 scalar meshSf =
meshPtr_->magSf()[faceI];
2191 vecArray[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
2195 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
2196 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
2198 scalar meshSf =
meshPtr_->magSf().boundaryField()[patchIdx][faceIdx];
2199 vecArray[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
2210 #if defined(CODI_ADF) || defined(CODI_ADR)
2224 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2225 const word resName = stateName +
"Res";
2226 volVectorField& stateRes =
const_cast<volVectorField&
>(
2227 meshPtr_->thisDb().lookupObject<volVectorField>(resName));
2231 for (label i = 0; i < 3; i++)
2233 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
2234 stateRes[cellI][i].setGradient(vecArray[localIdx]);
2241 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2242 const word resName = stateName +
"Res";
2243 volScalarField& stateRes =
const_cast<volScalarField&
>(
2244 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
2248 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2249 stateRes[cellI].setGradient(vecArray[localIdx]);
2255 const word stateName =
stateInfo_[
"modelStates"][idxI];
2256 const word resName = stateName +
"Res";
2257 volScalarField& stateRes =
const_cast<volScalarField&
>(
2258 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
2262 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2263 stateRes[cellI].setGradient(vecArray[localIdx]);
2269 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2270 const word resName = stateName +
"Res";
2271 surfaceScalarField& stateRes =
const_cast<surfaceScalarField&
>(
2272 meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName));
2276 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
2278 if (faceI < daIndexPtr_->nLocalInternalFaces)
2280 stateRes[faceI].setGradient(vecArray[localIdx]);
2284 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
2285 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
2287 stateRes.boundaryFieldRef()[patchIdx][faceIdx].setGradient(vecArray[localIdx]);
2297 const label oldTimeLevel)
2299 #if defined(CODI_ADF) || defined(CODI_ADR)
2318 if (oldTimeLevel < 0 || oldTimeLevel > 2)
2320 FatalErrorIn(
"") <<
"oldTimeLevel not valid. Options: 0, 1, or 2"
2321 << abort(FatalError);
2326 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2327 volVectorField& state =
const_cast<volVectorField&
>(
2328 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
2330 label maxOldTimes = state.nOldTimes();
2332 if (maxOldTimes >= oldTimeLevel)
2336 for (label i = 0; i < 3; i++)
2338 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
2339 if (oldTimeLevel == 0)
2341 vecArray[localIdx] = state[cellI][i].getGradient();
2343 else if (oldTimeLevel == 1)
2345 vecArray[localIdx] = state.oldTime()[cellI][i].getGradient();
2347 else if (oldTimeLevel == 2)
2349 vecArray[localIdx] = state.oldTime().oldTime()[cellI][i].getGradient();
2358 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2359 volScalarField& state =
const_cast<volScalarField&
>(
2360 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
2362 label maxOldTimes = state.nOldTimes();
2364 if (maxOldTimes >= oldTimeLevel)
2368 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2369 if (oldTimeLevel == 0)
2371 vecArray[localIdx] = state[cellI].getGradient();
2373 else if (oldTimeLevel == 1)
2375 vecArray[localIdx] = state.oldTime()[cellI].getGradient();
2377 else if (oldTimeLevel == 2)
2379 vecArray[localIdx] = state.oldTime().oldTime()[cellI].getGradient();
2387 const word stateName =
stateInfo_[
"modelStates"][idxI];
2388 volScalarField& state =
const_cast<volScalarField&
>(
2389 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
2391 label maxOldTimes = state.nOldTimes();
2393 if (maxOldTimes >= oldTimeLevel)
2397 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
2398 if (oldTimeLevel == 0)
2400 vecArray[localIdx] = state[cellI].getGradient();
2402 else if (oldTimeLevel == 1)
2404 vecArray[localIdx] = state.oldTime()[cellI].getGradient();
2406 else if (oldTimeLevel == 2)
2408 vecArray[localIdx] = state.oldTime().oldTime()[cellI].getGradient();
2416 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2417 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
2418 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
2420 label maxOldTimes = state.nOldTimes();
2422 if (maxOldTimes >= oldTimeLevel)
2426 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
2428 if (faceI < daIndexPtr_->nLocalInternalFaces)
2430 if (oldTimeLevel == 0)
2432 vecArray[localIdx] = state[faceI].getGradient();
2434 else if (oldTimeLevel == 1)
2436 vecArray[localIdx] = state.oldTime()[faceI].getGradient();
2438 else if (oldTimeLevel == 2)
2440 vecArray[localIdx] = state.oldTime().oldTime()[faceI].getGradient();
2445 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
2446 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
2449 if (oldTimeLevel == 0)
2451 vecArray[localIdx] =
2452 state.boundaryField()[patchIdx][faceIdx].getGradient();
2454 else if (oldTimeLevel == 1)
2456 vecArray[localIdx] =
2457 state.oldTime().boundaryField()[patchIdx][faceIdx].getGradient();
2459 else if (oldTimeLevel == 2)
2461 vecArray[localIdx] =
2462 state.oldTime().oldTime().boundaryField()[patchIdx][faceIdx].getGradient();
2485 Info <<
"Regression model computation has invalid values. Primal solution failed!" << endl;
2489 scalar tolMax =
daOptionPtr_->getOption<scalar>(
"primalMinResTolDiff");
2492 Info <<
"********************************************" << endl;
2493 Info <<
"Primal min residual " <<
daGlobalVarPtr_->primalMaxRes << endl
2494 <<
"did not satisfy the prescribed tolerance "
2496 Info <<
"Primal solution failed!" << endl;
2497 Info <<
"********************************************" << endl;
2510 const label printInterval)
const
2516 if (
runTime.timeIndex() % printInterval == 0 ||
runTime.timeIndex() == 1)
2537 IOobject::MUST_READ,
2541 if (MRFIO.typeHeaderOk<IOdictionary>(
true))
2543 IOdictionary MRFProperties(MRFIO);
2545 bool activeMRF(MRFProperties.subDict(
"MRF").lookupOrDefault(
"active",
true));
2549 const volVectorField&
U =
meshPtr_->thisDb().lookupObject<volVectorField>(
"U");
2551 volVectorField
URel(
"URel",
U);
2560 const word fieldName,
2561 const word fieldType)
2573 if (fieldType ==
"scalar")
2575 volScalarField& field =
2576 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
2577 field.correctBoundaryConditions();
2579 else if (fieldType ==
"vector")
2581 volVectorField& field =
2582 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
2583 field.correctBoundaryConditions();
2587 FatalErrorIn(
"") << fieldType <<
" not support. Options are: vector or scalar "
2588 << abort(FatalError);
2603 options.set(
"isPC", isPC);
2615 label nBCCalls =
daOptionPtr_->getOption<label>(
"maxCorrectBCCalls");
2617 for (label i = 0; i < nBCCalls; i++)
2653 const labelUList& owner =
meshPtr_->owner();
2654 const labelUList& neighbour =
meshPtr_->neighbour();
2658 dictionary normStateDict =
daOptionPtr_->getAllOptions().subDict(
"normalizeStates");
2659 wordList normResDict =
daOptionPtr_->getOption<wordList>(
"normalizeResiduals");
2662 const word stateName =
stateInfo_[
"modelStates"][idxI];
2663 const word resName = stateName +
"Res";
2665 label nInternalFaces =
daIndexPtr_->nLocalInternalFaces;
2666 scalarField
D(nCells, 0.0);
2667 scalarField upper(nInternalFaces, 0.0);
2668 scalarField lower(nInternalFaces, 0.0);
2671 scalar stateScaling = 1.0;
2672 if (normStateDict.found(stateName))
2674 stateScaling = normStateDict.getScalar(stateName);
2676 scalar resScaling = 1.0;
2680 if (normResDict.found(resName))
2685 PetscInt rowI =
daIndexPtr_->getGlobalAdjointStateIndex(stateName, cellI);
2686 PetscInt colI = rowI;
2687 scalar val1 =
D[cellI] * stateScaling / resScaling;
2689 MatSetValues(PCMat, 1, &rowI, 1, &colI, &val, INSERT_VALUES);
2693 for (label faceI = 0; faceI <
daIndexPtr_->nLocalInternalFaces; faceI++)
2695 label ownerCellI = owner[faceI];
2696 label neighbourCellI = neighbour[faceI];
2698 if (normResDict.found(resName))
2700 resScaling =
meshPtr_->V()[neighbourCellI];
2703 PetscInt rowI =
daIndexPtr_->getGlobalAdjointStateIndex(stateName, neighbourCellI);
2704 PetscInt colI =
daIndexPtr_->getGlobalAdjointStateIndex(stateName, ownerCellI);
2705 scalar val1 = lower[faceI] * stateScaling / resScaling;
2707 MatSetValues(PCMat, 1, &colI, 1, &rowI, &val, INSERT_VALUES);
2711 for (label faceI = 0; faceI <
daIndexPtr_->nLocalInternalFaces; faceI++)
2713 label ownerCellI = owner[faceI];
2714 label neighbourCellI = neighbour[faceI];
2716 if (normResDict.found(resName))
2718 resScaling =
meshPtr_->V()[ownerCellI];
2721 PetscInt rowI =
daIndexPtr_->getGlobalAdjointStateIndex(stateName, ownerCellI);
2722 PetscInt colI =
daIndexPtr_->getGlobalAdjointStateIndex(stateName, neighbourCellI);
2723 scalar val1 = upper[faceI] * stateScaling / resScaling;
2725 MatSetValues(PCMat, 1, &colI, 1, &rowI, &val, INSERT_VALUES);
2729 MatAssemblyBegin(PCMat, MAT_FINAL_ASSEMBLY);
2730 MatAssemblyEnd(PCMat, MAT_FINAL_ASSEMBLY);
2779 const label writeMesh,
2780 const wordList& additionalOutput)
2793 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2794 volVectorField& state =
2795 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
2803 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2804 volScalarField& state =
2805 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
2813 const word stateName =
stateInfo_[
"modelStates"][idxI];
2814 volScalarField& state =
2815 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
2823 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2824 surfaceScalarField& state =
2825 const_cast<surfaceScalarField&
>(
meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
2831 forAll(additionalOutput, idxI)
2833 word varName = additionalOutput[idxI];
2835 if (varName ==
"None")
2840 if (
meshPtr_->thisDb().foundObject<volScalarField>(varName))
2842 volScalarField& var =
2843 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(varName));
2847 else if (
meshPtr_->thisDb().foundObject<volVectorField>(varName))
2849 volVectorField& var =
2850 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(varName));
2854 else if (
meshPtr_->thisDb().foundObject<surfaceScalarField>(varName))
2856 surfaceScalarField& var =
2857 const_cast<surfaceScalarField&
>(
meshPtr_->thisDb().lookupObject<surfaceScalarField>(varName));
2863 Info <<
"Warning! The prescribed additionalOutput " << varName <<
" not found in the db! Ignoring it.." << endl;
2869 pointIOField points =
meshPtr_->thisDb().lookupObject<pointIOField>(
"points");
2886 pointIOField readPoints(
2889 Foam::name(timeVal),
2892 IOobject::MUST_READ,
2893 IOobject::NO_WRITE));
2909 pointIOField writePoints(
2912 Foam::name(timeVal),
2923 forAll(writePoints, pointI)
2925 for (label i = 0; i < 3; i++)
2927 writePoints[pointI][i] = points[counterI];
2935 writePoints.write();
2963 word timeName = Foam::name(timeVal);
2973 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2974 volVectorField& state =
2975 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
2977 volVectorField stateRead(
2982 IOobject::MUST_READ,
2983 IOobject::NO_WRITE),
2986 if (oldTimeLevel == 0)
2990 else if (oldTimeLevel == 1)
2992 state.oldTime() == stateRead;
2994 else if (oldTimeLevel == 2)
2998 volVectorField state0Read(
3003 IOobject::READ_IF_PRESENT,
3004 IOobject::NO_WRITE),
3006 state.oldTime().oldTime() == state0Read;
3010 state.oldTime().oldTime() == stateRead;
3015 FatalErrorIn(
"") <<
"oldTimeLevel can only be 0, 1, and 2!" << abort(FatalError);
3021 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3022 volScalarField& state =
3023 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3025 volScalarField stateRead(
3030 IOobject::MUST_READ,
3031 IOobject::NO_WRITE),
3034 if (oldTimeLevel == 0)
3038 else if (oldTimeLevel == 1)
3040 state.oldTime() == stateRead;
3042 else if (oldTimeLevel == 2)
3046 volScalarField state0Read(
3051 IOobject::READ_IF_PRESENT,
3052 IOobject::NO_WRITE),
3054 state.oldTime().oldTime() == state0Read;
3058 state.oldTime().oldTime() == stateRead;
3063 FatalErrorIn(
"") <<
"oldTimeLevel can only be 0, 1, and 2!" << abort(FatalError);
3069 const word stateName =
stateInfo_[
"modelStates"][idxI];
3070 volScalarField& state =
3071 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3073 volScalarField stateRead(
3078 IOobject::MUST_READ,
3079 IOobject::NO_WRITE),
3082 if (oldTimeLevel == 0)
3086 else if (oldTimeLevel == 1)
3088 state.oldTime() == stateRead;
3090 else if (oldTimeLevel == 2)
3094 volScalarField state0Read(
3099 IOobject::READ_IF_PRESENT,
3100 IOobject::NO_WRITE),
3102 state.oldTime().oldTime() == state0Read;
3106 state.oldTime().oldTime() == stateRead;
3111 FatalErrorIn(
"") <<
"oldTimeLevel can only be 0, 1, and 2!" << abort(FatalError);
3117 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3118 surfaceScalarField& state =
3119 const_cast<surfaceScalarField&
>(
meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
3121 label maxOldTimes = state.nOldTimes();
3123 if (maxOldTimes >= oldTimeLevel)
3125 surfaceScalarField stateRead(
3130 IOobject::MUST_READ,
3131 IOobject::NO_WRITE),
3134 if (oldTimeLevel == 0)
3138 else if (oldTimeLevel == 1)
3140 state.oldTime() == stateRead;
3142 else if (oldTimeLevel == 2)
3146 surfaceScalarField state0Read(
3151 IOobject::READ_IF_PRESENT,
3152 IOobject::NO_WRITE),
3154 state.oldTime().oldTime() == state0Read;
3158 state.oldTime().oldTime() == stateRead;
3163 FatalErrorIn(
"") <<
"oldTimeLevel can only be 0, 1, and 2!" << abort(FatalError);
3180 if (
daOptionPtr_->getOption<label>(
"writeMinorIterations"))
3197 dictionary bcDict =
daOptionPtr_->getAllOptions().subDict(
"primalBC");
3198 if (bcDict.toc().size() != 0)
3202 Info <<
"Setting up primal boundary conditions based on pyOptions: " << endl;
3204 daFieldPtr_->setPrimalBoundaryConditions(printInfo);
3217 FatalErrorIn(
"DASolver::runFPAdj")
3218 <<
"Child class not implemented!"
3219 << abort(FatalError);
3233 FatalErrorIn(
"DASolver::solveAdjointFP")
3234 <<
"Child class not implemented!"
3235 << abort(FatalError);
3249 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
3250 const volVectorField& state =
meshPtr_->thisDb().lookupObject<volVectorField>(stateName);
3251 scalarList avgState(3, 0.0);
3254 for (label i = 0; i < 3; i++)
3256 avgState[i] += state[cellI][i] /
daIndexPtr_->nGlobalCells;
3259 reduce(avgState[0], sumOp<scalar>());
3260 reduce(avgState[1], sumOp<scalar>());
3261 reduce(avgState[2], sumOp<scalar>());
3263 for (label i = 0; i < 3; i++)
3265 initState.set(stateName + Foam::name(i), avgState[i]);
3271 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3272 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3273 scalar avgState = 0.0;
3276 avgState += state[cellI];
3279 reduce(avgState, sumOp<scalar>());
3281 initState.set(stateName, avgState);
3286 const word stateName =
stateInfo_[
"modelStates"][idxI];
3287 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3288 scalar avgState = 0.0;
3291 avgState += state[cellI];
3294 reduce(avgState, sumOp<scalar>());
3296 initState.set(stateName, avgState);
3301 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3304 initState.set(stateName, 0.0);
3307 Info <<
"initState: " << initState << endl;
3317 Info <<
"Resetting state to its initial values" << endl;
3321 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
3322 volVectorField& state =
const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
3325 for (label i = 0; i < 3; i++)
3330 state.correctBoundaryConditions();
3335 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3336 volScalarField& state =
const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3341 state.correctBoundaryConditions();
3346 const word stateName =
stateInfo_[
"modelStates"][idxI];
3347 volScalarField& state =
const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3352 state.correctBoundaryConditions();
3357 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3358 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
3363 forAll(state.boundaryField(), patchI)
3365 forAll(state.boundaryField()[patchI], faceI)
3367 state.boundaryFieldRef()[patchI][faceI] =
initStateVals_[stateName];
3371 if (stateName ==
"phi")
3373 const volVectorField&
U =
meshPtr_->thisDb().lookupObject<volVectorField>(
"U");
3374 state = linearInterpolate(
U) &
meshPtr_->Sf();
3393 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
3394 const volVectorField& state =
meshPtr_->thisDb().lookupObject<volVectorField>(stateName);
3400 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3401 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3407 const word stateName =
stateInfo_[
"modelStates"][idxI];
3408 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3414 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3415 const surfaceScalarField& state =
meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName);
3419 reduce(fail, sumOp<label>());
3423 Info <<
"*************************************** Warning! ***************************************" << endl;
3424 Info <<
"Invalid values found. Return primal failure and reset the states to their initial values" << endl;
3425 Info <<
"*************************************** Warning! ***************************************" << endl;
3437 const double* dFdXs,
3440 const double timeName)
3458 volVectorField sens(
3464 IOobject::NO_WRITE),
3466 dimensionedVector(name, dimensionSet(0, 0, 0, 0, 0, 0, 0), vector::zero),
3469 forAll(sens.boundaryField(), patchI)
3471 if (
meshPtr_->boundaryMesh()[patchI].type() ==
"wall")
3473 forAll(sens.boundaryField()[patchI], faceI)
3475 sens.boundaryFieldRef()[patchI][faceI] = vector::zero;
3480 label nSurfPoints = round(size / 3);
3482 List<point> surfCoords(nSurfPoints);
3483 List<vector> surfdFdXs(nSurfPoints);
3485 forAll(surfCoords, pointI)
3487 for (label i = 0; i < 3; i++)
3489 surfCoords[pointI][i] = Xs[counterI];
3490 surfdFdXs[pointI][i] = dFdXs[counterI];
3495 pointField meshPoints =
meshPtr_->points();
3498 scalar minDistanceNorm = 0.0;
3502 if (
meshPtr_->boundaryMesh()[patchI].type() ==
"wall")
3509 label faceIPointIndexI =
meshPtr_->boundaryMesh()[patchI][faceI][pointI];
3510 scalar minDistance = 9999999;
3511 label minPointJ = -1;
3512 forAll(surfCoords, pointJ)
3514 distance = mag(surfCoords[pointJ] - meshPoints[faceIPointIndexI]);
3515 if (distance < minDistance)
3517 minDistance = distance;
3522 minDistanceNorm += minDistance * minDistance;
3525 sens.boundaryFieldRef()[patchI][faceI] += surfdFdXs[minPointJ];
3531 minDistanceNorm = sqrt(minDistanceNorm);
3534 forAll(sens.boundaryField(), patchI)
3536 if (
meshPtr_->boundaryMesh()[patchI].type() ==
"wall")
3538 forAll(sens.boundaryField()[patchI], faceI)
3540 sens.boundaryFieldRef()[patchI][faceI] /= sens.boundaryFieldRef()[patchI][faceI].size();
3545 Info <<
"Writing sensitivty map for " << name << endl;
3546 Info <<
"minDistance Norm: " << minDistanceNorm << endl;
3559 const double* dFdField,
3560 const word fieldType,
3561 const double timeName)
3577 if (fieldType ==
"scalar")
3579 volScalarField sens(
3585 IOobject::NO_WRITE),
3587 dimensionedScalar(name, dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0),
3592 sens[cellI] = dFdField[cellI];
3595 Info <<
"Writing sensitivty map for " << name << endl;
3602 sens.correctBoundaryConditions();
3607 else if (fieldType ==
"vector")
3609 volVectorField sens(
3615 IOobject::NO_WRITE),
3617 dimensionedVector(name, dimensionSet(0, 0, 0, 0, 0, 0, 0), vector::zero),
3623 for (label i = 0; i < 3; i++)
3625 sens[cellI][i] = dFdField[counterI];
3630 Info <<
"Writing sensitivty map for " << name << endl;
3637 sens.correctBoundaryConditions();
3644 FatalErrorIn(
"DASolver::writeSensMapField")
3645 <<
"fieldType not supported!"
3646 << abort(FatalError);
3651 const word
function,
3652 const double writeTime,
3665 Info <<
"Writting adjoint fields " << endl;
3671 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
3672 const volVectorField& state =
meshPtr_->thisDb().lookupObject<volVectorField>(stateName);
3673 word varName =
"adjoint_" +
function +
"_" + stateName;
3674 volVectorField adjointVar(varName, state);
3677 for (label i = 0; i < 3; i++)
3679 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
3680 adjointVar[cellI][i] =
psi[localIdx];
3683 adjointVar.correctBoundaryConditions();
3689 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3690 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3691 word varName =
"adjoint_" +
function +
"_" + stateName;
3692 volScalarField adjointVar(varName, state);
3695 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
3696 adjointVar[cellI] =
psi[localIdx];
3698 adjointVar.correctBoundaryConditions();
3704 const word stateName =
stateInfo_[
"modelStates"][idxI];
3705 const volScalarField& state =
meshPtr_->thisDb().lookupObject<volScalarField>(stateName);
3706 word varName =
"adjoint_" +
function +
"_" + stateName;
3707 volScalarField adjointVar(varName, state);
3710 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
3711 adjointVar[cellI] =
psi[localIdx];
3713 adjointVar.correctBoundaryConditions();
3719 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3720 const surfaceScalarField& state =
meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName);
3721 word varName =
"adjoint_" +
function +
"_" + stateName;
3722 surfaceScalarField adjointVar(varName, state);
3726 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
3728 if (faceI < daIndexPtr_->nLocalInternalFaces)
3730 adjointVar[faceI] =
psi[localIdx];
3734 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
3735 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
3737 adjointVar.boundaryFieldRef()[patchIdx][faceIdx] =
psi[localIdx];
3751 word inputName =
allOptions.subDict(
"inputInfo").toc()[idxI];
3752 word inputType =
allOptions.subDict(
"inputInfo").subDict(inputName).getWord(
"type");
3753 if (inputType ==
"volCoord")
3775 if (hasVolCoordInput)
3783 pointField points0 =
meshPtr_->points();
3784 for (label i = 100; i <= 100 + ddtSchemeOrder; i++)
3794 for (label i = 100; i <= 100 + ddtSchemeOrder; i++)
3810 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
3811 volVectorField& state =
const_cast<volVectorField&
>(
3812 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
3813 word meanStateName = stateName +
"Mean";
3814 const volVectorField& stateMean =
3815 meshPtr_->thisDb().lookupObject<volVectorField>(meanStateName);
3818 for (label i = 0; i < 3; i++)
3820 state[cellI][i] = stateMean[cellI][i];
3823 state.correctBoundaryConditions();
3828 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
3829 volScalarField& state =
const_cast<volScalarField&
>(
3830 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3831 word meanStateName = stateName +
"Mean";
3832 const volScalarField& stateMean =
3833 meshPtr_->thisDb().lookupObject<volScalarField>(meanStateName);
3836 state[cellI] = stateMean[cellI];
3838 state.correctBoundaryConditions();
3843 const word stateName =
stateInfo_[
"modelStates"][idxI];
3844 volScalarField& state =
const_cast<volScalarField&
>(
3845 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
3846 word meanStateName = stateName +
"Mean";
3847 const volScalarField& stateMean =
3848 meshPtr_->thisDb().lookupObject<volScalarField>(meanStateName);
3851 state[cellI] = stateMean[cellI];
3853 state.correctBoundaryConditions();
3858 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
3859 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
3860 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
3861 word meanStateName = stateName +
"Mean";
3862 const surfaceScalarField& stateMean =
3863 meshPtr_->thisDb().lookupObject<surfaceScalarField>(meanStateName);
3867 if (faceI < daIndexPtr_->nLocalInternalFaces)
3869 state[faceI] = stateMean[faceI];
3873 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
3874 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
3876 state.boundaryFieldRef()[patchIdx][faceIdx] = stateMean.boundaryField()[patchIdx][faceIdx];
3895 dictionary inputInfoDict =
daOptionPtr_->getAllOptions().subDict(
"inputInfo");
3896 forAll(inputInfoDict.toc(), idxI)
3898 word inputName = inputInfoDict.toc()[idxI];
3899 word inputType = inputInfoDict.subDict(inputName).getWord(
"type");
3900 if (inputType ==
"fieldUnsteady")
3902 label stepInterval = inputInfoDict.subDict(inputName).getLabel(
"stepInterval");
3903 scalar endTime =
meshPtr_->time().endTime().value();
3904 scalar deltaT =
meshPtr_->time().deltaT().value();
3905 label nSteps = round(endTime / deltaT);
3906 word interpMethod = inputInfoDict.subDict(inputName).getWord(
"interpolationMethod");
3907 label nParameters = -1;
3908 if (interpMethod ==
"linear")
3910 nParameters = nSteps / stepInterval + 1;
3912 else if (interpMethod ==
"rbf")
3914 nParameters = 2 * (nSteps / stepInterval + 1);
3918 scalarList initVal(nParameters *
meshPtr_->nCells(), 0.0);
3953 const dictionary& subDict =
daOptionPtr_->getAllOptions().subDict(
"inputInfo").subDict(inputName);
3954 word fieldName = subDict.getWord(
"fieldName");
3955 word fieldType = subDict.getWord(
"fieldType");
3956 label stepInterval = subDict.getLabel(
"stepInterval");
3957 word interpMethod = subDict.getWord(
"interpolationMethod");
3961 if (fieldType ==
"scalar")
3963 volScalarField& field =
3964 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
3967 if (interpMethod ==
"linear")
3969 label timeR = timeIndex % stepInterval;
3970 label timeI = timeIndex / stepInterval;
3972 label counterI = timeI *
meshPtr_->nCells();
3980 field[cellI] = val1;
3985 label counterINextField = counterI + deltaI;
3987 field[cellI] = val1 + (val2 - val1) * timeR / stepInterval;
3992 else if (interpMethod ==
"rbf")
3994 scalar offset = subDict.getScalar(
"offset");
3995 scalar endTime =
meshPtr_->time().endTime().value();
3996 scalar deltaT =
meshPtr_->time().deltaT().value();
3997 label nSteps = round(endTime / deltaT);
3998 label nFields = nSteps / stepInterval + 1;
4002 field[cellI] = offset;
4008 label deltaI = nFields *
meshPtr_->nCells();
4009 for (label i = 0; i < halfSize; i++)
4011 label cellI = i %
meshPtr_->nCells();
4014 label interpTimeIndex = i /
meshPtr_->nCells() * stepInterval;
4015 scalar d = (timeIndex - interpTimeIndex);
4016 field[cellI] += w * exp(-s * s * d * d);
4019 field.correctBoundaryConditions();
4023 FatalErrorIn(
"") <<
"fieldType not valid" << exit(FatalError);