11 <<
"Forward-Mode AD is activated, setting the AD seeds..." << endl;
13 if (daOptionPtr_->getAllOptions().subDict(
"useAD").getWord(
"mode") ==
"forward")
16 word designVarName = daOptionPtr_->getAllOptions().subDict(
"useAD").getWord(
"dvName");
18 dictionary designVarDict = daOptionPtr_->getAllOptions().subDict(
"designVar");
20 dictionary dvSubDict = designVarDict.subDict(designVarName);
21 word type = dvSubDict.getWord(
"designVarType");
28 pointField meshPointsForwardAD =
mesh.points();
30 Info <<
"Setting seeds based on FFD2XvSeedVec: " << endl;
31 PetscScalar* seedArray;
32 VecGetArray(FFD2XvSeedVec_, &seedArray);
33 forAll(meshPointsForwardAD, i)
35 for (label j = 0; j < 3; j++)
37 label localIdx = daIndexPtr_->getLocalXvIndex(i, j);
38 PetscScalar seedVal = seedArray[localIdx];
39 meshPointsForwardAD[i][j].setGradient(seedVal);
42 VecRestoreArray(FFD2XvSeedVec_, &seedArray);
44 mesh.movePoints(meshPointsForwardAD);
46 else if (type ==
"Field")
48 label seedIndex = daOptionPtr_->getAllOptions().subDict(
"useAD").getLabel(
"seedIndex");
50 word fieldName = dvSubDict.getWord(
"fieldName");
51 word fieldType = dvSubDict.getWord(
"fieldType");
53 if (fieldType ==
"scalar")
55 volScalarField& state =
const_cast<volScalarField&
>(
56 meshPtr_->thisDb().lookupObject<volScalarField>(fieldName));
60 label glxIdx = daIndexPtr_->getGlobalCellIndex(cellI);
61 if (glxIdx == seedIndex || seedIndex == -1)
63 state[cellI].setGradient(1.0);
67 else if (fieldType ==
"vector")
69 volVectorField& state =
const_cast<volVectorField&
>(
70 meshPtr_->thisDb().lookupObject<volVectorField>(fieldName));
74 for (label i = 0; i < 3; i++)
76 label glxIdx = daIndexPtr_->getLocalCellVectorIndex(cellI, i);
77 if (glxIdx == seedIndex || seedIndex == -1)
79 state[cellI][i].setGradient(1.0);
86 FatalErrorIn(
"") <<
"fieldType not valid. Options: scalar or vector"
90 else if (type ==
"ACTD")
93 scalarList actDVListForwardAD(9);
95 label seedIndex = daOptionPtr_->getAllOptions().subDict(
"useAD").getLabel(
"seedIndex");
97 DAFvSource&
fvSource =
const_cast<DAFvSource&
>(
98 meshPtr_->thisDb().lookupObject<DAFvSource>(
"DAFvSource"));
100 word diskName = dvSubDict.getWord(
"actuatorName");
101 dictionary fvSourceSubDict = daOptionPtr_->getAllOptions().subDict(
"fvSource");
102 word
source = fvSourceSubDict.subDict(diskName).getWord(
"source");
103 if (
source ==
"cylinderAnnulusSmooth")
106 for (label i = 0; i < 9; i++)
110 actDVListForwardAD[i] =
fvSource.getActuatorDVs(diskName, i);
111 actDVListForwardAD[i].setGradient(1.0);
112 fvSource.setActuatorDVs(diskName, i, actDVListForwardAD[i]);
123 FatalErrorIn(
"") <<
"only support cylinderAnnulusSmooth!"
124 << abort(FatalError);
127 else if (type ==
"AOA")
135 dvSubDict.readEntry<wordList>(
"patches", patches);
137 word flowAxis = dvSubDict.getWord(
"flowAxis");
138 word normalAxis = dvSubDict.getWord(
"normalAxis");
140 HashTable<label> axisIndices;
141 axisIndices.set(
"x", 0);
142 axisIndices.set(
"y", 1);
143 axisIndices.set(
"z", 2);
144 label flowAxisIndex = axisIndices[flowAxis];
145 label normalAxisIndex = axisIndices[normalAxis];
147 volVectorField&
U =
const_cast<volVectorField&
>(
148 meshPtr_->thisDb().lookupObject<volVectorField>(
"U"));
151 scalar Ux0 = -1e16, Uy0 = -1e16;
154 word patchName = patches[idxI];
155 label patchI = meshPtr_->boundaryMesh().findPatchID(patchName);
156 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
158 if (
U.boundaryField()[patchI].type() ==
"fixedValue")
160 Uy0 =
U.boundaryField()[patchI][0][normalAxisIndex];
161 Ux0 =
U.boundaryField()[patchI][0][flowAxisIndex];
164 else if (
U.boundaryField()[patchI].type() ==
"inletOutlet")
166 mixedFvPatchField<vector>& inletOutletPatch =
167 refCast<mixedFvPatchField<vector>>(
U.boundaryFieldRef()[patchI]);
168 Uy0 = inletOutletPatch.refValue()[0][normalAxisIndex];
169 Ux0 = inletOutletPatch.refValue()[0][flowAxisIndex];
174 FatalErrorIn(
"") <<
"boundaryType: " <<
U.boundaryFieldRef()[patchI].type()
176 <<
"Available options are: fixedValue, inletOutlet"
177 << abort(FatalError);
184 reduce(Ux0, maxOp<scalar>());
185 reduce(Uy0, maxOp<scalar>());
186 aoaForwardAD = atan(Uy0 / Ux0);
189 aoaForwardAD *= 180.0 / constant::mathematical::pi.getValue();
191 Info <<
"Setting the seed for AOA: " << aoaForwardAD << endl;
192 aoaForwardAD.setGradient(1.0);
195 aoaForwardAD *= constant::mathematical::pi.getValue() / 180.0;
199 DAUtility::angleOfAttackRadForwardAD = aoaForwardAD;
204 word patchName = patches[idxI];
205 label patchI = meshPtr_->boundaryMesh().findPatchID(patchName);
207 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
209 scalar UMag = sqrt(Ux0 * Ux0 + Uy0 * Uy0);
210 scalar UxNew = UMag * cos(aoaForwardAD);
211 scalar UyNew = UMag * sin(aoaForwardAD);
213 if (
U.boundaryField()[patchI].type() ==
"fixedValue")
215 forAll(
U.boundaryField()[patchI], faceI)
217 U.boundaryFieldRef()[patchI][faceI][flowAxisIndex] = UxNew;
218 U.boundaryFieldRef()[patchI][faceI][normalAxisIndex] = UyNew;
221 else if (
U.boundaryField()[patchI].type() ==
"inletOutlet")
223 mixedFvPatchField<vector>& inletOutletPatch =
224 refCast<mixedFvPatchField<vector>>(
U.boundaryFieldRef()[patchI]);
226 forAll(
U.boundaryField()[patchI], faceI)
228 inletOutletPatch.refValue()[faceI][flowAxisIndex] = UxNew;
229 inletOutletPatch.refValue()[faceI][normalAxisIndex] = UyNew;
235 else if (type ==
"BC")
237 scalar BCForwardAD = -1e16;
239 if (designVarName ==
"MRF")
241 const IOMRFZoneListDF&
MRF = meshPtr_->thisDb().lookupObject<IOMRFZoneListDF>(
"MRFProperties");
244 scalar& omega =
const_cast<scalar&
>(
MRF.getOmegaRef());
247 Info <<
"Setting the seed for BCForwardAD: " << BCForwardAD << endl;
248 BCForwardAD.setGradient(1.0);
257 word varName = dvSubDict.getWord(
"variable");
260 dvSubDict.readEntry<wordList>(
"patches", patches);
262 label comp = dvSubDict.getLabel(
"comp");
267 word patchName = patches[idxI];
268 label patchI = meshPtr_->boundaryMesh().findPatchID(patchName);
269 if (meshPtr_->thisDb().foundObject<volVectorField>(varName))
271 volVectorField& state(
const_cast<volVectorField&
>(
272 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
274 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
276 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
278 BCForwardAD = state.boundaryFieldRef()[patchI][0][comp];
280 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
281 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
283 mixedFvPatchField<vector>& inletOutletPatch =
284 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
285 BCForwardAD = inletOutletPatch.refValue()[0][comp];
289 else if (meshPtr_->thisDb().foundObject<volScalarField>(varName))
291 volScalarField& state(
const_cast<volScalarField&
>(
292 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
294 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
296 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
298 BCForwardAD = state.boundaryFieldRef()[patchI][0];
300 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
301 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
303 mixedFvPatchField<scalar>& inletOutletPatch =
304 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
305 BCForwardAD = inletOutletPatch.refValue()[0];
313 reduce(BCForwardAD, maxOp<scalar>());
315 Info <<
"Setting the seed for BCForwardAD: " << BCForwardAD << endl;
316 BCForwardAD.setGradient(1.0);
321 word patchName = patches[idxI];
322 label patchI = meshPtr_->boundaryMesh().findPatchID(patchName);
323 if (meshPtr_->thisDb().foundObject<volVectorField>(varName))
325 volVectorField& state(
const_cast<volVectorField&
>(
326 meshPtr_->thisDb().lookupObject<volVectorField>(varName)));
328 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
330 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
332 forAll(state.boundaryFieldRef()[patchI], faceI)
334 state.boundaryFieldRef()[patchI][faceI][comp] = BCForwardAD;
337 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
338 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
340 mixedFvPatchField<vector>& inletOutletPatch =
341 refCast<mixedFvPatchField<vector>>(state.boundaryFieldRef()[patchI]);
342 vector val = inletOutletPatch.refValue()[0];
343 val[comp] = BCForwardAD;
344 inletOutletPatch.refValue() = val;
348 else if (meshPtr_->thisDb().foundObject<volScalarField>(varName))
350 volScalarField& state(
const_cast<volScalarField&
>(
351 meshPtr_->thisDb().lookupObject<volScalarField>(varName)));
353 if (meshPtr_->boundaryMesh()[patchI].size() > 0)
355 if (state.boundaryFieldRef()[patchI].type() ==
"fixedValue")
357 forAll(state.boundaryFieldRef()[patchI], faceI)
359 state.boundaryFieldRef()[patchI][faceI] = BCForwardAD;
362 else if (state.boundaryFieldRef()[patchI].type() ==
"inletOutlet"
363 || state.boundaryFieldRef()[patchI].type() ==
"outletInlet")
365 mixedFvPatchField<scalar>& inletOutletPatch =
366 refCast<mixedFvPatchField<scalar>>(state.boundaryFieldRef()[patchI]);
367 inletOutletPatch.refValue() = BCForwardAD;