17 DARegression::DARegression(
24 mesh.time().timeName(),
34 dictionary regSubDict = daOption.
getAllOptions().subDict(
"regressionModel");
35 active_ = regSubDict.getLabel(
"active");
40 forAll(regSubDict.toc(), idxI)
42 word key = regSubDict.toc()[idxI];
52 dictionary modelSubDict = daOption.
getAllOptions().subDict(
"regressionModel").subDict(modelName);
54 modelType_.set(modelName, modelSubDict.getWord(
"modelType"));
56 wordList tempWordList;
57 scalarList tempScalarList;
58 labelList tempLabelList;
60 modelSubDict.readEntry<wordList>(
"inputNames", tempWordList);
63 outputName_.set(modelName, modelSubDict.getWord(
"outputName"));
65 modelSubDict.readEntry<scalarList>(
"inputShift", tempScalarList);
68 modelSubDict.readEntry<scalarList>(
"inputScale", tempScalarList);
71 outputShift_.set(modelName, modelSubDict.getScalar(
"outputShift"));
73 outputScale_.set(modelName, modelSubDict.getScalar(
"outputScale"));
81 printInputInfo_.set(modelName, modelSubDict.getLabel(
"printInputInfo"));
83 writeFeatures_.set(modelName, modelSubDict.lookupOrDefault<label>(
"writeFeatures", 0));
87 modelSubDict.readEntry<labelList>(
"hiddenLayerNeurons", tempLabelList);
92 leakyCoeff_.set(modelName, modelSubDict.lookupOrDefault<scalar>(
"leakyCoeff", 0.0));
95 else if (
modelType_[modelName] ==
"radialBasisFunction")
97 nRBFs_.set(modelName, modelSubDict.getLabel(
"nRBFs"));
99 else if (
modelType_[modelName] ==
"externalTensorFlow")
111 FatalErrorIn(
"DARegression") <<
"modelType_: " <<
modelType_[modelName] <<
" not supported. Options are: neuralNetwork, radialBasisFunction, and externalTensorFlow" << abort(FatalError);
118 FatalErrorIn(
"DARegression") <<
"inputNames has different sizes than inputShift or inputScale" << abort(FatalError);
127 PtrList<volScalarField> features(nInputs);
136 mesh_.time().timeName(),
141 dimensionedScalar(inputName, dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0)));
150 #if defined(CODI_ADF)
152 outputFieldArrayDouble_ =
new double[
mesh_.nCells()];
177 if (inputName ==
"VoS")
180 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
181 const tmp<volTensorField> tgradU(fvc::grad(
U));
182 const volTensorField& gradU = tgradU();
183 volScalarField magOmega = mag(skew(gradU));
184 volScalarField magS = mag(symm(gradU));
187 features_[modelName][idxI][cellI] = (magOmega[cellI] / (magS[cellI] + magOmega[cellI] + 1e-16) +
inputShift_[modelName][idxI]) *
inputScale_[modelName][idxI];
189 features_[modelName][idxI].correctBoundaryConditions();
191 else if (inputName ==
"PoD")
199 features_[modelName][idxI].correctBoundaryConditions();
201 else if (inputName ==
"chiSA")
204 const volScalarField& nuTilda =
mesh_.thisDb().lookupObject<volScalarField>(
"nuTilda");
208 features_[modelName][idxI][cellI] = (nuTilda[cellI] / (nu[cellI] + nuTilda[cellI] + 1e-16) +
inputShift_[modelName][idxI]) *
inputScale_[modelName][idxI];
210 features_[modelName][idxI].correctBoundaryConditions();
212 else if (inputName ==
"pGradStream")
215 const volScalarField&
p =
mesh_.thisDb().lookupObject<volScalarField>(
"p");
216 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
217 volVectorField pGrad(
"gradP", fvc::grad(
p));
218 volScalarField pG_denominator(mag(
U) * mag(pGrad) + mag(
U & pGrad));
219 forAll(pG_denominator, cellI)
221 pG_denominator[cellI] += 1e-16;
223 volScalarField::Internal pGradAlongStream = (
U() & pGrad()) / pG_denominator();
229 features_[modelName][idxI].correctBoundaryConditions();
231 else if (inputName ==
"PSoSS")
234 const volScalarField&
p =
mesh_.thisDb().lookupObject<volScalarField>(
"p");
235 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
236 const tmp<volTensorField> tgradU(fvc::grad(
U));
237 const volTensorField& gradU = tgradU();
238 volVectorField pGrad(
"gradP", fvc::grad(
p));
239 vector diagUGrad = vector::zero;
243 diagUGrad[0] = gradU[cellI].xx();
244 diagUGrad[1] = gradU[cellI].yy();
245 diagUGrad[2] = gradU[cellI].zz();
246 val = mag(pGrad[cellI]) / (mag(pGrad[cellI]) + mag(3.0 * cmptAv(
U[cellI] & diagUGrad)) + 1e-16);
249 features_[modelName][idxI].correctBoundaryConditions();
251 else if (inputName ==
"SCurv")
254 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
255 const tmp<volTensorField> tgradU(fvc::grad(
U));
256 const volTensorField& gradU = tgradU();
261 val = mag(
U[cellI] & gradU[cellI]) / (mag(
U[cellI] &
U[cellI]) + mag(
U[cellI] & gradU[cellI]) + 1e-16);
264 features_[modelName][idxI].correctBoundaryConditions();
266 else if (inputName ==
"UOrth")
269 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
270 const tmp<volTensorField> tgradU(fvc::grad(
U));
271 const volTensorField& gradU = tgradU();
276 val = mag(
U[cellI] & gradU[cellI] &
U[cellI]) / (mag(
U[cellI]) * mag(gradU[cellI] &
U[cellI]) + mag(
U[cellI] & gradU[cellI] &
U[cellI]) + 1e-16);
279 features_[modelName][idxI].correctBoundaryConditions();
281 else if (inputName ==
"KoU2")
284 const volScalarField&
k =
mesh_.thisDb().lookupObject<volScalarField>(
"k");
285 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
289 val =
k[cellI] / (0.5 * (
U[cellI] &
U[cellI]) +
k[cellI] + 1e-16);
292 features_[modelName][idxI].correctBoundaryConditions();
294 else if (inputName ==
"ReWall")
297 const volScalarField& y =
mesh_.thisDb().lookupObject<volScalarField>(
"yWall");
298 const volScalarField&
k =
mesh_.thisDb().lookupObject<volScalarField>(
"k");
303 val = sqrt(
k[cellI]) * y[cellI] / (50.0 * nu[cellI] + sqrt(
k[cellI]) * y[cellI] + 1e-16);
306 features_[modelName][idxI].correctBoundaryConditions();
308 else if (inputName ==
"CoP")
316 features_[modelName][idxI].correctBoundaryConditions();
318 else if (inputName ==
"TauoK")
321 const volScalarField&
k =
mesh_.thisDb().lookupObject<volScalarField>(
"k");
322 const volScalarField& nut =
mesh_.thisDb().lookupObject<volScalarField>(
"nut");
323 const volVectorField&
U =
mesh_.thisDb().lookupObject<volVectorField>(
"U");
324 volSymmTensorField tau(2.0 / 3.0 * I *
k - nut * twoSymm(fvc::grad(
U)));
328 val = mag(tau[cellI]) / (
k[cellI] + mag(tau[cellI]) + 1e-16);
331 features_[modelName][idxI].correctBoundaryConditions();
335 FatalErrorIn(
"") <<
"inputName: " << inputName <<
" not supported. Options are: VoS, PoD, chiSA, pGradStream, PSoSS, SCurv, UOrth, KoU2, ReWall, CoP, TauoK" << abort(FatalError);
385 volScalarField& outputField =
const_cast<volScalarField&
>(
mesh_.thisDb().lookupObject<volScalarField>(
outputName_[modelName]));
390 List<List<scalar>> layerVals;
391 layerVals.setSize(nHiddenLayers);
392 for (label layerI = 0; layerI < nHiddenLayers; layerI++)
395 layerVals[layerI].setSize(nNeurons);
402 for (label layerI = 0; layerI < nHiddenLayers; layerI++)
405 forAll(layerVals[layerI], neuronI)
407 layerVals[layerI][neuronI] = 0.0;
409 for (label neuronI = 0; neuronI < nNeurons; neuronI++)
417 layerVals[layerI][neuronI] +=
features_[modelName][neuronJ][cellI] *
parameters_[modelName][counterI];
424 forAll(layerVals[layerI - 1], neuronJ)
427 layerVals[layerI][neuronI] += layerVals[layerI - 1][neuronJ] *
parameters_[modelName][counterI];
432 layerVals[layerI][neuronI] +=
parameters_[modelName][counterI];
437 layerVals[layerI][neuronI] = 1 / (1 + exp(-layerVals[layerI][neuronI]));
441 layerVals[layerI][neuronI] = (1 - exp(-2 * layerVals[layerI][neuronI])) / (1 + exp(-2 * layerVals[layerI][neuronI]));
445 if (layerVals[layerI][neuronI] < 0)
447 layerVals[layerI][neuronI] =
leakyCoeff_[modelName] * layerVals[layerI][neuronI];
452 FatalErrorIn(
"") <<
"activationFunction not valid. Options are: sigmoid, tanh, and relu" << abort(FatalError);
457 scalar outputVal = 0.0;
458 forAll(layerVals[nHiddenLayers - 1], neuronJ)
461 outputVal += layerVals[nHiddenLayers - 1][neuronJ] *
parameters_[modelName][counterI];
475 outputField.correctBoundaryConditions();
477 else if (
modelType_[modelName] ==
"radialBasisFunction")
482 label dP = 2 * nInputs + 1;
486 scalar outputVal = 0.0;
487 for (label i = 0; i <
nRBFs_[modelName]; i++)
489 scalar expCoeff = 0.0;
490 for (label j = 0; j < nInputs; j++)
496 outputVal +=
parameters_[modelName][dP * i + dP - 1] * exp(-expCoeff);
505 outputField.correctBoundaryConditions();
507 else if (
modelType_[modelName] ==
"externalTensorFlow")
510 label nCells =
mesh_.nCells();
515 #if defined(CODI_ADR)
516 Info <<
"WARNINGN...... Regression model for ADR is not implemented..." << endl;
565 #elif defined(CODI_ADF)
566 Info <<
"WARNINGN...... Regression model for ADF is not implemented..." << endl;
609 counterI = cellI * nInputs + idxI;
614 forAll(outputField, cellI)
623 forAll(outputField, cellI)
631 FatalErrorIn(
"") <<
"modelType_: " <<
modelType_ <<
" not supported. Options are: neuralNetwork, radialBasisFunction, and externalTensorFlow" << abort(FatalError);
647 FatalErrorIn(
"") <<
"nParameters() is called but the regression model is not active!" << abort(FatalError);
677 else if (
modelType_[modelName] ==
"radialBasisFunction")
686 else if (
modelType_[modelName] ==
"externalTensorFlow")
693 FatalErrorIn(
"") <<
"modelType_: " <<
modelType_[modelName] <<
" not supported. Options are: neuralNetwork, radialBasisFunction, and externalTensorFlow" << abort(FatalError);
717 if (std::isnan(outputField[cellI]))
722 if (std::isinf(outputField[cellI]))
746 Pout <<
"************* Warning! output values have nan and are set to " <<
defaultOutputValue_[modelName] << endl;
752 Pout <<
"************* Warning! output values have inf and are set to " <<
defaultOutputValue_[modelName] << endl;
756 reduce(fail, sumOp<label>());