36 pyOptions_(pyOptions),
40 daOptionPtr_(nullptr),
44 daCheckMeshPtr_(nullptr),
45 daLinearEqnPtr_(nullptr),
46 daResidualPtr_(nullptr)
47 #ifdef CODI_AD_REVERSE
49 globalADTape_(codi::RealReverse::getTape())
57 Info <<
"Initializing mesh and runtime for DASolver" << endl;
64 Info <<
"DAOpton initialized " << endl;
79 allOptions.readEntry<word>(
"solverName", modelType);
81 if (
allOptions.lookupOrDefault<label>(
"debug", 0))
83 Info <<
"Selecting " << modelType <<
" for DASolver" << endl;
86 dictionaryConstructorTable::iterator cstrIter =
87 dictionaryConstructorTablePtr_->find(modelType);
90 if (cstrIter == dictionaryConstructorTablePtr_->end())
98 <<
"Unknown DASolver type "
99 << modelType << nl << nl
100 <<
"Valid DASolver types:" << endl
101 << dictionaryConstructorTablePtr_->sortedToc()
106 return autoPtr<DASolver>(
107 cstrIter()(argsAll, pyOptions));
120 scalar endTime =
runTime.endTime().value();
121 scalar deltaT =
runTime.deltaT().value();
122 scalar t =
runTime.timeOutputValue();
125 functionObjectList& funcObj =
const_cast<functionObjectList&
>(
runTime.functionObjects());
138 Info <<
"Time = " << t << endl;
147 else if (t > endTime - 0.5 * deltaT)
170 FatalErrorIn(
"printAllObjFuncs") <<
"daObjFuncPtrList_.size() ==0... "
171 <<
"Forgot to call setDAObjFuncList?"
172 << abort(FatalError);
183 <<
": " << objFuncVal;
184 #ifdef CODI_AD_FORWARD
187 if (
daOptionPtr_->getAllOptions().subDict(
"useAD").getWord(
"mode") ==
"forward")
189 Info <<
" ForwardAD Deriv: " << objFuncVal.getGradient();
216 FatalErrorIn(
"printAllObjFuncs") <<
"daObjFuncPtrList_.size() ==0... "
217 <<
"Forgot to call setDAObjFuncList?"
218 << abort(FatalError);
221 scalar objFuncValue = 0.0;
282 const dictionary& objFuncDict =
allOptions.subDict(
"objFunc");
286 label nObjFuncInstances = 0;
287 forAll(objFuncDict.toc(), idxI)
289 word objFunI = objFuncDict.toc()[idxI];
290 const dictionary& objFuncSubDict = objFuncDict.subDict(objFunI);
291 forAll(objFuncSubDict.toc(), idxJ)
301 label objFuncInstanceI = 0;
302 forAll(objFuncDict.toc(), idxI)
304 word objFunI = objFuncDict.toc()[idxI];
305 const dictionary& objFuncSubDict = objFuncDict.subDict(objFunI);
306 forAll(objFuncSubDict.toc(), idxJ)
309 word objPart = objFuncSubDict.toc()[idxJ];
310 const dictionary& objFuncSubDictPart = objFuncSubDict.subDict(objPart);
341 label nPoints, nFaces;
356 label nPoints, nFaces;
363 const scalar* volCoords,
382 label nPoints, nFaces;
386 label counterFaceI = 0;
390 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
393 for (label i = 0; i < 3; i++)
395 surfCoords[counterFaceI] =
meshPtr_->Cf().boundaryField()[patchI][faceI][i];
409 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
412 for (label i = 0; i < 3; i++)
414 surfCoords[counterFaceI] =
meshPtr_->Cf().boundaryField()[patchI][faceI][i] + 1000.0;
422 const double* volCoords,
426 #ifdef CODI_AD_REVERSE
430 scalar* volCoordsArray =
new scalar[
daIndexPtr_->nLocalXv];
433 volCoordsArray[i] = volCoords[i];
436 scalar* surfCoordsArray =
new scalar[nCouplingFaces * 6];
441 this->globalADTape_.reset();
443 this->globalADTape_.setActive();
448 this->globalADTape_.registerInput(volCoordsArray[i]);
455 for (label i = 0; i < nCouplingFaces * 6; i++)
457 this->globalADTape_.registerOutput(surfCoordsArray[i]);
461 this->globalADTape_.setPassive();
464 for (label i = 0; i < nCouplingFaces * 6; i++)
466 surfCoordsArray[i].setGradient(seeds[i]);
470 this->globalADTape_.evaluate();
475 product[i] = volCoordsArray[i].getGradient();
478 delete[] volCoordsArray;
479 delete[] surfCoordsArray;
482 this->globalADTape_.clearAdjoints();
483 this->globalADTape_.reset();
509 dictionary couplingInfo =
daOptionPtr_->getAllOptions().subDict(
"couplingInfo");
512 forAll(couplingInfo.toc(), idxI)
514 word scenario = couplingInfo.toc()[idxI];
515 label active = couplingInfo.subDict(scenario).getLabel(
"active");
518 dictionary couplingGroups = couplingInfo.subDict(scenario).subDict(
"couplingSurfaceGroups");
520 if (groupName ==
"NONE")
522 groupName = couplingGroups.toc()[0];
523 couplingGroups.readEntry<wordList>(groupName, patchList);
529 couplingGroups.readEntry<wordList>(groupName, patchList);
537 Info <<
"************************ WARNING ************************" << endl;
538 Info <<
"getCouplingPatchList is called but none of " << endl;
539 Info <<
"scenario is active in couplingInfo dict! " << endl;
540 Info <<
"return designSurfaces as patchList.." << endl;
541 Info <<
"************************ WARNING ************************" << endl;
543 daOptionPtr_->getAllOptions().readEntry<wordList>(
"designSurfaces", patchList);
577 List<word> patchList;
581 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(
"T"));
584 label localFaceI = 0;
588 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
590 mixedFvPatchField<scalar>& mixedPatch =
591 refCast<mixedFvPatchField<scalar>>(
T.boundaryFieldRef()[patchI]);
593 forAll(mixedPatch.refValue(), faceI)
595 mixedPatch.refValue()[faceI] = thermal[localFaceI];
596 mixedPatch.refGrad()[faceI] = 0;
604 #ifdef IncompressibleFlow
609 IOdictionary transportProperties(
611 "transportProperties",
617 scalar Cp = readScalar(transportProperties.lookup(
"Cp"));
622 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
624 mixedFvPatchField<scalar>& mixedPatch =
625 refCast<mixedFvPatchField<scalar>>(
T.boundaryFieldRef()[patchI]);
630 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
631 scalar alphaEffBf =
alphaEff.boundaryField()[patchI][faceI];
632 scalar myKDeltaCoeffs = Cp * alphaEffBf * deltaCoeffs;
633 scalar neighKDeltaCoeffs = thermal[localFaceI];
634 mixedPatch.valueFraction()[faceI] = neighKDeltaCoeffs / (myKDeltaCoeffs + neighKDeltaCoeffs);
640 #ifdef CompressibleFlow
650 const IOdictionary& thermoDict =
meshPtr_->thisDb().lookupObject<IOdictionary>(
"thermophysicalProperties");
651 dictionary mixSubDict = thermoDict.subDict(
"mixture");
652 dictionary specieSubDict = mixSubDict.subDict(
"specie");
653 scalar molWeight = specieSubDict.getScalar(
"molWeight");
654 dictionary thermodynamicsSubDict = mixSubDict.subDict(
"thermodynamics");
655 scalar Cp = thermodynamicsSubDict.getScalar(
"Cp");
659 scalar RR = Foam::constant::thermodynamic::RR;
663 scalar R = RR / molWeight;
667 if (
he.name() ==
"e")
680 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
682 mixedFvPatchField<scalar>& mixedPatch =
683 refCast<mixedFvPatchField<scalar>>(
T.boundaryFieldRef()[patchI]);
688 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
689 scalar alphaEffBf =
alphaEff.boundaryField()[patchI][faceI];
690 scalar myKDeltaCoeffs = tmpVal * alphaEffBf * deltaCoeffs;
691 scalar neighKDeltaCoeffs = thermal[localFaceI];
692 mixedPatch.valueFraction()[faceI] = neighKDeltaCoeffs / (myKDeltaCoeffs + neighKDeltaCoeffs);
700 IOdictionary transportProperties(
702 "transportProperties",
708 scalar
k = readScalar(transportProperties.lookup(
"k"));
713 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
715 mixedFvPatchField<scalar>& mixedPatch =
716 refCast<mixedFvPatchField<scalar>>(
T.boundaryFieldRef()[patchI]);
721 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
722 scalar myKDeltaCoeffs =
k * deltaCoeffs;
723 scalar neighKDeltaCoeffs = thermal[localFaceI];
724 mixedPatch.valueFraction()[faceI] = neighKDeltaCoeffs / (myKDeltaCoeffs + neighKDeltaCoeffs);
732 const scalar* volCoords,
733 const scalar* states,
763 List<word> patchList;
766 const objectRegistry& db =
meshPtr_->thisDb();
767 const volScalarField&
T = db.lookupObject<volScalarField>(
"T");
770 label localFaceI = 0;
774 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
777 label faceCellI =
meshPtr_->boundaryMesh()[patchI].faceCells()[faceI];
778 thermal[localFaceI] =
T[faceCellI];
785 #ifdef IncompressibleFlow
792 IOdictionary transportProperties(
794 "transportProperties",
800 scalar Cp = readScalar(transportProperties.lookup(
"Cp"));
805 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
809 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
810 scalar alphaEffBf =
alphaEff.boundaryField()[patchI][faceI];
811 thermal[localFaceI] = Cp * alphaEffBf * deltaCoeffs;
817 #ifdef CompressibleFlow
827 const IOdictionary& thermoDict =
meshPtr_->thisDb().lookupObject<IOdictionary>(
"thermophysicalProperties");
828 dictionary mixSubDict = thermoDict.subDict(
"mixture");
829 dictionary specieSubDict = mixSubDict.subDict(
"specie");
830 scalar molWeight = specieSubDict.getScalar(
"molWeight");
831 dictionary thermodynamicsSubDict = mixSubDict.subDict(
"thermodynamics");
832 scalar Cp = thermodynamicsSubDict.getScalar(
"Cp");
836 scalar RR = Foam::constant::thermodynamic::RR;
840 scalar R = RR / molWeight;
844 if (
he.name() ==
"e")
857 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
861 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
862 scalar alphaEffBf =
alphaEff.boundaryField()[patchI][faceI];
863 thermal[localFaceI] = tmpVal * alphaEffBf * deltaCoeffs;
871 IOdictionary transportProperties(
873 "transportProperties",
879 scalar
k = readScalar(transportProperties.lookup(
"k"));
884 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
888 scalar deltaCoeffs =
T.boundaryField()[patchI].patch().deltaCoeffs()[faceI];
889 thermal[localFaceI] =
k * deltaCoeffs;
897 const word inputName,
898 const double* volCoords,
899 const double* states,
920 #ifdef CODI_AD_REVERSE
924 scalar* volCoordsArray =
new scalar[
daIndexPtr_->nLocalXv];
927 volCoordsArray[i] = volCoords[i];
930 scalar* statesArray =
new scalar[
daIndexPtr_->nLocalAdjointStates];
931 for (label i = 0; i <
daIndexPtr_->nLocalAdjointStates; i++)
933 statesArray[i] = states[i];
936 scalar* thermalArray =
new scalar[nCouplingFaces * 2];
941 this->globalADTape_.reset();
943 this->globalADTape_.setActive();
946 if (inputName ==
"volCoords")
950 this->globalADTape_.registerInput(volCoordsArray[i]);
953 else if (inputName ==
"states")
955 for (label i = 0; i <
daIndexPtr_->nLocalAdjointStates; i++)
957 this->globalADTape_.registerInput(statesArray[i]);
962 FatalErrorIn(
"getThermalAD") <<
" inputName not valid. "
963 << abort(FatalError);
967 this->
getThermal(volCoordsArray, statesArray, thermalArray);
970 for (label i = 0; i < nCouplingFaces * 2; i++)
972 this->globalADTape_.registerOutput(thermalArray[i]);
976 this->globalADTape_.setPassive();
979 for (label i = 0; i < nCouplingFaces * 2; i++)
981 thermalArray[i].setGradient(seeds[i]);
985 this->globalADTape_.evaluate();
988 if (inputName ==
"volCoords")
992 product[i] = volCoordsArray[i].getGradient();
995 else if (inputName ==
"states")
997 for (label i = 0; i <
daIndexPtr_->nLocalAdjointStates; i++)
999 product[i] = statesArray[i].getGradient();
1004 FatalErrorIn(
"getThermalAD") <<
" inputName not valid. "
1005 << abort(FatalError);
1023 volCoordsArray[i].setGradient(0.0);
1025 for (label i = 0; i <
daIndexPtr_->nLocalAdjointStates; i++)
1027 statesArray[i].setGradient(0.0);
1029 this->
getThermal(volCoordsArray, statesArray, thermalArray);
1031 delete[] volCoordsArray;
1032 delete[] statesArray;
1033 delete[] thermalArray;
1036 this->globalADTape_.clearAdjoints();
1037 this->globalADTape_.reset();
1061 #ifndef SolidDASolver
1063 label nPoints, nFaces;
1064 List<word> patchList;
1069 List<scalar> fXTemp(nPoints);
1070 List<scalar> fYTemp(nPoints);
1071 List<scalar> fZTemp(nPoints);
1082 PetscScalar* vecArrayFX;
1083 VecGetArray(fX, &vecArrayFX);
1084 PetscScalar* vecArrayFY;
1085 VecGetArray(fY, &vecArrayFY);
1086 PetscScalar* vecArrayFZ;
1087 VecGetArray(fZ, &vecArrayFZ);
1090 label pointCounter = 0;
1094 PetscScalar val1, val2, val3;
1100 vecArrayFX[pointCounter] = val1;
1101 vecArrayFY[pointCounter] = val2;
1102 vecArrayFZ[pointCounter] = val3;
1107 VecRestoreArray(fX, &vecArrayFX);
1108 VecRestoreArray(fY, &vecArrayFY);
1109 VecRestoreArray(fZ, &vecArrayFZ);
1114 void DASolver::getAcousticData(Vec x, Vec y, Vec z, Vec nX, Vec nY, Vec nZ, Vec a, Vec fX, Vec fY, Vec fZ, word groupName)
1149 #ifndef SolidDASolver
1151 label nPoints, nFaces;
1152 List<word> patchList;
1157 List<scalar> xTemp(nFaces);
1158 List<scalar> yTemp(nFaces);
1159 List<scalar> zTemp(nFaces);
1160 List<scalar> nXTemp(nFaces);
1161 List<scalar> nYTemp(nFaces);
1162 List<scalar> nZTemp(nFaces);
1163 List<scalar> aTemp(nFaces);
1164 List<scalar> fXTemp(nFaces);
1165 List<scalar> fYTemp(nFaces);
1166 List<scalar> fZTemp(nFaces);
1169 this->
getAcousticDataInternal(xTemp, yTemp, zTemp, nXTemp, nYTemp, nZTemp, aTemp, fXTemp, fYTemp, fZTemp, patchList);
1184 PetscScalar* vecArrayX;
1185 VecGetArray(x, &vecArrayX);
1186 PetscScalar* vecArrayY;
1187 VecGetArray(y, &vecArrayY);
1188 PetscScalar* vecArrayZ;
1189 VecGetArray(z, &vecArrayZ);
1190 PetscScalar* vecArrayNX;
1191 VecGetArray(nX, &vecArrayNX);
1192 PetscScalar* vecArrayNY;
1193 VecGetArray(nY, &vecArrayNY);
1194 PetscScalar* vecArrayNZ;
1195 VecGetArray(nZ, &vecArrayNZ);
1196 PetscScalar* vecArrayA;
1197 VecGetArray(a, &vecArrayA);
1198 PetscScalar* vecArrayFX;
1199 VecGetArray(fX, &vecArrayFX);
1200 PetscScalar* vecArrayFY;
1201 VecGetArray(fY, &vecArrayFY);
1202 PetscScalar* vecArrayFZ;
1203 VecGetArray(fZ, &vecArrayFZ);
1206 label pointCounter = 0;
1210 PetscScalar val1, val2, val3, val4, val5, val6, val7, val8, val9, val10;
1223 vecArrayX[pointCounter] = val1;
1224 vecArrayY[pointCounter] = val2;
1225 vecArrayZ[pointCounter] = val3;
1226 vecArrayNX[pointCounter] = val4;
1227 vecArrayNY[pointCounter] = val5;
1228 vecArrayNZ[pointCounter] = val6;
1229 vecArrayA[pointCounter] = val7;
1230 vecArrayFX[pointCounter] = val8;
1231 vecArrayFY[pointCounter] = val9;
1232 vecArrayFZ[pointCounter] = val10;
1237 VecRestoreArray(x, &vecArrayX);
1238 VecRestoreArray(y, &vecArrayY);
1239 VecRestoreArray(z, &vecArrayZ);
1240 VecRestoreArray(nX, &vecArrayNX);
1241 VecRestoreArray(nY, &vecArrayNY);
1242 VecRestoreArray(nZ, &vecArrayNZ);
1243 VecRestoreArray(a, &vecArrayA);
1244 VecRestoreArray(fX, &vecArrayFX);
1245 VecRestoreArray(fY, &vecArrayFY);
1246 VecRestoreArray(fZ, &vecArrayFZ);
1254 List<word>& patchList)
1273 const pointMesh& pMesh = pointMesh::New(
meshPtr_());
1274 const pointBoundaryMesh& boundaryMesh = pMesh.boundary();
1282 label patchIPoints = boundaryMesh.findPatchID(patchList[cI]);
1283 nPoints += boundaryMesh[patchIPoints].size();
1286 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchList[cI]);
1287 nFaces +=
meshPtr_->boundaryMesh()[patchI].size();
1296 List<word>& patchList)
1312 #ifndef SolidDASolver
1314 dictionary couplingInfo =
daOptionPtr_->getAllOptions().subDict(
"couplingInfo");
1315 scalar pRef = couplingInfo.subDict(
"aerostructural").getScalar(
"pRef");
1317 SortableList<word> patchListSort(patchList);
1320 volVectorField volumeForceField(
1326 IOobject::NO_WRITE),
1328 dimensionedVector(
"surfaceForce", dimensionSet(1, 1, -2, 0, 0, 0, 0), vector::zero),
1329 fixedValueFvPatchScalarField::typeName);
1334 vector force(vector::zero);
1336 const objectRegistry& db =
meshPtr_->thisDb();
1337 const volScalarField&
p = db.lookupObject<volScalarField>(
"p");
1339 const surfaceVectorField::Boundary& Sfb =
meshPtr_->Sf().boundaryField();
1342 tmp<volSymmTensorField> tdevRhoReff = daTurb.
devRhoReff();
1343 const volSymmTensorField::Boundary& devRhoReffb = tdevRhoReff().boundaryField();
1345 const pointMesh& pMesh = pointMesh::New(
meshPtr_());
1346 const pointBoundaryMesh& boundaryMesh = pMesh.boundary();
1349 forAll(patchListSort, cI)
1352 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchListSort[cI]);
1354 const fvPatch& patch =
meshPtr_->boundary()[patchI];
1356 vectorField fN(Sfb[patchI] * (
p.boundaryField()[patchI] - pRef));
1358 vectorField fT(Sfb[patchI] & devRhoReffb[patchI]);
1362 force.x() = fN[faceI].x() + fT[faceI].x();
1363 force.y() = fN[faceI].y() + fT[faceI].y();
1364 force.z() = fN[faceI].z() + fT[faceI].z();
1365 volumeForceField.boundaryFieldRef()[patchI][faceI] = force;
1368 volumeForceField.write();
1371 pointField meshPoints =
meshPtr_->points();
1373 vector nodeForce(vector::zero);
1375 label patchStart = 0;
1376 forAll(patchListSort, cI)
1379 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchListSort[cI]);
1380 label patchIPoints = boundaryMesh.findPatchID(patchListSort[cI]);
1382 label nPointsPatch = boundaryMesh[patchIPoints].size();
1383 List<scalar> fXTemp(nPointsPatch);
1384 List<scalar> fYTemp(nPointsPatch);
1385 List<scalar> fZTemp(nPointsPatch);
1386 List<label> pointListTemp(nPointsPatch);
1389 label pointCounter = 0;
1394 const label nPoints =
meshPtr_->boundaryMesh()[patchI][faceI].size();
1397 nodeForce = volumeForceField.boundaryFieldRef()[patchI][faceI] / double(nPoints);
1403 label faceIPointIndexI =
meshPtr_->boundaryMesh()[patchI][faceI][pointI];
1408 for (label i = 0; i < pointCounter; i++)
1410 if (faceIPointIndexI == pointListTemp[i])
1422 fXTemp[iPoint] += nodeForce[0];
1423 fYTemp[iPoint] += nodeForce[1];
1424 fZTemp[iPoint] += nodeForce[2];
1430 fXTemp[pointCounter] = nodeForce[0];
1431 fYTemp[pointCounter] = nodeForce[1];
1432 fZTemp[pointCounter] = nodeForce[2];
1435 pointListTemp[pointCounter] = faceIPointIndexI;
1444 SortableList<label> pointListSort(pointListTemp);
1445 forAll(pointListSort.indices(), indexI)
1447 fX[patchStart + indexI] = fXTemp[pointListSort.indices()[indexI]];
1448 fY[patchStart + indexI] = fYTemp[pointListSort.indices()[indexI]];
1449 fZ[patchStart + indexI] = fZTemp[pointListSort.indices()[indexI]];
1453 patchStart += nPointsPatch;
1470 List<word>& patchList)
1502 #ifndef SolidDASolver
1505 daOptionPtr_->getAllOptions().subDict(
"couplingInfo").subDict(
"aeroacoustic").readEntry<scalar>(
"pRef", pRef);
1507 SortableList<word> patchListSort(patchList);
1515 const objectRegistry& db =
meshPtr_->thisDb();
1516 const volScalarField&
p = db.lookupObject<volScalarField>(
"p");
1518 const surfaceVectorField::Boundary& Sfb =
meshPtr_->Sf().boundaryField();
1521 tmp<volSymmTensorField> tdevRhoReff = daTurb.
devRhoReff();
1522 const volSymmTensorField::Boundary& devRhoReffb = tdevRhoReff().boundaryField();
1526 forAll(patchListSort, cI)
1529 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchListSort[cI]);
1531 const fvPatch& patch =
meshPtr_->boundary()[patchI];
1534 vectorField fN(Sfb[patchI] * (
p.boundaryField()[patchI] - pRef));
1536 vectorField fT(Sfb[patchI] & devRhoReffb[patchI]);
1542 x[iFace] = patch.Cf()[faceI].x();
1543 y[iFace] = patch.Cf()[faceI].y();
1544 z[iFace] = patch.Cf()[faceI].z();
1547 nX[iFace] = -patch.Sf()[faceI].x() / patch.magSf()[faceI];
1548 nY[iFace] = -patch.Sf()[faceI].y() / patch.magSf()[faceI];
1549 nZ[iFace] = -patch.Sf()[faceI].z() / patch.magSf()[faceI];
1552 a[iFace] = patch.magSf()[faceI];
1555 fX[iFace] = -(fN[faceI].x() + fT[faceI].x());
1556 fY[iFace] = -(fN[faceI].y() + fT[faceI].y());
1557 fZ[iFace] = -(fN[faceI].z() + fT[faceI].z());
1651 const vector& center,
1652 scalarList& aForceL,
1653 scalarList& tForceL,
1770 const word propName,
1771 const scalarField& aForce,
1772 const scalarField& tForce,
1773 const scalarField& rDist,
1774 const scalarList& targetForce,
1775 const vector& center,
1791 const dictionary& propSubDict =
daOptionPtr_->getAllOptions().subDict(
"wingProp").subDict(propName);
1792 scalar actEps = propSubDict.getScalar(
"actEps");
1793 word rotDir = propSubDict.getWord(
"rotDir");
1794 word interpScheme = propSubDict.getWord(
"interpScheme");
1795 scalarList axisDummy;
1796 propSubDict.readEntry<scalarList>(
"axis", axisDummy);
1797 axis[0] = axisDummy[0];
1798 axis[1] = axisDummy[1];
1799 axis[2] = axisDummy[2];
1801 if (interpScheme ==
"poly4Gauss")
1805 scalar rotDirCon = 0.0;
1806 if (rotDir ==
"right")
1810 else if (rotDir ==
"left")
1816 FatalErrorIn(
"calcFvSourceInternal") <<
"Rotation direction must be either right of left"
1817 << abort(FatalError);
1821 const volVectorField& meshC =
fvSource.mesh().C();
1822 const scalarField& meshV =
fvSource.mesh().V();
1825 volVectorField meshTanDir = meshC * 0;
1828 scalar rOuter = (3 * rDist[rDist.size() - 1] - rDist[rDist.size() - 2]) / 2;
1829 scalarField rNorm = rDist;
1832 rNorm[index] = rDist[index] / rOuter;
1836 scalar rStarMin = rNorm[0];
1837 scalar rStarMax = rNorm[rNorm.size() - 1];
1840 scalar f1 = aForce[aForce.size() - 2];
1841 scalar f2 = aForce[aForce.size() - 1];
1842 scalar f3 = aForce[0];
1843 scalar f4 = aForce[1];
1844 scalar g1 = tForce[tForce.size() - 2];
1845 scalar g2 = tForce[tForce.size() - 1];
1846 scalar g3 = tForce[0];
1847 scalar g4 = tForce[1];
1848 scalar r1 = rNorm[rNorm.size() - 2];
1849 scalar r2 = rNorm[rNorm.size() - 1];
1850 scalar r3 = rNorm[0];
1851 scalar r4 = rNorm[1];
1852 scalar df3 = (f4 - f3) / (r4 - r3);
1853 scalar dg3 = (g4 - g3) / (r4 - r3);
1857 scalar
mu = 2 * r1 - r2;
1861 for (i = 0; i < maxI; i++)
1863 sigmaS = ((r2 -
mu) * (r2 -
mu) - (r1 -
mu) * (r1 -
mu)) / (2 * log(f1 / f2));
1864 mu = r1 - sqrt(-2 * sigmaS * log(f1 * sqrt(2 * degToRad(180) * sigmaS)));
1870 scalar sigmaAxialOut = sqrt(sigmaS);
1871 scalar muAxialOut =
mu;
1875 for (i = 0; i < maxI; i++)
1877 sigmaS = ((r2 -
mu) * (r2 -
mu) - (r1 -
mu) * (r1 -
mu)) / (2 * log(g1 / g2));
1878 mu = r1 - sqrt(-2 * sigmaS * log(g1 * sqrt(2 * degToRad(180) * sigmaS)));
1884 scalar sigmaTangentialOut = sqrt(sigmaS);
1885 scalar muTangentialOut =
mu;
1888 scalar coefAAxialIn = (df3 * r3 - 2 * f3) / (2 * pow(r3, 4));
1889 scalar coefBAxialIn = (f3 - coefAAxialIn * pow(r3, 4)) / (r3 * r3);
1892 scalar coefATangentialIn = (dg3 * r3 - 2 * g3) / (2 * pow(r3, 4));
1893 scalar coefBTangentialIn = (g3 - coefATangentialIn * pow(r3, 4)) / (r3 * r3);
1899 vector cellDir = meshC[cellI] - center;
1900 scalar length = sqrt(sqr(cellDir[0]) + sqr(cellDir[1]) + sqr(cellDir[2]));
1901 cellDir = cellDir / length;
1904 scalar meshDist = (
axis & cellDir) * length;
1905 vector projP = {center[0] -
axis[0] * meshDist, center[1] -
axis[1] * meshDist, center[2] -
axis[2] * meshDist};
1906 meshDist = mag(meshDist);
1909 scalar meshR = sqrt(sqr(meshC[cellI][0] - projP[0]) + sqr(meshC[cellI][1] - projP[1]) + sqr(meshC[cellI][2] - projP[2]));
1912 vector cellAxDir = cellDir ^
axis;
1915 meshTanDir[cellI] = cellAxDir;
1917 scalar rStar = meshR / rOuter;
1919 if (rStar < rStarMin)
1921 fvSource[cellI] = ((coefAAxialIn * pow(rStar, 4) + coefBAxialIn * pow(rStar, 2)) *
axis + (coefATangentialIn * pow(rStar, 4) + coefBTangentialIn * pow(rStar, 2)) * cellAxDir * rotDirCon) * exp(-sqr(meshDist / actEps));
1923 else if (rStar > rStarMax)
1925 fvSource[cellI] = (1 / (sigmaAxialOut * sqrt(2 * degToRad(180)))) * exp(-0.5 * sqr((rStar - muAxialOut) / sigmaAxialOut)) *
axis;
1926 fvSource[cellI] =
fvSource[cellI] + (1 / (sigmaTangentialOut * sqrt(2 * degToRad(180)))) * exp(-0.5 * sqr((rStar - muTangentialOut) / sigmaTangentialOut)) * cellAxDir * rotDirCon;
1931 fvSource[cellI] = (interpolateSplineXY(rStar, rNorm, aForce) *
axis + interpolateSplineXY(rStar, rNorm, tForce) * cellAxDir * rotDirCon) * exp(-sqr(meshDist / actEps));
1936 scalar scaleAxial = 0;
1937 scalar scaleTangential = 0;
1940 scaleAxial = scaleAxial + (
fvSource[cellI] &
axis) * meshV[cellI];
1941 scaleTangential = scaleTangential + (
fvSource[cellI] & meshTanDir[cellI]) * meshV[cellI];
1943 reduce(scaleAxial, sumOp<scalar>());
1944 reduce(scaleTangential, sumOp<scalar>());
1945 scaleAxial = targetForce[0] / scaleAxial;
1946 scaleTangential = targetForce[1] / scaleTangential * rotDirCon;
1951 fvSource[cellI][0] =
fvSource[cellI][0] * mag(
axis[0]) * scaleAxial +
fvSource[cellI][0] * mag(meshTanDir[cellI][0]) * scaleTangential;
1952 fvSource[cellI][1] =
fvSource[cellI][1] * mag(
axis[1]) * scaleAxial +
fvSource[cellI][1] * mag(meshTanDir[cellI][1]) * scaleTangential;
1953 fvSource[cellI][2] =
fvSource[cellI][2] * mag(
axis[2]) * scaleAxial +
fvSource[cellI][2] * mag(meshTanDir[cellI][2]) * scaleTangential;
1956 else if (interpScheme ==
"gauss")
1960 scalar rInner = rDist[0];
1961 scalar rOuter = rDist[rDist.size() - 1];
1962 scalar fAxialInner = aForce[0];
1963 scalar fAxialOuter = aForce[aForce.size() - 1];
1964 scalar fTanInner = tForce[0];
1965 scalar fTanOuter = tForce[tForce.size() - 1];
1968 dirNorm /= mag(
axis);
1971 scalar axialForceSum = 0.0;
1972 scalar tangentialForceSum = 0.0;
1976 vector cellC =
mesh.C()[cellI];
1978 vector cellC2AVec = cellC - center;
1980 tensor cellC2AVecE(tensor::zero);
1981 cellC2AVecE.xx() = cellC2AVec.x();
1982 cellC2AVecE.yy() = cellC2AVec.y();
1983 cellC2AVecE.zz() = cellC2AVec.z();
1987 vector cellC2AVecA = cellC2AVecE & dirNorm;
1989 vector cellC2AVecR = cellC2AVec - cellC2AVecA;
1992 scalar cellC2AVecRLen = mag(cellC2AVecR);
1994 scalar cellC2AVecALen = mag(cellC2AVecA);
1996 scalar fAxial = 0.0;
1999 scalar dA2_Eps2 = (cellC2AVecALen * cellC2AVecALen) / actEps / actEps;
2004 if (cellC2AVecRLen < rInner)
2006 scalar dR2_Eps2 = (cellC2AVecRLen - rInner) * (cellC2AVecRLen - rInner) / actEps / actEps;
2007 fAxial = fAxialInner * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2008 fTan = fTanInner * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2010 else if (cellC2AVecRLen >= rInner && cellC2AVecRLen <= rOuter)
2012 fAxial = interpolateSplineXY(cellC2AVecRLen, rDist, aForce) * exp(-dA2_Eps2);
2013 fTan = interpolateSplineXY(cellC2AVecRLen, rDist, tForce) * exp(-dA2_Eps2);
2017 scalar dR2_Eps2 = (cellC2AVecRLen - rOuter) * (cellC2AVecRLen - rOuter) / actEps / actEps;
2018 fAxial = fAxialOuter * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2019 fTan = fTanOuter * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2022 axialForceSum += fAxial *
mesh.V()[cellI];
2023 tangentialForceSum += fTan *
mesh.V()[cellI];
2025 reduce(axialForceSum, sumOp<scalar>());
2026 reduce(tangentialForceSum, sumOp<scalar>());
2028 scalar aForceScale = targetForce[0] / axialForceSum;
2029 scalar tForceScale = targetForce[1] / tangentialForceSum;
2033 tangentialForceSum = 0;
2037 vector cellC =
mesh.C()[cellI];
2039 vector cellC2AVec = cellC - center;
2041 tensor cellC2AVecE(tensor::zero);
2042 cellC2AVecE.xx() = cellC2AVec.x();
2043 cellC2AVecE.yy() = cellC2AVec.y();
2044 cellC2AVecE.zz() = cellC2AVec.z();
2048 vector cellC2AVecA = cellC2AVecE & dirNorm;
2050 vector cellC2AVecR = cellC2AVec - cellC2AVecA;
2054 vector cellC2AVecC(vector::zero);
2055 if (rotDir ==
"left")
2058 cellC2AVecC = cellC2AVecR ^ dirNorm;
2060 else if (rotDir ==
"right")
2063 cellC2AVecC = dirNorm ^ cellC2AVecR;
2067 FatalErrorIn(
" ") <<
"rotDir not valid" << abort(FatalError);
2071 scalar cellC2AVecRLen = mag(cellC2AVecR);
2073 scalar cellC2AVecCLen = mag(cellC2AVecC);
2075 scalar cellC2AVecALen = mag(cellC2AVecA);
2077 vector cellC2AVecCNorm = cellC2AVecC / cellC2AVecCLen;
2079 scalar fAxial = 0.0;
2082 scalar dA2_Eps2 = (cellC2AVecALen * cellC2AVecALen) / actEps / actEps;
2087 if (cellC2AVecRLen < rInner)
2089 scalar dR2_Eps2 = (cellC2AVecRLen - rInner) * (cellC2AVecRLen - rInner) / actEps / actEps;
2090 fAxial = aForceScale * fAxialInner * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2091 fTan = tForceScale * fTanInner * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2093 else if (cellC2AVecRLen >= rInner && cellC2AVecRLen <= rOuter)
2095 fAxial = aForceScale * interpolateSplineXY(cellC2AVecRLen, rDist, aForce) * exp(-dA2_Eps2);
2096 fTan = tForceScale * interpolateSplineXY(cellC2AVecRLen, rDist, tForce) * exp(-dA2_Eps2);
2100 scalar dR2_Eps2 = (cellC2AVecRLen - rOuter) * (cellC2AVecRLen - rOuter) / actEps / actEps;
2101 fAxial = aForceScale * fAxialOuter * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2102 fTan = tForceScale * fTanOuter * exp(-dR2_Eps2) * exp(-dA2_Eps2);
2105 vector sourceVec = (fAxial * dirNorm + fTan * cellC2AVecCNorm);
2107 axialForceSum += fAxial *
mesh.V()[cellI];
2108 tangentialForceSum += fTan *
mesh.V()[cellI];
2113 reduce(axialForceSum, sumOp<scalar>());
2114 reduce(tangentialForceSum, sumOp<scalar>());
2116 if (
daOptionPtr_->getOption<word>(
"runStatus") ==
"solvePrimal")
2118 Info <<
"Integrated Axial Force for " << propName <<
": " << axialForceSum << endl;
2119 Info <<
"Integrated Tangential Force for " << propName <<
": " << tangentialForceSum << endl;
2124 FatalErrorIn(
"") <<
"interpScheme not valid! Options: poly4Gauss or gauss"
2125 << abort(FatalError);
2130 const word propName,
2153 const dictionary& propSubDict =
daOptionPtr_->getAllOptions().subDict(
"wingProp").subDict(propName);
2154 label nPoints = propSubDict.getLabel(
"nForceSections");
2158 Field<scalar> aForceTemp(nPoints);
2159 Field<scalar> tForceTemp(nPoints);
2160 Field<scalar> rDistTemp(nPoints);
2161 List<scalar> targetForceTemp(2);
2162 Vector<scalar> centerTemp;
2163 volVectorField fvSourceTemp(
2169 IOobject::NO_WRITE),
2171 dimensionedVector(
"surfaceForce", dimensionSet(0, 0, 0, 0, 0, 0, 0), vector::zero),
2172 fixedValueFvPatchScalarField::typeName);
2175 PetscScalar* vecArrayAForce;
2176 VecGetArray(aForce, &vecArrayAForce);
2177 PetscScalar* vecArrayTForce;
2178 VecGetArray(tForce, &vecArrayTForce);
2179 PetscScalar* vecArrayRDist;
2180 VecGetArray(rDist, &vecArrayRDist);
2181 PetscScalar* vecArrayTargetForce;
2182 VecGetArray(targetForce, &vecArrayTargetForce);
2183 PetscScalar* vecArrayCenter;
2184 VecGetArray(center, &vecArrayCenter);
2189 aForceTemp[cI] = vecArrayAForce[cI];
2190 tForceTemp[cI] = vecArrayTForce[cI];
2191 rDistTemp[cI] = vecArrayRDist[cI];
2193 targetForceTemp[0] = vecArrayTargetForce[0];
2194 targetForceTemp[1] = vecArrayTargetForce[1];
2195 centerTemp[0] = vecArrayCenter[0];
2196 centerTemp[1] = vecArrayCenter[1];
2197 centerTemp[2] = vecArrayCenter[2];
2200 this->
calcFvSourceInternal(propName, aForceTemp, tForceTemp, rDistTemp, targetForceTemp, centerTemp, fvSourceTemp);
2203 PetscScalar* vecArrayFvSource;
2204 VecGetArray(
fvSource, &vecArrayFvSource);
2210 PetscScalar val1, val2, val3;
2216 vecArrayFvSource[3 * cI] = val1;
2217 vecArrayFvSource[3 * cI + 1] = val2;
2218 vecArrayFvSource[3 * cI + 2] = val3;
2221 VecRestoreArray(aForce, &vecArrayAForce);
2222 VecRestoreArray(tForce, &vecArrayTForce);
2223 VecRestoreArray(rDist, &vecArrayRDist);
2224 VecRestoreArray(targetForce, &vecArrayTargetForce);
2225 VecRestoreArray(center, &vecArrayCenter);
2226 VecRestoreArray(
fvSource, &vecArrayFvSource);
2232 const word propName,
2247 #ifdef CODI_AD_REVERSE
2249 Info <<
"Calculating [dFvSource/dInputs]^T*Psi using reverse-mode AD. PropName: "
2250 << propName <<
" mode: " <<
mode << endl;
2252 VecZeroEntries(dFvSource);
2254 const dictionary& propSubDict =
daOptionPtr_->getAllOptions().subDict(
"wingProp").subDict(propName);
2255 label nPoints = propSubDict.getLabel(
"nForceSections");
2257 Field<scalar> aForceField(nPoints);
2258 Field<scalar> tForceField(nPoints);
2259 Field<scalar> rDistField(nPoints);
2260 List<scalar> targetForceList(2);
2261 vector centerVector = vector::zero;
2263 volVectorField fvSourceVField(
2269 IOobject::NO_WRITE),
2271 dimensionedVector(
"surfaceForce", dimensionSet(0, 0, 0, 0, 0, 0, 0), vector::zero),
2272 fixedValueFvPatchScalarField::typeName);
2274 PetscScalar* vecArrayAForce;
2275 PetscScalar* vecArrayTForce;
2276 PetscScalar* vecArrayRDist;
2277 PetscScalar* vecArrayTargetForce;
2278 PetscScalar* vecArrayCenter;
2279 const PetscScalar* vecArrayPsi;
2281 VecGetArray(aForce, &vecArrayAForce);
2282 for (label i = 0; i < nPoints; i++)
2284 aForceField[i] = vecArrayAForce[i];
2286 VecRestoreArray(aForce, &vecArrayAForce);
2288 VecGetArray(tForce, &vecArrayTForce);
2289 for (label i = 0; i < nPoints; i++)
2291 tForceField[i] = vecArrayTForce[i];
2293 VecRestoreArray(tForce, &vecArrayTForce);
2295 VecGetArray(rDist, &vecArrayRDist);
2296 for (label i = 0; i < nPoints; i++)
2298 rDistField[i] = vecArrayRDist[i];
2300 VecRestoreArray(rDist, &vecArrayRDist);
2302 VecGetArray(targetForce, &vecArrayTargetForce);
2303 targetForceList[0] = vecArrayTargetForce[0];
2304 targetForceList[1] = vecArrayTargetForce[1];
2305 VecRestoreArray(targetForce, &vecArrayTargetForce);
2307 VecGetArray(center, &vecArrayCenter);
2308 centerVector[0] = vecArrayCenter[0];
2309 centerVector[1] = vecArrayCenter[1];
2310 centerVector[2] = vecArrayCenter[2];
2311 VecRestoreArray(center, &vecArrayCenter);
2313 this->globalADTape_.reset();
2314 this->globalADTape_.setActive();
2316 if (
mode ==
"aForce")
2318 for (label i = 0; i < nPoints; i++)
2320 this->globalADTape_.registerInput(aForceField[i]);
2323 else if (
mode ==
"tForce")
2325 for (label i = 0; i < nPoints; i++)
2327 this->globalADTape_.registerInput(tForceField[i]);
2330 else if (
mode ==
"rDist")
2332 for (label i = 0; i < nPoints; i++)
2334 this->globalADTape_.registerInput(rDistField[i]);
2337 else if (
mode ==
"targetForce")
2339 for (label i = 0; i < 2; i++)
2341 this->globalADTape_.registerInput(targetForceList[i]);
2344 else if (
mode ==
"center")
2346 for (label i = 0; i < 3; i++)
2348 this->globalADTape_.registerInput(centerVector[i]);
2353 FatalErrorIn(
"calcdFvSourcedInputsTPsiAD") <<
"mode not valid"
2354 << abort(FatalError);
2358 this->
calcFvSourceInternal(propName, aForceField, tForceField, rDistField, targetForceList, centerVector, fvSourceVField);
2361 forAll(fvSourceVField, i)
2363 this->globalADTape_.registerOutput(fvSourceVField[i][0]);
2364 this->globalADTape_.registerOutput(fvSourceVField[i][1]);
2365 this->globalADTape_.registerOutput(fvSourceVField[i][2]);
2368 this->globalADTape_.setPassive();
2371 VecGetArrayRead(
psi, &vecArrayPsi);
2372 forAll(fvSourceVField, i)
2375 fvSourceVField[i][0].setGradient(vecArrayPsi[i * 3]);
2376 fvSourceVField[i][1].setGradient(vecArrayPsi[i * 3 + 1]);
2377 fvSourceVField[i][2].setGradient(vecArrayPsi[i * 3 + 2]);
2379 VecRestoreArrayRead(
psi, &vecArrayPsi);
2381 this->globalADTape_.evaluate();
2383 PetscScalar* vecArrayProd;
2384 VecGetArray(dFvSource, &vecArrayProd);
2385 if (
mode ==
"aForce")
2389 vecArrayProd[i] = aForceField[i].getGradient();
2392 else if (
mode ==
"tForce")
2396 vecArrayProd[i] = tForceField[i].getGradient();
2399 else if (
mode ==
"rDist")
2403 vecArrayProd[i] = rDistField[i].getGradient();
2406 else if (
mode ==
"targetForce")
2408 forAll(targetForceList, i)
2410 vecArrayProd[i] = targetForceList[i].getGradient();
2413 else if (
mode ==
"center")
2417 vecArrayProd[i] = centerVector[i].getGradient();
2421 VecRestoreArray(dFvSource, &vecArrayProd);
2423 this->globalADTape_.clearAdjoints();
2424 this->globalADTape_.reset();
2429 const dictionary& maxResConLv4JacPCMat,
2430 HashTable<List<List<word>>>& stateResConInfo)
const
2481 if (maxResConLv4JacPCMat.toc().size() == 0)
2483 Info <<
"maxResConLv4JacPCMat is empty, just return" << endl;
2489 forAll(stateResConInfo.toc(), idxJ)
2491 word key1 = stateResConInfo.toc()[idxJ];
2492 bool keyFound =
false;
2493 forAll(maxResConLv4JacPCMat.toc(), idxI)
2495 word key = maxResConLv4JacPCMat.toc()[idxI];
2499 label maxLv = maxResConLv4JacPCMat.getLabel(key);
2500 label maxLv1 = stateResConInfo[key1].size() - 1;
2503 FatalErrorIn(
"") <<
"maxResConLv4JacPCMat maxLevel"
2504 << maxLv <<
" for " << key
2505 <<
" larger than stateResConInfo maxLevel "
2506 << maxLv1 <<
" for " << key1
2507 << abort(FatalError);
2513 FatalErrorIn(
"") << key1 <<
" not found in maxResConLv4JacPCMat"
2514 << abort(FatalError);
2520 Info <<
"Reducing max connectivity level of Jacobian PC Mat to : ";
2521 Info << maxResConLv4JacPCMat << endl;
2525 HashTable<List<List<word>>> stateResConInfoBK;
2526 forAll(stateResConInfo.toc(), idxI)
2528 word key = stateResConInfo.toc()[idxI];
2529 stateResConInfoBK.set(key, stateResConInfo[key]);
2533 stateResConInfo.clearStorage();
2536 forAll(stateResConInfoBK.toc(), idxI)
2538 word key = stateResConInfoBK.toc()[idxI];
2539 label maxConLevel = maxResConLv4JacPCMat.getLabel(key);
2540 label conSize = stateResConInfoBK[key].size();
2541 if (conSize > maxConLevel + 1)
2543 List<List<word>> conList;
2544 conList.setSize(maxConLevel + 1);
2545 for (label i = 0; i <= maxConLevel; i++)
2547 conList[i] = stateResConInfoBK[key][i];
2549 stateResConInfo.set(key, conList);
2553 stateResConInfo.set(key, stateResConInfoBK[key]);
2561 const label writeRes)
2568 if (
mode ==
"print")
2571 Info <<
"Printing Primal Residual Statistics." << endl;
2573 else if (
mode ==
"calc")
2579 FatalErrorIn(
"") <<
"mode not valid" << abort(FatalError);
2584 options.set(
"isPC", isPC);
2590 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
2591 const word resName = stateName +
"Res";
2592 const volVectorField& stateRes =
meshPtr_->thisDb().lookupObject<volVectorField>(resName);
2594 vector vecResMax(0, 0, 0);
2595 vector vecResNorm2(0, 0, 0);
2596 vector vecResMean(0, 0, 0);
2599 vecResNorm2.x() += pow(stateRes[cellI].x(), 2.0);
2600 vecResNorm2.y() += pow(stateRes[cellI].y(), 2.0);
2601 vecResNorm2.z() += pow(stateRes[cellI].z(), 2.0);
2602 vecResMean.x() += fabs(stateRes[cellI].x());
2603 vecResMean.y() += fabs(stateRes[cellI].y());
2604 vecResMean.z() += fabs(stateRes[cellI].z());
2605 if (fabs(stateRes[cellI].x()) > vecResMax.x())
2607 vecResMax.x() = fabs(stateRes[cellI].x());
2609 if (fabs(stateRes[cellI].y()) > vecResMax.y())
2611 vecResMax.y() = fabs(stateRes[cellI].y());
2613 if (fabs(stateRes[cellI].z()) > vecResMax.z())
2615 vecResMax.z() = fabs(stateRes[cellI].z());
2618 vecResMean = vecResMean / stateRes.size();
2619 reduce(vecResMean, sumOp<vector>());
2620 vecResMean = vecResMean / Pstream::nProcs();
2621 reduce(vecResNorm2, sumOp<vector>());
2622 reduce(vecResMax, maxOp<vector>());
2623 vecResNorm2.x() = pow(vecResNorm2.x(), 0.5);
2624 vecResNorm2.y() = pow(vecResNorm2.y(), 0.5);
2625 vecResNorm2.z() = pow(vecResNorm2.z(), 0.5);
2626 if (
mode ==
"print")
2628 Info << stateName <<
" Residual Norm2: " << vecResNorm2 << endl;
2629 Info << stateName <<
" Residual Mean: " << vecResMean << endl;
2630 Info << stateName <<
" Residual Max: " << vecResMax << endl;
2641 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
2642 const word resName = stateName +
"Res";
2643 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
2645 scalar scalarResMax = 0, scalarResNorm2 = 0, scalarResMean = 0;
2648 scalarResNorm2 += pow(stateRes[cellI], 2.0);
2649 scalarResMean += fabs(stateRes[cellI]);
2650 if (fabs(stateRes[cellI]) > scalarResMax)
2651 scalarResMax = fabs(stateRes[cellI]);
2653 scalarResMean = scalarResMean / stateRes.size();
2654 reduce(scalarResMean, sumOp<scalar>());
2655 scalarResMean = scalarResMean / Pstream::nProcs();
2656 reduce(scalarResNorm2, sumOp<scalar>());
2657 reduce(scalarResMax, maxOp<scalar>());
2658 scalarResNorm2 = pow(scalarResNorm2, 0.5);
2659 if (
mode ==
"print")
2661 Info << stateName <<
" Residual Norm2: " << scalarResNorm2 << endl;
2662 Info << stateName <<
" Residual Mean: " << scalarResMean << endl;
2663 Info << stateName <<
" Residual Max: " << scalarResMax << endl;
2674 const word stateName =
stateInfo_[
"modelStates"][idxI];
2675 const word resName = stateName +
"Res";
2676 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
2678 scalar scalarResMax = 0, scalarResNorm2 = 0, scalarResMean = 0;
2681 scalarResNorm2 += pow(stateRes[cellI], 2.0);
2682 scalarResMean += fabs(stateRes[cellI]);
2683 if (fabs(stateRes[cellI]) > scalarResMax)
2684 scalarResMax = fabs(stateRes[cellI]);
2686 scalarResMean = scalarResMean / stateRes.size();
2687 reduce(scalarResMean, sumOp<scalar>());
2688 scalarResMean = scalarResMean / Pstream::nProcs();
2689 reduce(scalarResNorm2, sumOp<scalar>());
2690 reduce(scalarResMax, maxOp<scalar>());
2691 scalarResNorm2 = pow(scalarResNorm2, 0.5);
2692 if (
mode ==
"print")
2694 Info << stateName <<
" Residual Norm2: " << scalarResNorm2 << endl;
2695 Info << stateName <<
" Residual Mean: " << scalarResMean << endl;
2696 Info << stateName <<
" Residual Max: " << scalarResMax << endl;
2707 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
2708 const word resName = stateName +
"Res";
2709 const surfaceScalarField& stateRes =
meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName);
2711 scalar phiResMax = 0, phiResNorm2 = 0, phiResMean = 0;
2714 phiResNorm2 += pow(stateRes[faceI], 2.0);
2715 phiResMean += fabs(stateRes[faceI]);
2716 if (fabs(stateRes[faceI]) > phiResMax)
2717 phiResMax = fabs(stateRes[faceI]);
2719 forAll(stateRes.boundaryField(), patchI)
2721 forAll(stateRes.boundaryField()[patchI], faceI)
2723 scalar bPhiRes = stateRes.boundaryField()[patchI][faceI];
2724 phiResNorm2 += pow(bPhiRes, 2.0);
2725 phiResMean += fabs(bPhiRes);
2726 if (fabs(bPhiRes) > phiResMax)
2727 phiResMax = fabs(bPhiRes);
2730 phiResMean = phiResMean /
meshPtr_->nFaces();
2731 reduce(phiResMean, sumOp<scalar>());
2732 phiResMean = phiResMean / Pstream::nProcs();
2733 reduce(phiResNorm2, sumOp<scalar>());
2734 reduce(phiResMax, maxOp<scalar>());
2735 phiResNorm2 = pow(phiResNorm2, 0.5);
2736 if (
mode ==
"print")
2738 Info << stateName <<
" Residual Norm2: " << phiResNorm2 << endl;
2739 Info << stateName <<
" Residual Mean: " << phiResMean << endl;
2740 Info << stateName <<
" Residual Max: " << phiResMax << endl;
2783 matName =
"dRdWTPC";
2787 FatalErrorIn(
"") <<
"isPC " << isPC <<
" not supported! "
2788 <<
"Options are: 0 (for dRdWT) and 1 (for dRdWTPC)." << abort(FatalError);
2796 Info <<
"Computing " << matName <<
" " <<
runTimePtr_->elapsedClockTime() <<
" s" << endl;
2797 Info <<
"Initializing dRdWCon. " <<
runTimePtr_->elapsedClockTime() <<
" s" << endl;
2800 word modelType =
"dRdW";
2809 const HashTable<List<List<word>>>& stateResConInfo =
daStateInfoPtr_->getStateResConInfo();
2814 HashTable<List<List<word>>> stateResConInfoReduced = stateResConInfo;
2816 dictionary maxResConLv4JacPCMat =
daOptionPtr_->getAllOptions().subDict(
"maxResConLv4JacPCMat");
2819 options.set(
"stateResConInfo", stateResConInfoReduced);
2823 options.set(
"stateResConInfo", stateResConInfo);
2828 daJacCon->setupJacConPreallocation(options);
2831 daJacCon->initializeJacCon(options);
2834 daJacCon->setupJacCon(options);
2835 Info <<
"dRdWCon Created. " <<
runTimePtr_->elapsedClockTime() <<
" s" << endl;
2838 daJacCon->readJacConColoring();
2851 dictionary options1;
2852 options1.set(
"transposed", 1);
2853 options1.set(
"isPC", isPC);
2857 options1.set(
"lowerBound",
daOptionPtr_->getSubDictOption<scalar>(
"jacLowerBounds",
"dRdWPC"));
2861 options1.set(
"lowerBound",
daOptionPtr_->getSubDictOption<scalar>(
"jacLowerBounds",
"dRdW"));
2865 daPartDeriv->initializePartDerivMat(options1, dRdWT);
2868 daPartDeriv->calcPartDerivMat(options1, xvVec, wVec, dRdWT);
2875 wordList writeJacobians;
2876 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
2877 if (writeJacobians.found(
"dRdWT") || writeJacobians.found(
"all"))
2889 const word objFuncName,
2909 VecZeroEntries(dFdW);
2912 dictionary objFuncSubDict =
2913 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
2916 forAll(objFuncSubDict.toc(), idxJ)
2919 word objFuncPart = objFuncSubDict.toc()[idxJ];
2920 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
2924 MatCreate(PETSC_COMM_WORLD, &dFdWMat);
2927 word modelType =
"dFdW";
2944 objFuncSubDictPart));
2948 const List<List<word>>& objFuncConInfo = daObjFunc->getObjFuncConInfo();
2949 const labelList& objFuncFaceSources = daObjFunc->getObjFuncFaceSources();
2950 const labelList& objFuncCellSources = daObjFunc->getObjFuncCellSources();
2951 options.set(
"objFuncConInfo", objFuncConInfo);
2952 options.set(
"objFuncFaceSources", objFuncFaceSources);
2953 options.set(
"objFuncCellSources", objFuncCellSources);
2954 options.set(
"objFuncName", objFuncName);
2955 options.set(
"objFuncPart", objFuncPart);
2956 options.set(
"objFuncSubDictPart", objFuncSubDictPart);
2959 daJacCon->initializeJacCon(options);
2962 daJacCon->setupJacCon(options);
2963 Info <<
"dFdWCon Created. " <<
meshPtr_->time().elapsedClockTime() <<
" s" << endl;
2966 word postFix =
"_" + objFuncName +
"_" + objFuncPart;
2967 daJacCon->readJacConColoring(postFix);
2980 daPartDeriv->initializePartDerivMat(options, dFdWMat);
2983 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dFdWMat);
2988 Vec dFdWPart, oneVec;
2989 label objGeoSize = objFuncFaceSources.size() + objFuncCellSources.size();
2990 VecCreate(PETSC_COMM_WORLD, &oneVec);
2991 VecSetSizes(oneVec, objGeoSize, PETSC_DETERMINE);
2992 VecSetFromOptions(oneVec);
2994 VecSet(oneVec, 1.0);
2995 VecDuplicate(wVec, &dFdWPart);
2996 VecZeroEntries(dFdWPart);
2998 MatMultTranspose(dFdWMat, oneVec, dFdWPart);
3003 VecAXPY(dFdW, 1.0, dFdWPart);
3010 MatDestroy(&dFdWMat);
3011 VecDestroy(&dFdWPart);
3012 VecDestroy(&oneVec);
3019 wordList writeJacobians;
3020 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3021 if (writeJacobians.found(
"dFdW") || writeJacobians.found(
"all"))
3023 word outputName =
"dFdW_" + objFuncName;
3032 const word designVarName,
3052 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
3055 dictionary dvSubDict = designVarDict.subDict(designVarName);
3059 word varName = dvSubDict.getWord(
"variable");
3062 dvSubDict.readEntry<wordList>(
"patches", patches);
3064 label comp = dvSubDict.getLabel(
"comp");
3067 word dummyType =
"dummy";
3078 word modelType =
"dRdBC";
3090 options.set(
"variable", varName);
3091 options.set(
"patches", patches);
3092 options.set(
"comp", comp);
3093 options.set(
"isPC", 0);
3096 daPartDeriv->initializePartDerivMat(options, dRdBC);
3099 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dRdBC);
3106 wordList writeJacobians;
3107 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3108 if (writeJacobians.found(
"dRdBC") || writeJacobians.found(
"all"))
3110 word outputName =
"dRdBC_" + designVarName;
3119 const word objFuncName,
3120 const word designVarName,
3142 VecZeroEntries(dFdBC);
3145 word dummyType =
"dummy";
3154 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
3158 word varName = dvSubDict.getWord(
"variable");
3161 dvSubDict.readEntry<wordList>(
"patches", patches);
3163 label comp = dvSubDict.getLabel(
"comp");
3166 dictionary objFuncSubDict =
3167 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
3170 forAll(objFuncSubDict.toc(), idxK)
3172 word objFuncPart = objFuncSubDict.toc()[idxK];
3173 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
3176 MatCreate(PETSC_COMM_WORLD, &dFdBCMat);
3179 word modelType =
"dFdBC";
3191 options.set(
"objFuncName", objFuncName);
3192 options.set(
"objFuncPart", objFuncPart);
3193 options.set(
"objFuncSubDictPart", objFuncSubDictPart);
3194 options.set(
"variable", varName);
3195 options.set(
"patches", patches);
3196 options.set(
"comp", comp);
3199 daPartDeriv->initializePartDerivMat(options, dFdBCMat);
3202 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dFdBCMat);
3207 Vec dFdBCPart, oneVec;
3208 VecDuplicate(dFdBC, &oneVec);
3209 VecSet(oneVec, 1.0);
3210 VecDuplicate(dFdBC, &dFdBCPart);
3211 VecZeroEntries(dFdBCPart);
3213 MatMult(dFdBCMat, oneVec, dFdBCPart);
3217 VecAXPY(dFdBC, 1.0, dFdBCPart);
3225 MatDestroy(&dFdBCMat);
3226 VecDestroy(&dFdBCPart);
3227 VecDestroy(&oneVec);
3230 wordList writeJacobians;
3231 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3232 if (writeJacobians.found(
"dFdBC") || writeJacobians.found(
"all"))
3234 word outputName =
"dFdBC_" + designVarName;
3243 const word designVarName,
3263 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
3266 dictionary dvSubDict = designVarDict.subDict(designVarName);
3271 dvSubDict.readEntry<wordList>(
"patches", patches);
3273 word flowAxis = dvSubDict.getWord(
"flowAxis");
3274 word normalAxis = dvSubDict.getWord(
"normalAxis");
3277 word dummyType =
"dummy";
3288 word modelType =
"dRdAOA";
3300 options.set(
"patches", patches);
3301 options.set(
"flowAxis", flowAxis);
3302 options.set(
"normalAxis", normalAxis);
3303 options.set(
"isPC", 0);
3306 daPartDeriv->initializePartDerivMat(options, dRdAOA);
3309 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dRdAOA);
3316 wordList writeJacobians;
3317 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3318 if (writeJacobians.found(
"dRdAOA") || writeJacobians.found(
"all"))
3320 word outputName =
"dRdAOA_" + designVarName;
3330 const word designVarName,
3333 #ifdef CODI_AD_REVERSE
3352 Info <<
"Calculating [dRdBC]^T * Psi using reverse-mode AD" << endl;
3354 VecZeroEntries(dRdBCTPsi);
3359 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
3362 dictionary dvSubDict = designVarDict.subDict(designVarName);
3367 if (designVarName ==
"MRF")
3372 scalar& omega =
const_cast<scalar&
>(
MRF.getOmegaRef());
3375 this->globalADTape_.
reset();
3376 this->globalADTape_.setActive();
3378 this->globalADTape_.registerInput(BC);
3382 else if (designVarName ==
"fvSource")
3384 volVectorField&
fvSource =
const_cast<volVectorField&
>(
3385 meshPtr_->thisDb().lookupObject<volVectorField>(
"fvSource"));
3387 label comp = dvSubDict.getLabel(
"comp");
3391 this->globalADTape_.reset();
3392 this->globalADTape_.setActive();
3394 this->globalADTape_.registerInput(BC);
3406 word varName = dvSubDict.getWord(
"variable");
3409 dvSubDict.readEntry<wordList>(
"patches", patches);
3411 label comp = dvSubDict.getLabel(
"comp");
3416 word patchName = patches[idxI];
3417 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
3418 if (
meshPtr_->thisDb().foundObject<volVectorField>(varName))
3420 volVectorField& state(
const_cast<volVectorField&
>(
3421 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
3423 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3425 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3427 BC = state.boundaryFieldRef()[patchI][0][comp];
3429 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3430 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3432 mixedFvPatchField<vector>& inletOutletPatch =
3433 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
3434 BC = inletOutletPatch.refValue()[0][comp];
3438 else if (
meshPtr_->thisDb().foundObject<volScalarField>(varName))
3440 volScalarField& state(
const_cast<volScalarField&
>(
3441 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
3443 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3445 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3447 BC = state.boundaryFieldRef()[patchI][0];
3449 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3450 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3452 mixedFvPatchField<scalar>& inletOutletPatch =
3453 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
3454 BC = inletOutletPatch.refValue()[0];
3462 reduce(BC, maxOp<scalar>());
3464 this->globalADTape_.reset();
3465 this->globalADTape_.setActive();
3467 this->globalADTape_.registerInput(BC);
3471 word patchName = patches[idxI];
3472 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
3473 if (
meshPtr_->thisDb().foundObject<volVectorField>(varName))
3475 volVectorField& state(
const_cast<volVectorField&
>(
3476 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
3478 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3480 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3482 forAll(state.boundaryFieldRef()[patchI], faceI)
3484 state.boundaryFieldRef()[patchI][faceI][comp] = BC;
3487 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3488 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3490 mixedFvPatchField<vector>& inletOutletPatch =
3491 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
3492 vector val = inletOutletPatch.refValue()[0];
3494 inletOutletPatch.refValue() = val;
3498 else if (
meshPtr_->thisDb().foundObject<volScalarField>(varName))
3500 volScalarField& state(
const_cast<volScalarField&
>(
3501 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
3503 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3505 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3507 forAll(state.boundaryFieldRef()[patchI], faceI)
3509 state.boundaryFieldRef()[patchI][faceI] = BC;
3512 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3513 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3515 mixedFvPatchField<scalar>& inletOutletPatch =
3516 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
3517 inletOutletPatch.refValue() = BC;
3531 options.set(
"isPC", isPC);
3536 this->globalADTape_.setPassive();
3539 this->globalADTape_.evaluate();
3541 PetscScalar derivVal = BC.getGradient();
3543 VecSetValue(dRdBCTPsi, 0, derivVal, ADD_VALUES);
3545 VecAssemblyBegin(dRdBCTPsi);
3546 VecAssemblyEnd(dRdBCTPsi);
3548 this->globalADTape_.clearAdjoints();
3549 this->globalADTape_.reset();
3551 wordList writeJacobians;
3552 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3553 if (writeJacobians.found(
"dRdBCTPsi") || writeJacobians.found(
"all"))
3555 word outputName =
"dRdBCTPsi_" + designVarName;
3565 const word objFuncName,
3566 const word designVarName,
3569 #ifdef CODI_AD_REVERSE
3586 Info <<
"Calculating dFdBC using reverse-mode AD for " << designVarName << endl;
3588 VecZeroEntries(dFdBC);
3596 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
3599 dictionary dvSubDict = designVarDict.subDict(designVarName);
3604 if (designVarName ==
"MRF")
3608 scalar& omega =
const_cast<scalar&
>(
MRF.getOmegaRef());
3611 else if (designVarName ==
"fvSource")
3613 volVectorField&
fvSource =
const_cast<volVectorField&
>(
3614 meshPtr_->thisDb().lookupObject<volVectorField>(
"fvSource"));
3616 label comp = dvSubDict.getLabel(
"comp");
3624 word varName = dvSubDict.getWord(
"variable");
3627 dvSubDict.readEntry<wordList>(
"patches", patches);
3629 label comp = dvSubDict.getLabel(
"comp");
3634 word patchName = patches[idxI];
3635 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
3636 if (
meshPtr_->thisDb().foundObject<volVectorField>(varName))
3638 volVectorField& state(
const_cast<volVectorField&
>(
3639 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
3641 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3643 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3645 BC = state.boundaryFieldRef()[patchI][0][comp];
3647 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3648 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3650 mixedFvPatchField<vector>& inletOutletPatch =
3651 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
3652 BC = inletOutletPatch.refValue()[0][comp];
3656 else if (
meshPtr_->thisDb().foundObject<volScalarField>(varName))
3658 volScalarField& state(
const_cast<volScalarField&
>(
3659 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
3661 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3663 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3665 BC = state.boundaryFieldRef()[patchI][0];
3667 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3668 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3670 mixedFvPatchField<scalar>& inletOutletPatch =
3671 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
3672 BC = inletOutletPatch.refValue()[0];
3680 reduce(BC, maxOp<scalar>());
3684 dictionary objFuncSubDict =
3685 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
3687 forAll(objFuncSubDict.toc(), idxK)
3689 word objFuncPart = objFuncSubDict.toc()[idxK];
3690 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
3701 objFuncSubDictPart));
3704 this->globalADTape_.reset();
3706 this->globalADTape_.setActive();
3708 this->globalADTape_.registerInput(BC);
3710 if (designVarName ==
"MRF")
3714 scalar& omega =
const_cast<scalar&
>(
MRF.getOmegaRef());
3717 else if (designVarName ==
"fvSource")
3719 volVectorField&
fvSource =
const_cast<volVectorField&
>(
3720 meshPtr_->thisDb().lookupObject<volVectorField>(
"fvSource"));
3722 label comp = dvSubDict.getLabel(
"comp");
3734 word varName = dvSubDict.getWord(
"variable");
3737 dvSubDict.readEntry<wordList>(
"patches", patches);
3739 label comp = dvSubDict.getLabel(
"comp");
3742 word patchName = patches[idxI];
3743 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
3744 if (
meshPtr_->thisDb().foundObject<volVectorField>(varName))
3746 volVectorField& state(
const_cast<volVectorField&
>(
3747 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
3749 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3751 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3753 forAll(state.boundaryFieldRef()[patchI], faceI)
3755 state.boundaryFieldRef()[patchI][faceI][comp] = BC;
3758 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3759 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3761 mixedFvPatchField<vector>& inletOutletPatch =
3762 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
3763 vector val = inletOutletPatch.refValue()[0];
3765 inletOutletPatch.refValue() = val;
3769 else if (
meshPtr_->thisDb().foundObject<volScalarField>(varName))
3771 volScalarField& state(
const_cast<volScalarField&
>(
3772 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
3774 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
3776 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
3778 forAll(state.boundaryFieldRef()[patchI], faceI)
3780 state.boundaryFieldRef()[patchI][faceI] = BC;
3783 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
3784 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
3786 mixedFvPatchField<scalar>& inletOutletPatch =
3787 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
3788 inletOutletPatch.refValue() = BC;
3800 scalar fRef = daObjFunc->getObjFuncValue();
3802 this->globalADTape_.registerOutput(fRef);
3804 this->globalADTape_.setPassive();
3807 if (Pstream::master())
3809 fRef.setGradient(1.0);
3812 this->globalADTape_.evaluate();
3816 VecDuplicate(dFdBC, &dFdBCPart);
3817 VecZeroEntries(dFdBCPart);
3818 PetscScalar derivVal = BC.getGradient();
3820 VecSetValue(dFdBCPart, 0, derivVal, ADD_VALUES);
3821 VecAssemblyBegin(dFdBCPart);
3822 VecAssemblyEnd(dFdBCPart);
3825 this->globalADTape_.clearAdjoints();
3826 this->globalADTape_.reset();
3830 VecAXPY(dFdBC, 1.0, dFdBCPart);
3834 Info <<
"In calcdFdBCAD" << endl;
3836 Info << objFuncName <<
": " << fRef << endl;
3839 VecDestroy(&dFdBCPart);
3842 wordList writeJacobians;
3843 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3844 if (writeJacobians.found(
"dFdBC") || writeJacobians.found(
"all"))
3846 word outputName =
"dFdBC_" + designVarName +
"_" + objFuncName;
3856 const word objFuncName,
3857 const word designVarName,
3879 VecZeroEntries(dFdAOA);
3881 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
3884 dictionary dvSubDict = designVarDict.subDict(designVarName);
3889 dvSubDict.readEntry<wordList>(
"patches", patches);
3891 word flowAxis = dvSubDict.getWord(
"flowAxis");
3892 word normalAxis = dvSubDict.getWord(
"normalAxis");
3895 word dummyType =
"dummy";
3904 dictionary objFuncSubDict =
3905 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
3908 forAll(objFuncSubDict.toc(), idxK)
3910 word objFuncPart = objFuncSubDict.toc()[idxK];
3911 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
3914 MatCreate(PETSC_COMM_WORLD, &dFdAOAMat);
3917 word modelType =
"dFdAOA";
3929 options.set(
"objFuncName", objFuncName);
3930 options.set(
"objFuncPart", objFuncPart);
3931 options.set(
"objFuncSubDictPart", objFuncSubDictPart);
3932 options.set(
"patches", patches);
3933 options.set(
"flowAxis", flowAxis);
3934 options.set(
"normalAxis", normalAxis);
3937 daPartDeriv->initializePartDerivMat(options, dFdAOAMat);
3940 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dFdAOAMat);
3944 Vec dFdAOAPart, oneVec;
3945 VecDuplicate(dFdAOA, &oneVec);
3946 VecSet(oneVec, 1.0);
3947 VecDuplicate(dFdAOA, &dFdAOAPart);
3948 VecZeroEntries(dFdAOAPart);
3950 MatMult(dFdAOAMat, oneVec, dFdAOAPart);
3954 VecAXPY(dFdAOA, 1.0, dFdAOAPart);
3962 MatDestroy(&dFdAOAMat);
3963 VecDestroy(&dFdAOAPart);
3964 VecDestroy(&oneVec);
3967 wordList writeJacobians;
3968 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
3969 if (writeJacobians.found(
"dFdAOA") || writeJacobians.found(
"all"))
3971 word outputName =
"dFdAOA_" + designVarName;
3981 const word designVarName,
3984 #ifdef CODI_AD_REVERSE
4007 Info <<
"Calculating [dRdAOA]^T * Psi using reverse-mode AD" << endl;
4009 VecZeroEntries(dRdAOATPsi);
4014 dictionary designVarDict =
daOptionPtr_->getAllOptions().subDict(
"designVar");
4017 dictionary dvSubDict = designVarDict.subDict(designVarName);
4022 dvSubDict.readEntry<wordList>(
"patches", patches);
4024 word flowAxis = dvSubDict.getWord(
"flowAxis");
4025 word normalAxis = dvSubDict.getWord(
"normalAxis");
4027 HashTable<label> axisIndices;
4028 axisIndices.set(
"x", 0);
4029 axisIndices.set(
"y", 1);
4030 axisIndices.set(
"z", 2);
4031 label flowAxisIndex = axisIndices[flowAxis];
4032 label normalAxisIndex = axisIndices[normalAxis];
4034 volVectorField&
U =
const_cast<volVectorField&
>(
4035 meshPtr_->thisDb().lookupObject<volVectorField>(
"U"));
4038 scalar Ux0 = -1e16, Uy0 = -1e16;
4041 word patchName = patches[idxI];
4042 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
4043 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
4045 if (
U.boundaryField()[patchI].type() ==
"fixedValue")
4047 Uy0 =
U.boundaryField()[patchI][0][normalAxisIndex];
4048 Ux0 =
U.boundaryField()[patchI][0][flowAxisIndex];
4051 else if (
U.boundaryField()[patchI].type() ==
"inletOutlet")
4053 mixedFvPatchField<vector>& inletOutletPatch =
4054 refCast<mixedFvPatchField<vector>>(
U.boundaryFieldRef()[patchI]);
4055 Uy0 = inletOutletPatch.refValue()[0][normalAxisIndex];
4056 Ux0 = inletOutletPatch.refValue()[0][flowAxisIndex];
4061 FatalErrorIn(
"") <<
"boundaryType: " <<
U.boundaryFieldRef()[patchI].type()
4062 <<
" not supported!"
4063 <<
"Avaiable options are: fixedValue, inletOutlet"
4064 << abort(FatalError);
4071 reduce(Ux0, maxOp<scalar>());
4072 reduce(Uy0, maxOp<scalar>());
4073 scalar aoa = atan(Uy0 / Ux0);
4075 this->globalADTape_.reset();
4076 this->globalADTape_.setActive();
4078 this->globalADTape_.registerInput(aoa);
4082 word patchName = patches[idxI];
4083 label patchI =
meshPtr_->boundaryMesh().findPatchID(patchName);
4085 if (
meshPtr_->boundaryMesh()[patchI].size() > 0)
4087 scalar UMag = sqrt(Ux0 * Ux0 + Uy0 * Uy0);
4088 scalar UxNew = UMag * cos(aoa);
4089 scalar UyNew = UMag * sin(aoa);
4091 if (
U.boundaryField()[patchI].type() ==
"fixedValue")
4093 forAll(
U.boundaryField()[patchI], faceI)
4095 U.boundaryFieldRef()[patchI][faceI][flowAxisIndex] = UxNew;
4096 U.boundaryFieldRef()[patchI][faceI][normalAxisIndex] = UyNew;
4099 else if (
U.boundaryField()[patchI].type() ==
"inletOutlet")
4101 mixedFvPatchField<vector>& inletOutletPatch =
4102 refCast<mixedFvPatchField<vector>>(
U.boundaryFieldRef()[patchI]);
4104 forAll(
U.boundaryField()[patchI], faceI)
4106 inletOutletPatch.refValue()[faceI][flowAxisIndex] = UxNew;
4107 inletOutletPatch.refValue()[faceI][normalAxisIndex] = UyNew;
4119 options.set(
"isPC", isPC);
4124 this->globalADTape_.setPassive();
4127 this->globalADTape_.evaluate();
4130 PetscScalar derivVal = aoa.getGradient() * constant::mathematical::pi.getValue() / 180.0;
4132 VecSetValue(dRdAOATPsi, 0, derivVal, ADD_VALUES);
4134 VecAssemblyBegin(dRdAOATPsi);
4135 VecAssemblyEnd(dRdAOATPsi);
4137 this->globalADTape_.clearAdjoints();
4138 this->globalADTape_.reset();
4140 wordList writeJacobians;
4141 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4142 if (writeJacobians.found(
"dRdAOATPsi") || writeJacobians.found(
"all"))
4144 word outputName =
"dRdAOATPsi_" + designVarName;
4154 const word designVarName,
4178 label nDesignVars = -9999;
4182 word dummyType =
"dummy";
4191 word modelType =
"dRdFFD";
4203 options.set(
"nDesignVars", nDesignVars);
4204 options.set(
"isPC", 0);
4210 daPartDeriv->initializePartDerivMat(options, dRdFFD);
4213 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dRdFFD);
4220 wordList writeJacobians;
4221 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4222 if (writeJacobians.found(
"dRdFFD") || writeJacobians.found(
"all"))
4224 word outputName =
"dRdFFD_" + designVarName;
4230 daPartDeriv->clear();
4236 const word objFuncName,
4237 const word designVarName,
4259 VecZeroEntries(dFdFFD);
4265 label nDesignVars = -9999;
4269 word dummyType =
"dummy";
4278 dictionary objFuncSubDict =
4279 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
4282 forAll(objFuncSubDict.toc(), idxK)
4284 word objFuncPart = objFuncSubDict.toc()[idxK];
4285 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
4288 MatCreate(PETSC_COMM_WORLD, &dFdFFDMat);
4291 word modelType =
"dFdFFD";
4303 options.set(
"objFuncName", objFuncName);
4304 options.set(
"objFuncPart", objFuncPart);
4305 options.set(
"objFuncSubDictPart", objFuncSubDictPart);
4306 options.set(
"nDesignVars", nDesignVars);
4312 daPartDeriv->initializePartDerivMat(options, dFdFFDMat);
4315 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dFdFFDMat);
4321 Vec dFdFFDPart, oneVec;
4322 VecCreate(PETSC_COMM_WORLD, &oneVec);
4323 VecSetSizes(oneVec, PETSC_DETERMINE, 1);
4324 VecSetFromOptions(oneVec);
4325 VecSet(oneVec, 1.0);
4326 VecDuplicate(dFdFFD, &dFdFFDPart);
4327 VecZeroEntries(dFdFFDPart);
4329 MatMultTranspose(dFdFFDMat, oneVec, dFdFFDPart);
4333 VecAXPY(dFdFFD, 1.0, dFdFFDPart);
4340 MatDestroy(&dFdFFDMat);
4341 VecDestroy(&dFdFFDPart);
4342 VecDestroy(&oneVec);
4345 daPartDeriv->clear();
4348 wordList writeJacobians;
4349 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4350 if (writeJacobians.found(
"dFdFFD") || writeJacobians.found(
"all"))
4352 word outputName =
"dFdFFD_" + designVarName;
4361 const word designVarName,
4362 const word designVarType,
4385 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
4386 word actuatorName = dvSubDict.getWord(
"actuatorName");
4389 word dummyType =
"dummy";
4398 word modelType =
"dRd" + designVarType;
4410 options.set(
"actuatorName", actuatorName);
4411 options.set(
"isPC", 0);
4414 daPartDeriv->initializePartDerivMat(options, dRdACT);
4417 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dRdACT);
4424 wordList writeJacobians;
4425 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4426 if (writeJacobians.found(
"dRdACT") || writeJacobians.found(
"all"))
4428 word outputName =
"dRd" + designVarType +
"_" + designVarName;
4437 const word objFuncName,
4438 const word designVarName,
4439 const word designVarType,
4461 VecZeroEntries(dFdACT);
4463 if (designVarType !=
"ACTD")
4469 word dummyType =
"dummy";
4478 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
4479 word actuatorName = dvSubDict.getWord(
"actuatorName");
4482 dictionary objFuncSubDict =
4483 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
4486 forAll(objFuncSubDict.toc(), idxK)
4488 word objFuncPart = objFuncSubDict.toc()[idxK];
4489 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
4492 MatCreate(PETSC_COMM_WORLD, &dFdACTMat);
4495 word modelType =
"dFd" + designVarType;
4507 options.set(
"objFuncName", objFuncName);
4508 options.set(
"objFuncPart", objFuncPart);
4509 options.set(
"objFuncSubDictPart", objFuncSubDictPart);
4510 options.set(
"actuatorName", actuatorName);
4513 daPartDeriv->initializePartDerivMat(options, dFdACTMat);
4516 daPartDeriv->calcPartDerivMat(options, xvVec, wVec, dFdACTMat);
4521 VecDuplicate(dFdACT, &dFdACTPart);
4522 VecZeroEntries(dFdACTPart);
4523 MatGetColumnVector(dFdACTMat, dFdACTPart, 0);
4527 VecAXPY(dFdACT, 1.0, dFdACTPart);
4535 MatDestroy(&dFdACTMat);
4536 VecDestroy(&dFdACTPart);
4539 wordList writeJacobians;
4540 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4541 if (writeJacobians.found(
"dFdACT") || writeJacobians.found(
"all"))
4543 word outputName =
"dFdACT_" + designVarName;
4552 const word objFuncName,
4553 const word designVarName,
4556 #ifdef CODI_AD_REVERSE
4576 Info <<
"Calculating dFdField using reverse-mode AD for " << designVarName << endl;
4578 VecZeroEntries(dFdField);
4587 dictionary objFuncSubDict =
4588 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
4590 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
4592 word fieldName = dvSubDict.getWord(
"fieldName");
4593 word fieldType = dvSubDict.getWord(
"fieldType");
4596 forAll(objFuncSubDict.toc(), idxK)
4598 word objFuncPart = objFuncSubDict.toc()[idxK];
4599 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
4610 objFuncSubDictPart));
4613 this->globalADTape_.reset();
4615 this->globalADTape_.setActive();
4625 scalar fRef = daObjFunc->getObjFuncValue();
4627 this->globalADTape_.registerOutput(fRef);
4629 this->globalADTape_.setPassive();
4633 if (Pstream::master())
4635 fRef.setGradient(1.0);
4638 this->globalADTape_.evaluate();
4642 VecDuplicate(dFdField, &dFdFieldPart);
4643 VecZeroEntries(dFdFieldPart);
4647 this->globalADTape_.clearAdjoints();
4648 this->globalADTape_.reset();
4652 VecAXPY(dFdField, 1.0, dFdFieldPart);
4656 Info <<
"In calcdFdFieldAD" << endl;
4658 Info << objFuncName <<
": " << fRef << endl;
4661 VecDestroy(&dFdFieldPart);
4664 wordList writeJacobians;
4665 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
4666 if (writeJacobians.found(
"dFdField") || writeJacobians.found(
"all"))
4668 word outputName =
"dFdField_" + designVarName;
4694 #ifdef CODI_AD_REVERSE
4779 label printInfo = 0;
4782 Info <<
"Updating the OpenFOAM field..." << endl;
4790 label maxCorrectBCCalls =
daOptionPtr_->getOption<label>(
"maxCorrectBCCalls");
4791 for (label i = 0; i < maxCorrectBCCalls; i++)
4802 label printInfo = 0;
4805 Info <<
"Updating the OpenFOAM field..." << endl;
4813 label maxCorrectBCCalls =
daOptionPtr_->getOption<label>(
"maxCorrectBCCalls");
4814 for (label i = 0; i < maxCorrectBCCalls; i++)
4837 Info <<
"Updating the OpenFOAM mesh..." << endl;
4856 Info <<
"Updating the OpenFOAM mesh..." << endl;
4865 #ifdef CODI_AD_REVERSE
4880 Info <<
"In initializedRdWTMatrixFree" << endl;
4886 label localSize =
daIndexPtr_->nLocalAdjointStates;
4887 MatCreateShell(PETSC_COMM_WORLD, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE,
this, &
dRdWTMF_);
4890 Info <<
"dRdWT Jacobian Free created!" << endl;
4897 #ifdef CODI_AD_REVERSE
4908 #ifdef CODI_AD_REVERSE
4917 MatShellGetContext(dRdWTMF, (
void**)&ctx);
4925 if (!ctx->globalADTape4dRdWTInitialized)
4927 ctx->initializeGlobalADTape4dRdWT();
4928 ctx->globalADTape4dRdWTInitialized = 1;
4932 ctx->assignVec2ResidualGradient(vecX);
4934 ctx->globalADTape_.evaluate();
4936 ctx->assignStateGradient2Vec(vecY);
4938 ctx->normalizeGradientVec(vecY);
4940 ctx->globalADTape_.clearAdjoints();
4949 #ifdef CODI_AD_REVERSE
4961 this->globalADTape_.reset();
4963 this->globalADTape_.setActive();
4974 options.set(
"isPC", isPC);
4980 this->globalADTape_.setPassive();
4989 const word objFuncName,
4992 #ifdef CODI_AD_REVERSE
5010 Info <<
"Calculating dFdW using reverse-mode AD" << endl;
5012 VecZeroEntries(dFdW);
5021 dictionary objFuncSubDict =
5022 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
5025 forAll(objFuncSubDict.toc(), idxJ)
5028 word objFuncPart = objFuncSubDict.toc()[idxJ];
5029 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
5040 objFuncSubDictPart));
5043 this->globalADTape_.reset();
5045 this->globalADTape_.setActive();
5054 scalar fRef = daObjFunc->getObjFuncValue();
5056 this->globalADTape_.registerOutput(fRef);
5058 this->globalADTape_.setPassive();
5062 if (Pstream::master())
5064 fRef.setGradient(1.0);
5067 this->globalADTape_.evaluate();
5071 VecDuplicate(dFdW, &dFdWPart);
5072 VecZeroEntries(dFdWPart);
5076 this->globalADTape_.clearAdjoints();
5077 this->globalADTape_.reset();
5081 VecAXPY(dFdW, 1.0, dFdWPart);
5085 Info <<
"In calcdFdWAD" << endl;
5087 Info << objFuncName <<
": " << fRef << endl;
5090 VecDestroy(&dFdWPart);
5096 wordList writeJacobians;
5097 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
5098 if (writeJacobians.found(
"dFdW") || writeJacobians.found(
"all"))
5100 word outputName =
"dFdW_" + objFuncName;
5111 const word objFuncName,
5112 const word designVarName,
5115 #ifdef CODI_AD_REVERSE
5134 Info <<
"Calculating dFdXv using reverse-mode AD" << endl;
5136 VecZeroEntries(dFdXv);
5142 dictionary objFuncSubDict =
5143 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
5146 forAll(objFuncSubDict.toc(), idxJ)
5149 word objFuncPart = objFuncSubDict.toc()[idxJ];
5150 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
5161 objFuncSubDictPart));
5163 pointField meshPoints =
meshPtr_->points();
5166 this->globalADTape_.reset();
5168 this->globalADTape_.setActive();
5172 for (label j = 0; j < 3; j++)
5174 this->globalADTape_.registerInput(meshPoints[i][j]);
5185 scalar fRef = daObjFunc->getObjFuncValue();
5187 this->globalADTape_.registerOutput(fRef);
5189 this->globalADTape_.setPassive();
5193 if (Pstream::master())
5195 fRef.setGradient(1.0);
5198 this->globalADTape_.evaluate();
5202 VecDuplicate(dFdXv, &dFdXvPart);
5203 VecZeroEntries(dFdXvPart);
5207 for (label j = 0; j < 3; j++)
5210 PetscScalar val = meshPoints[i][j].getGradient();
5211 VecSetValue(dFdXvPart, rowI, val, INSERT_VALUES);
5214 VecAssemblyBegin(dFdXvPart);
5215 VecAssemblyEnd(dFdXvPart);
5218 this->globalADTape_.clearAdjoints();
5219 this->globalADTape_.reset();
5223 VecAXPY(dFdXv, 1.0, dFdXvPart);
5228 Info << objFuncName <<
": " << fRef << endl;
5231 VecDestroy(&dFdXvPart);
5234 wordList writeJacobians;
5235 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
5236 if (writeJacobians.found(
"dFdXv") || writeJacobians.found(
"all"))
5238 word outputName =
"dFdXv_" + objFuncName +
"_" + designVarName;
5246 const double* volCoords,
5247 const double* states,
5248 const double* thermal,
5249 const double* seeds,
5252 #ifdef CODI_AD_REVERSE
5269 Info <<
"Calculating [dRdThermal]^T * Psi using reverse-mode AD" << endl;
5271 scalar* volCoordsArray =
new scalar[
daIndexPtr_->nLocalXv];
5274 volCoordsArray[i] = volCoords[i];
5277 scalar* statesArray =
new scalar[
daIndexPtr_->nLocalAdjointStates];
5278 for (label i = 0; i <
daIndexPtr_->nLocalAdjointStates; i++)
5280 statesArray[i] = states[i];
5284 scalar* thermalArray =
new scalar[nCouplingFaces * 2];
5285 for (label i = 0; i < nCouplingFaces * 2; i++)
5287 thermalArray[i] = thermal[i];
5296 this->globalADTape_.reset();
5298 this->globalADTape_.setActive();
5301 for (label i = 0; i < nCouplingFaces * 2; i++)
5303 this->globalADTape_.registerInput(thermalArray[i]);
5316 options.set(
"isPC", isPC);
5324 this->globalADTape_.setPassive();
5330 this->globalADTape_.evaluate();
5333 for (label i = 0; i < nCouplingFaces * 2; i++)
5335 product[i] = thermalArray[i].getGradient();
5351 for (label i = 0; i < nCouplingFaces * 2; i++)
5353 thermalArray[i].setGradient(0.0);
5357 delete[] thermalArray;
5358 delete[] volCoordsArray;
5359 delete[] statesArray;
5362 this->globalADTape_.clearAdjoints();
5363 this->globalADTape_.reset();
5374 #ifdef CODI_AD_REVERSE
5391 Info <<
"Calculating [dRdXv]^T * Psi using reverse-mode AD" << endl;
5393 VecZeroEntries(dRdXvTPsi);
5398 pointField meshPoints =
meshPtr_->points();
5399 this->globalADTape_.reset();
5400 this->globalADTape_.setActive();
5403 for (label j = 0; j < 3; j++)
5405 this->globalADTape_.registerInput(meshPoints[i][j]);
5417 options.set(
"isPC", isPC);
5422 this->globalADTape_.setPassive();
5425 this->globalADTape_.evaluate();
5429 for (label j = 0; j < 3; j++)
5432 PetscScalar val = meshPoints[i][j].getGradient();
5433 VecSetValue(dRdXvTPsi, rowI, val, INSERT_VALUES);
5437 VecAssemblyBegin(dRdXvTPsi);
5438 VecAssemblyEnd(dRdXvTPsi);
5440 this->globalADTape_.clearAdjoints();
5441 this->globalADTape_.reset();
5451 #ifdef CODI_AD_REVERSE
5468 Info <<
"Calculating dForcedXvAD using reverse-mode AD" << endl;
5470 VecZeroEntries(dForcedXv);
5475 pointField meshPoints =
meshPtr_->points();
5476 this->globalADTape_.reset();
5477 this->globalADTape_.setActive();
5480 for (label j = 0; j < 3; j++)
5482 this->globalADTape_.registerInput(meshPoints[i][j]);
5494 label nPoints, nFaces;
5495 List<word> patchList;
5498 List<scalar> fX(nPoints);
5499 List<scalar> fY(nPoints);
5500 List<scalar> fZ(nPoints);
5504 this->globalADTape_.setPassive();
5507 this->globalADTape_.evaluate();
5511 for (label j = 0; j < 3; j++)
5514 PetscScalar val = meshPoints[i][j].getGradient();
5515 VecSetValue(dForcedXv, rowI, val, INSERT_VALUES);
5519 VecAssemblyBegin(dForcedXv);
5520 VecAssemblyEnd(dForcedXv);
5522 this->globalADTape_.clearAdjoints();
5523 this->globalADTape_.reset();
5533 const word groupName)
5535 #ifdef CODI_AD_REVERSE
5552 Info <<
"Calculating dAcoudXvAD using reverse-mode AD" << endl;
5554 VecZeroEntries(dAcoudXv);
5559 pointField meshPoints =
meshPtr_->points();
5560 this->globalADTape_.reset();
5561 this->globalADTape_.setActive();
5564 for (label j = 0; j < 3; j++)
5566 this->globalADTape_.registerInput(meshPoints[i][j]);
5578 label nPoints, nFaces;
5579 List<word> patchList;
5582 List<scalar> x(nFaces);
5583 List<scalar> y(nFaces);
5584 List<scalar> z(nFaces);
5585 List<scalar> nX(nFaces);
5586 List<scalar> nY(nFaces);
5587 List<scalar> nZ(nFaces);
5588 List<scalar> a(nFaces);
5589 List<scalar> fX(nFaces);
5590 List<scalar> fY(nFaces);
5591 List<scalar> fZ(nFaces);
5593 this->
getAcousticDataInternal(x, y, z, nX, nY, nZ, a, fX, fY, fZ, patchList);
5595 if (varName ==
"xAcou")
5601 else if (varName ==
"nAcou")
5607 else if (varName ==
"aAcou")
5611 else if (varName ==
"fAcou")
5617 this->globalADTape_.setPassive();
5619 if (varName ==
"xAcou")
5625 else if (varName ==
"nAcou")
5631 else if (varName ==
"aAcou")
5635 else if (varName ==
"fAcou")
5641 this->globalADTape_.evaluate();
5645 for (label j = 0; j < 3; j++)
5648 PetscScalar val = meshPoints[i][j].getGradient();
5649 VecSetValue(dAcoudXv, rowI, val, INSERT_VALUES);
5653 VecAssemblyBegin(dAcoudXv);
5654 VecAssemblyEnd(dAcoudXv);
5656 this->globalADTape_.clearAdjoints();
5657 this->globalADTape_.reset();
5665 const word designVarName,
5668 #ifdef CODI_AD_REVERSE
5687 Info <<
"Calculating [dRdField]^T * Psi using reverse-mode AD" << endl;
5689 VecZeroEntries(dRdFieldTPsi);
5694 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
5696 word fieldName = dvSubDict.getWord(
"fieldName");
5697 word fieldType = dvSubDict.getWord(
"fieldType");
5699 this->globalADTape_.reset();
5700 this->globalADTape_.setActive();
5710 options.set(
"isPC", isPC);
5715 this->globalADTape_.setPassive();
5718 this->globalADTape_.evaluate();
5722 VecAssemblyBegin(dRdFieldTPsi);
5723 VecAssemblyEnd(dRdFieldTPsi);
5725 this->globalADTape_.clearAdjoints();
5726 this->globalADTape_.reset();
5728 wordList writeJacobians;
5729 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
5730 if (writeJacobians.found(
"dRdFieldTPsi") || writeJacobians.found(
"all"))
5732 word outputName =
"dRdFieldTPsi_" + designVarName;
5742 const word objFuncName,
5743 const word designVarName,
5746 #ifdef CODI_AD_REVERSE
5765 Info <<
"Calculating dFdACT using reverse-mode AD" << endl;
5767 VecZeroEntries(dFdACT);
5770 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
5771 word designVarType = dvSubDict.getWord(
"designVarType");
5772 if (designVarType ==
"ACTD")
5777 word diskName = dvSubDict.getWord(
"actuatorName");
5778 dictionary fvSourceSubDict =
daOptionPtr_->getAllOptions().subDict(
"fvSource");
5779 word
source = fvSourceSubDict.subDict(diskName).getWord(
"source");
5780 if (
source ==
"cylinderAnnulusSmooth")
5786 dictionary objFuncSubDict =
5787 daOptionPtr_->getAllOptions().subDict(
"objFunc").subDict(objFuncName);
5790 forAll(objFuncSubDict.toc(), idxJ)
5793 word objFuncPart = objFuncSubDict.toc()[idxJ];
5794 dictionary objFuncSubDictPart = objFuncSubDict.subDict(objFuncPart);
5805 objFuncSubDictPart));
5808 scalarList actDVList(10);
5809 for (label i = 0; i < 10; i++)
5811 actDVList[i] =
fvSource.getActuatorDVs(diskName, i);
5815 this->globalADTape_.reset();
5817 this->globalADTape_.setActive();
5819 for (label i = 0; i < 10; i++)
5821 this->globalADTape_.registerInput(actDVList[i]);
5824 for (label i = 0; i < 10; i++)
5826 fvSource.setActuatorDVs(diskName, i, actDVList[i]);
5840 scalar fRef = daObjFunc->getObjFuncValue();
5842 this->globalADTape_.registerOutput(fRef);
5844 this->globalADTape_.setPassive();
5848 if (Pstream::master())
5850 fRef.setGradient(1.0);
5853 this->globalADTape_.evaluate();
5857 VecDuplicate(dFdACT, &dFdACTPart);
5858 VecZeroEntries(dFdACTPart);
5860 for (label i = 0; i < 10; i++)
5862 PetscScalar valIn = actDVList[i].getGradient();
5864 VecSetValue(dFdACTPart, i, valIn, ADD_VALUES);
5867 VecAssemblyBegin(dFdACTPart);
5868 VecAssemblyEnd(dFdACTPart);
5871 this->globalADTape_.clearAdjoints();
5872 this->globalADTape_.reset();
5876 VecAXPY(dFdACT, 1.0, dFdACTPart);
5881 Info << objFuncName <<
": " << fRef << endl;
5884 VecDestroy(&dFdACTPart);
5889 FatalErrorIn(
"") <<
"source not supported. Options: cylinderAnnulusSmooth"
5890 << abort(FatalError);
5895 FatalErrorIn(
"") <<
"designVarType not supported. Options: ACTD"
5896 << abort(FatalError);
5899 wordList writeJacobians;
5900 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
5901 if (writeJacobians.found(
"dFdACT") || writeJacobians.found(
"all"))
5903 word outputName =
"dFdACT_" + objFuncName +
"_" + designVarName;
5914 const word designVarName,
5917 #ifdef CODI_AD_REVERSE
5936 Info <<
"Calculating [dRdAct]^T * Psi using reverse-mode AD" << endl;
5938 VecZeroEntries(dRdActTPsi);
5940 dictionary dvSubDict =
daOptionPtr_->getAllOptions().subDict(
"designVar").subDict(designVarName);
5941 word designVarType = dvSubDict.getWord(
"designVarType");
5942 if (designVarType ==
"ACTD")
5948 word diskName = dvSubDict.getWord(
"actuatorName");
5950 dictionary fvSourceSubDict =
daOptionPtr_->getAllOptions().subDict(
"fvSource");
5951 word
source = fvSourceSubDict.subDict(diskName).getWord(
"source");
5952 if (
source ==
"cylinderAnnulusSmooth")
5958 scalarList actDVList(10);
5959 for (label i = 0; i < 10; i++)
5961 actDVList[i] =
fvSource.getActuatorDVs(diskName, i);
5964 this->globalADTape_.reset();
5965 this->globalADTape_.setActive();
5967 for (label i = 0; i < 10; i++)
5969 this->globalADTape_.registerInput(actDVList[i]);
5973 for (label i = 0; i < 10; i++)
5975 fvSource.setActuatorDVs(diskName, i, actDVList[i]);
5985 options.set(
"isPC", isPC);
5990 this->globalADTape_.setPassive();
5993 this->globalADTape_.evaluate();
5995 for (label i = 0; i < 10; i++)
5997 PetscScalar valIn = actDVList[i].getGradient();
5999 VecSetValue(dRdActTPsi, i, valIn, ADD_VALUES);
6002 VecAssemblyBegin(dRdActTPsi);
6003 VecAssemblyEnd(dRdActTPsi);
6005 this->globalADTape_.clearAdjoints();
6006 this->globalADTape_.reset();
6010 FatalErrorIn(
"") <<
"source not supported. Options: cylinderAnnulusSmooth"
6011 << abort(FatalError);
6016 FatalErrorIn(
"") <<
"designVarType not supported. Options: ACTD"
6017 << abort(FatalError);
6019 wordList writeJacobians;
6020 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
6021 if (writeJacobians.found(
"dRdActTPsi") || writeJacobians.found(
"all"))
6023 word outputName =
"dRdActTPsi_" + designVarName;
6036 #ifdef CODI_AD_REVERSE
6052 Info <<
"Calculating dForcesdW using reverse-mode AD" << endl;
6054 VecZeroEntries(dForcedW);
6062 this->globalADTape_.reset();
6063 this->globalADTape_.setActive();
6074 label nPoints, nFaces;
6075 List<word> patchList;
6078 List<scalar> fX(nPoints);
6079 List<scalar> fY(nPoints);
6080 List<scalar> fZ(nPoints);
6084 this->globalADTape_.setPassive();
6087 this->globalADTape_.evaluate();
6095 VecAssemblyBegin(dForcedW);
6096 VecAssemblyEnd(dForcedW);
6098 this->globalADTape_.clearAdjoints();
6099 this->globalADTape_.reset();
6111 #ifdef CODI_AD_REVERSE
6127 Info <<
"Calculating dAcoudW using reverse-mode AD" << endl;
6129 VecZeroEntries(dAcoudW);
6137 this->globalADTape_.reset();
6138 this->globalADTape_.setActive();
6149 label nPoints, nFaces;
6150 List<word> patchList;
6153 List<scalar> x(nFaces);
6154 List<scalar> y(nFaces);
6155 List<scalar> z(nFaces);
6156 List<scalar> nX(nFaces);
6157 List<scalar> nY(nFaces);
6158 List<scalar> nZ(nFaces);
6159 List<scalar> a(nFaces);
6160 List<scalar> fX(nFaces);
6161 List<scalar> fY(nFaces);
6162 List<scalar> fZ(nFaces);
6164 this->
getAcousticDataInternal(x, y, z, nX, nY, nZ, a, fX, fY, fZ, patchList);
6166 if (varName ==
"xAcou")
6172 else if (varName ==
"nAcou")
6178 else if (varName ==
"aAcou")
6182 else if (varName ==
"fAcou")
6188 this->globalADTape_.setPassive();
6190 if (varName ==
"xAcou")
6196 else if (varName ==
"nAcou")
6202 else if (varName ==
"aAcou")
6206 else if (varName ==
"fAcou")
6212 this->globalADTape_.evaluate();
6220 VecAssemblyBegin(dAcoudW);
6221 VecAssemblyEnd(dAcoudW);
6223 this->globalADTape_.clearAdjoints();
6224 this->globalADTape_.reset();
6233 #ifdef CODI_AD_REVERSE
6299 #ifdef CODI_AD_REVERSE
6315 Info <<
"Calculating [dRdW]^T * Psi using reverse-mode AD" << endl;
6317 VecZeroEntries(dRdWTPsi);
6325 this->globalADTape_.reset();
6326 this->globalADTape_.setActive();
6337 options.set(
"isPC", isPC);
6342 this->globalADTape_.setPassive();
6345 this->globalADTape_.evaluate();
6353 VecAssemblyBegin(dRdWTPsi);
6354 VecAssemblyEnd(dRdWTPsi);
6356 this->globalADTape_.clearAdjoints();
6357 this->globalADTape_.reset();
6359 wordList writeJacobians;
6360 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
6361 if (writeJacobians.found(
"dRdWTPsi") || writeJacobians.found(
"all"))
6363 word outputName =
"dRdWTPsi";
6371 const label oldTimeLevel,
6375 #ifdef CODI_AD_REVERSE
6396 Info <<
"Calculating [dRdWOld]^T * Psi using reverse-mode AD with level " << oldTimeLevel << endl;
6398 VecZeroEntries(dRdWOldTPsi);
6400 this->globalADTape_.reset();
6401 this->globalADTape_.setActive();
6412 options.set(
"isPC", isPC);
6417 this->globalADTape_.setPassive();
6420 this->globalADTape_.evaluate();
6428 VecAssemblyBegin(dRdWOldTPsi);
6429 VecAssemblyEnd(dRdWOldTPsi);
6431 this->globalADTape_.clearAdjoints();
6432 this->globalADTape_.reset();
6434 wordList writeJacobians;
6435 daOptionPtr_->getAllOptions().readEntry<wordList>(
"writeJacobians", writeJacobians);
6436 if (writeJacobians.found(
"dRdWOldTPsi") || writeJacobians.found(
"all"))
6438 word outputName =
"dRdWOldTPsi";
6447 #ifdef CODI_AD_REVERSE
6460 if (oldTimeLevel < 0 || oldTimeLevel > 2)
6462 FatalErrorIn(
"") <<
"oldTimeLevel not valid. Options: 0, 1, or 2"
6463 << abort(FatalError);
6468 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
6469 volVectorField& state =
const_cast<volVectorField&
>(
6470 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
6472 label maxOldTimes = state.nOldTimes();
6474 if (maxOldTimes >= oldTimeLevel)
6478 for (label i = 0; i < 3; i++)
6480 if (oldTimeLevel == 0)
6482 this->globalADTape_.registerInput(state[cellI][i]);
6484 else if (oldTimeLevel == 1)
6486 this->globalADTape_.registerInput(state.oldTime()[cellI][i]);
6488 else if (oldTimeLevel == 2)
6490 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI][i]);
6499 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
6500 volScalarField& state =
const_cast<volScalarField&
>(
6501 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
6503 label maxOldTimes = state.nOldTimes();
6505 if (maxOldTimes >= oldTimeLevel)
6509 if (oldTimeLevel == 0)
6511 this->globalADTape_.registerInput(state[cellI]);
6513 else if (oldTimeLevel == 1)
6515 this->globalADTape_.registerInput(state.oldTime()[cellI]);
6517 else if (oldTimeLevel == 2)
6519 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI]);
6527 const word stateName =
stateInfo_[
"modelStates"][idxI];
6528 volScalarField& state =
const_cast<volScalarField&
>(
6529 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
6531 label maxOldTimes = state.nOldTimes();
6533 if (maxOldTimes >= oldTimeLevel)
6537 if (oldTimeLevel == 0)
6539 this->globalADTape_.registerInput(state[cellI]);
6541 else if (oldTimeLevel == 1)
6543 this->globalADTape_.registerInput(state.oldTime()[cellI]);
6545 else if (oldTimeLevel == 2)
6547 this->globalADTape_.registerInput(state.oldTime().oldTime()[cellI]);
6555 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
6556 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
6557 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
6559 label maxOldTimes = state.nOldTimes();
6561 if (maxOldTimes >= oldTimeLevel)
6565 if (oldTimeLevel == 0)
6567 this->globalADTape_.registerInput(state[faceI]);
6569 else if (oldTimeLevel == 1)
6571 this->globalADTape_.registerInput(state.oldTime()[faceI]);
6573 else if (oldTimeLevel == 2)
6575 this->globalADTape_.registerInput(state.oldTime().oldTime()[faceI]);
6578 forAll(state.boundaryField(), patchI)
6580 forAll(state.boundaryField()[patchI], faceI)
6582 if (oldTimeLevel == 0)
6584 this->globalADTape_.registerInput(state.boundaryFieldRef()[patchI][faceI]);
6586 else if (oldTimeLevel == 1)
6588 this->globalADTape_.registerInput(state.oldTime().boundaryFieldRef()[patchI][faceI]);
6590 else if (oldTimeLevel == 2)
6592 this->globalADTape_.registerInput(state.oldTime().oldTime().boundaryFieldRef()[patchI][faceI]);
6603 const word fieldName,
6604 const word fieldType)
6606 #ifdef CODI_AD_REVERSE
6617 if (fieldType ==
"scalar")
6619 volScalarField& state =
const_cast<volScalarField&
>(
6620 meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
6624 this->globalADTape_.registerInput(state[cellI]);
6627 else if (fieldType ==
"vector")
6629 volVectorField& state =
const_cast<volVectorField&
>(
6630 meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
6634 for (label i = 0; i < 3; i++)
6636 this->globalADTape_.registerInput(state[cellI][i]);
6642 FatalErrorIn(
"") <<
"fieldType not valid. Options: scalar or vector"
6643 << abort(FatalError);
6651 #ifdef CODI_AD_REVERSE
6659 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
6660 const word stateResName = stateName +
"Res";
6661 volVectorField& stateRes =
const_cast<volVectorField&
>(
6662 meshPtr_->thisDb().lookupObject<volVectorField>(stateResName));
6666 for (label i = 0; i < 3; i++)
6668 this->globalADTape_.registerOutput(stateRes[cellI][i]);
6675 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
6676 const word stateResName = stateName +
"Res";
6677 volScalarField& stateRes =
const_cast<volScalarField&
>(
6678 meshPtr_->thisDb().lookupObject<volScalarField>(stateResName));
6682 this->globalADTape_.registerOutput(stateRes[cellI]);
6688 const word stateName =
stateInfo_[
"modelStates"][idxI];
6689 const word stateResName = stateName +
"Res";
6690 volScalarField& stateRes =
const_cast<volScalarField&
>(
6691 meshPtr_->thisDb().lookupObject<volScalarField>(stateResName));
6695 this->globalADTape_.registerOutput(stateRes[cellI]);
6701 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
6702 const word stateResName = stateName +
"Res";
6703 surfaceScalarField& stateRes =
const_cast<surfaceScalarField&
>(
6704 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateResName));
6708 this->globalADTape_.registerOutput(stateRes[faceI]);
6710 forAll(stateRes.boundaryField(), patchI)
6712 forAll(stateRes.boundaryField()[patchI], faceI)
6714 this->globalADTape_.registerOutput(stateRes.boundaryFieldRef()[patchI][faceI]);
6726 #if defined(CODI_AD_REVERSE)
6741 this->globalADTape_.registerOutput(fX[cI]);
6742 this->globalADTape_.registerOutput(fY[cI]);
6743 this->globalADTape_.registerOutput(fZ[cI]);
6751 #if defined(CODI_AD_REVERSE)
6762 this->globalADTape_.registerOutput(a[cI]);
6769 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
6781 dictionary normStateDict =
daOptionPtr_->getAllOptions().subDict(
"normalizeStates");
6783 PetscScalar* vecArray;
6784 VecGetArray(vecY, &vecArray);
6788 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
6790 if (normStateDict.found(stateName))
6793 scalar scalingFactor = normStateDict.getScalar(stateName);
6797 for (label i = 0; i < 3; i++)
6799 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
6800 vecArray[localIdx] *= scalingFactor.getValue();
6808 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
6810 if (normStateDict.found(stateName))
6812 scalar scalingFactor = normStateDict.getScalar(stateName);
6816 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
6817 vecArray[localIdx] *= scalingFactor.getValue();
6824 const word stateName =
stateInfo_[
"modelStates"][idxI];
6826 if (normStateDict.found(stateName))
6829 scalar scalingFactor = normStateDict.getScalar(stateName);
6833 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
6834 vecArray[localIdx] *= scalingFactor.getValue();
6841 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
6843 if (normStateDict.found(stateName))
6845 scalar scalingFactor = normStateDict.getScalar(stateName);
6849 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
6851 if (faceI < daIndexPtr_->nLocalInternalFaces)
6853 scalar meshSf =
meshPtr_->magSf()[faceI];
6854 vecArray[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
6858 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
6859 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
6861 scalar meshSf =
meshPtr_->magSf().boundaryField()[patchIdx][faceIdx];
6862 vecArray[localIdx] *= scalingFactor.getValue() * meshSf.getValue();
6868 VecRestoreArray(vecY, &vecArray);
6886 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
6890 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
6891 const word resName = stateName +
"Res";
6892 volVectorField& stateRes =
const_cast<volVectorField&
>(
6893 meshPtr_->thisDb().lookupObject<volVectorField>(resName));
6897 for (label i = 0; i < 3; i++)
6899 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
6900 stateRes[cellI][i].setGradient(seeds[localIdx]);
6907 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
6908 const word resName = stateName +
"Res";
6909 volScalarField& stateRes =
const_cast<volScalarField&
>(
6910 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
6914 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
6915 stateRes[cellI].setGradient(seeds[localIdx]);
6921 const word stateName =
stateInfo_[
"modelStates"][idxI];
6922 const word resName = stateName +
"Res";
6923 volScalarField& stateRes =
const_cast<volScalarField&
>(
6924 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
6928 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
6929 stateRes[cellI].setGradient(seeds[localIdx]);
6935 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
6936 const word resName = stateName +
"Res";
6937 surfaceScalarField& stateRes =
const_cast<surfaceScalarField&
>(
6938 meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName));
6942 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
6944 if (faceI < daIndexPtr_->nLocalInternalFaces)
6946 stateRes[faceI].setGradient(seeds[localIdx]);
6950 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
6951 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
6953 stateRes.boundaryFieldRef()[patchIdx][faceIdx].setGradient(seeds[localIdx]);
6962 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
6974 const PetscScalar* vecArray;
6975 VecGetArrayRead(vecX, &vecArray);
6979 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
6980 const word resName = stateName +
"Res";
6981 volVectorField& stateRes =
const_cast<volVectorField&
>(
6982 meshPtr_->thisDb().lookupObject<volVectorField>(resName));
6986 for (label i = 0; i < 3; i++)
6988 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
6989 stateRes[cellI][i].setGradient(vecArray[localIdx]);
6996 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
6997 const word resName = stateName +
"Res";
6998 volScalarField& stateRes =
const_cast<volScalarField&
>(
6999 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
7003 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7004 stateRes[cellI].setGradient(vecArray[localIdx]);
7010 const word stateName =
stateInfo_[
"modelStates"][idxI];
7011 const word resName = stateName +
"Res";
7012 volScalarField& stateRes =
const_cast<volScalarField&
>(
7013 meshPtr_->thisDb().lookupObject<volScalarField>(resName));
7017 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7018 stateRes[cellI].setGradient(vecArray[localIdx]);
7024 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
7025 const word resName = stateName +
"Res";
7026 surfaceScalarField& stateRes =
const_cast<surfaceScalarField&
>(
7027 meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName));
7031 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
7033 if (faceI < daIndexPtr_->nLocalInternalFaces)
7035 stateRes[faceI].setGradient(vecArray[localIdx]);
7039 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
7040 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
7042 stateRes.boundaryFieldRef()[patchIdx][faceIdx].setGradient(vecArray[localIdx]);
7047 VecRestoreArrayRead(vecX, &vecArray);
7057 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
7074 PetscScalar* vecArrayFBarVec;
7075 VecGetArray(fBarVec, &vecArrayFBarVec);
7081 fX[cI].setGradient(vecArrayFBarVec[i]);
7082 fY[cI].setGradient(vecArrayFBarVec[i + 1]);
7083 fZ[cI].setGradient(vecArrayFBarVec[i + 2]);
7089 VecRestoreArray(fBarVec, &vecArrayFBarVec);
7099 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
7112 PetscScalar* vecArrayFBarVec;
7113 VecGetArray(fBarVec, &vecArrayFBarVec);
7119 a[cI].setGradient(vecArrayFBarVec[i + offset]);
7125 VecRestoreArray(fBarVec, &vecArrayFBarVec);
7131 const label oldTimeLevel)
7133 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
7152 if (oldTimeLevel < 0 || oldTimeLevel > 2)
7154 FatalErrorIn(
"") <<
"oldTimeLevel not valid. Options: 0, 1, or 2"
7155 << abort(FatalError);
7158 PetscScalar* vecArray;
7159 VecGetArray(vecY, &vecArray);
7163 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
7164 volVectorField& state =
const_cast<volVectorField&
>(
7165 meshPtr_->thisDb().lookupObject<volVectorField>(stateName));
7167 label maxOldTimes = state.nOldTimes();
7169 if (maxOldTimes >= oldTimeLevel)
7173 for (label i = 0; i < 3; i++)
7175 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
7176 if (oldTimeLevel == 0)
7178 vecArray[localIdx] = state[cellI][i].getGradient();
7180 else if (oldTimeLevel == 1)
7182 vecArray[localIdx] = state.oldTime()[cellI][i].getGradient();
7184 else if (oldTimeLevel == 2)
7186 vecArray[localIdx] = state.oldTime().oldTime()[cellI][i].getGradient();
7195 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
7196 volScalarField& state =
const_cast<volScalarField&
>(
7197 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
7199 label maxOldTimes = state.nOldTimes();
7201 if (maxOldTimes >= oldTimeLevel)
7205 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7206 if (oldTimeLevel == 0)
7208 vecArray[localIdx] = state[cellI].getGradient();
7210 else if (oldTimeLevel == 1)
7212 vecArray[localIdx] = state.oldTime()[cellI].getGradient();
7214 else if (oldTimeLevel == 2)
7216 vecArray[localIdx] = state.oldTime().oldTime()[cellI].getGradient();
7224 const word stateName =
stateInfo_[
"modelStates"][idxI];
7225 volScalarField& state =
const_cast<volScalarField&
>(
7226 meshPtr_->thisDb().lookupObject<volScalarField>(stateName));
7228 label maxOldTimes = state.nOldTimes();
7230 if (maxOldTimes >= oldTimeLevel)
7234 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7235 if (oldTimeLevel == 0)
7237 vecArray[localIdx] = state[cellI].getGradient();
7239 else if (oldTimeLevel == 1)
7241 vecArray[localIdx] = state.oldTime()[cellI].getGradient();
7243 else if (oldTimeLevel == 2)
7245 vecArray[localIdx] = state.oldTime().oldTime()[cellI].getGradient();
7253 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
7254 surfaceScalarField& state =
const_cast<surfaceScalarField&
>(
7255 meshPtr_->thisDb().lookupObject<surfaceScalarField>(stateName));
7257 label maxOldTimes = state.nOldTimes();
7259 if (maxOldTimes >= oldTimeLevel)
7263 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
7265 if (faceI < daIndexPtr_->nLocalInternalFaces)
7267 if (oldTimeLevel == 0)
7269 vecArray[localIdx] = state[faceI].getGradient();
7271 else if (oldTimeLevel == 1)
7273 vecArray[localIdx] = state.oldTime()[faceI].getGradient();
7275 else if (oldTimeLevel == 2)
7277 vecArray[localIdx] = state.oldTime().oldTime()[faceI].getGradient();
7282 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
7283 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
7286 if (oldTimeLevel == 0)
7288 vecArray[localIdx] =
7289 state.boundaryField()[patchIdx][faceIdx].getGradient();
7291 else if (oldTimeLevel == 1)
7293 vecArray[localIdx] =
7294 state.oldTime().boundaryField()[patchIdx][faceIdx].getGradient();
7296 else if (oldTimeLevel == 2)
7298 vecArray[localIdx] =
7299 state.oldTime().oldTime().boundaryField()[patchIdx][faceIdx].getGradient();
7306 VecRestoreArray(vecY, &vecArray);
7312 const word fieldName,
7313 const word fieldType,
7316 #if defined(CODI_AD_FORWARD) || defined(CODI_AD_REVERSE)
7329 PetscScalar* vecArray;
7330 VecGetArray(vecY, &vecArray);
7332 if (fieldType ==
"scalar")
7334 volScalarField& state =
const_cast<volScalarField&
>(
7335 meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
7339 vecArray[cellI] = state[cellI].getGradient();
7342 else if (fieldType ==
"vector")
7344 volVectorField& state =
const_cast<volVectorField&
>(
7345 meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
7349 for (label i = 0; i < 3; i++)
7351 label localIdx = cellI * 3 + i;
7352 vecArray[localIdx] = state[cellI][i].getGradient();
7358 FatalErrorIn(
"") <<
"fieldType not valid. Options: scalar or vector"
7359 << abort(FatalError);
7362 VecRestoreArray(vecY, &vecArray);
7382 VecGetSize(mpiVec, &vecSize);
7387 VecScatterCreateToAll(mpiVec, &ctx, &vout);
7388 VecScatterBegin(ctx, mpiVec, vout, INSERT_VALUES, SCATTER_FORWARD);
7389 VecScatterEnd(ctx, mpiVec, vout, INSERT_VALUES, SCATTER_FORWARD);
7391 PetscScalar* voutArray;
7392 VecGetArray(vout, &voutArray);
7394 PetscScalar* seqVecArray;
7395 VecGetArray(seqVec, &seqVecArray);
7397 for (label i = 0; i < vecSize; i++)
7399 seqVecArray[i] = voutArray[i];
7401 VecRestoreArray(vout, &voutArray);
7402 VecRestoreArray(seqVec, &seqVecArray);
7403 VecScatterDestroy(&ctx);
7413 MatConvert(dXvdFFDMat, MATSAME, MAT_INITIAL_MATRIX, &
dXvdFFDMat_);
7415 MatAssemblyBegin(
dXvdFFDMat_, MAT_FINAL_ASSEMBLY);
7440 scalar tol =
daOptionPtr_->getOption<scalar>(
"primalMinResTol");
7441 scalar tolMax =
daOptionPtr_->getOption<scalar>(
"primalMinResTolDiff");
7444 Info <<
"********************************************" << endl;
7446 <<
"did not satisfy the prescribed tolerance "
7448 Info <<
"Primal solution failed!" << endl;
7449 Info <<
"********************************************" << endl;
7462 const label printInterval)
const
7468 if (
runTime.timeIndex() % printInterval == 0 ||
runTime.timeIndex() == 1)
7489 IOobject::MUST_READ,
7493 if (MRFIO.typeHeaderOk<IOdictionary>(
true))
7495 IOdictionary MRFProperties(MRFIO);
7497 bool activeMRF(MRFProperties.subDict(
"MRF").lookupOrDefault(
"active",
true));
7501 const volVectorField&
U =
meshPtr_->thisDb().lookupObject<volVectorField>(
"U");
7503 volVectorField
URel(
"URel",
U);
7512 const word fieldName,
7514 const label localCellI,
7531 if (
meshPtr_->thisDb().foundObject<volVectorField>(fieldName))
7533 volVectorField& field =
7534 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
7535 field[localCellI][compI] = val;
7537 else if (
meshPtr_->thisDb().foundObject<volScalarField>(fieldName))
7539 volScalarField& field =
7540 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
7541 field[localCellI] = val;
7545 FatalErrorIn(
"") << fieldName <<
" not found in volScalar and volVector Fields "
7546 << abort(FatalError);
7551 const word fieldName,
7553 const label globalCellI,
7574 if (
meshPtr_->thisDb().foundObject<volVectorField>(fieldName))
7576 if (
daIndexPtr_->globalCellVectorNumbering.isLocal(globalCellI))
7578 volVectorField& field =
7579 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
7580 label localCellI =
daIndexPtr_->globalCellVectorNumbering.toLocal(globalCellI);
7581 field[localCellI][compI] = val;
7584 else if (
meshPtr_->thisDb().foundObject<volScalarField>(fieldName))
7586 if (
daIndexPtr_->globalCellNumbering.isLocal(globalCellI))
7588 volScalarField& field =
7589 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
7590 label localCellI =
daIndexPtr_->globalCellNumbering.toLocal(globalCellI);
7591 field[localCellI] = val;
7596 FatalErrorIn(
"") << fieldName <<
" not found in volScalar and volVector Fields "
7597 << abort(FatalError);
7618 options.set(
"isPC", isPC);
7622 PetscScalar* vecArray;
7623 VecGetArray(resVec, &vecArray);
7627 const word stateName =
stateInfo_[
"volVectorStates"][idxI];
7628 const word resName = stateName +
"Res";
7629 const volVectorField& stateRes =
meshPtr_->thisDb().lookupObject<volVectorField>(resName);
7633 for (label i = 0; i < 3; i++)
7635 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI, i);
7643 const word stateName =
stateInfo_[
"volScalarStates"][idxI];
7644 const word resName = stateName +
"Res";
7645 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
7649 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7656 const word stateName =
stateInfo_[
"modelStates"][idxI];
7657 const word resName = stateName +
"Res";
7658 const volScalarField& stateRes =
meshPtr_->thisDb().lookupObject<volScalarField>(resName);
7662 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, cellI);
7669 const word stateName =
stateInfo_[
"surfaceScalarStates"][idxI];
7670 const word resName = stateName +
"Res";
7671 const surfaceScalarField& stateRes =
meshPtr_->thisDb().lookupObject<surfaceScalarField>(resName);
7675 label localIdx =
daIndexPtr_->getLocalAdjointStateIndex(stateName, faceI);
7677 if (faceI < daIndexPtr_->nLocalInternalFaces)
7683 label relIdx = faceI -
daIndexPtr_->nLocalInternalFaces;
7684 label patchIdx =
daIndexPtr_->bFacePatchI[relIdx];
7691 VecRestoreArray(resVec, &vecArray);
7695 const word fieldName,
7696 const word fieldType)
7708 if (fieldType ==
"scalar")
7710 volScalarField& field =
7711 const_cast<volScalarField&
>(
meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
7712 field.correctBoundaryConditions();
7714 else if (fieldType ==
"vector")
7716 volVectorField& field =
7717 const_cast<volVectorField&
>(
meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
7718 field.correctBoundaryConditions();
7722 FatalErrorIn(
"") << fieldType <<
" not support. Options are: vector or scalar "
7723 << abort(FatalError);
7737 scalar instanceStart =
7741 if (t > instanceStart || fabs(t - endTime) < 1e-8)
7743 Info <<
"Saving time instance " << timeInstanceI <<
" at Time = " << t << endl;
7753 word objFuncName =
daOptionPtr_->getAllOptions().subDict(
"objFunc").toc()[idxI];
7787 word objFuncName =
daOptionPtr_->getAllOptions().subDict(
"objFunc").toc()[idxI];
7809 Info <<
"Setting fields for time instance " << instanceI << endl;
7818 word
mode =
daOptionPtr_->getSubDictOption<word>(
"unsteadyAdjoint",
"mode");
7821 label oldTimeLevel = 0;
7829 if (
mode ==
"timeAccurateAdjoint")
7835 idxI = max(instanceI - 1, 0);
7845 idxI = max(instanceI - 2, 0);
7855 for (label i = 0; i < 10; i++)
7871 PetscInt Istart, Iend;
7872 MatGetOwnershipRange(stateMat, &Istart, &Iend);
7874 PetscInt IstartBC, IendBC;
7875 MatGetOwnershipRange(stateBCMat, &IstartBC, &IendBC);
7879 for (label i = Istart; i < Iend; i++)
7881 label relIdx = i - Istart;
7883 if (
mode ==
"mat2List")
7885 MatGetValues(stateMat, 1, &i, 1, &n, &val);
7888 else if (
mode ==
"list2Mat")
7891 MatSetValue(stateMat, i, n, val, INSERT_VALUES);
7895 FatalErrorIn(
"") <<
"mode not valid!" << abort(FatalError);
7899 for (label i = IstartBC; i < IendBC; i++)
7901 label relIdx = i - IstartBC;
7903 if (
mode ==
"mat2List")
7905 MatGetValues(stateBCMat, 1, &i, 1, &n, &val);
7908 else if (
mode ==
"list2Mat")
7911 MatSetValue(stateBCMat, i, n, val, INSERT_VALUES);
7915 FatalErrorIn(
"") <<
"mode not valid!" << abort(FatalError);
7920 if (
mode ==
"list2Mat")
7922 MatAssemblyBegin(stateMat, MAT_FINAL_ASSEMBLY);
7923 MatAssemblyEnd(stateMat, MAT_FINAL_ASSEMBLY);
7924 MatAssemblyBegin(stateBCMat, MAT_FINAL_ASSEMBLY);
7925 MatAssemblyEnd(stateBCMat, MAT_FINAL_ASSEMBLY);
7928 PetscScalar* timeVecArray;
7929 PetscScalar* timeIdxVecArray;
7930 VecGetArray(timeVec, &timeVecArray);
7931 VecGetArray(timeIdxVec, &timeIdxVecArray);
7935 if (
mode ==
"mat2List")
7940 else if (
mode ==
"list2Mat")
7947 FatalErrorIn(
"") <<
"mode not valid!" << abort(FatalError);
7951 VecRestoreArray(timeVec, &timeVecArray);
7952 VecRestoreArray(timeIdxVec, &timeIdxVecArray);
7963 if (
daOptionPtr_->getOption<label>(
"writeMinorIterations"))
7971 const label instanceI,
7972 const word objFuncName)
7992 dictionary bcDict =
daOptionPtr_->getAllOptions().subDict(
"primalBC");
7993 if (bcDict.toc().size() != 0)
7997 Info <<
"Setting up primal boundary conditions based on pyOptions: " << endl;
7999 daFieldPtr_->setPrimalBoundaryConditions(printInfo);
8014 FatalErrorIn(
"DASolver::runFPAdj")
8015 <<
"Child class not implemented!"
8016 << abort(FatalError);