30#include <torch/script.h>
31#include <torch/torch.h>
52 NUmodes =
para->ITHACAdict->lookupOrDefault<label>(
"NmodesUproj", 10);
53 NNutModes =
para->ITHACAdict->lookupOrDefault<label>(
"NmodesNutProj", 10);
81 torch::nn::Sequential
Net;
87 std::string Msg = filename +
88 " is not existing, please run the training stage of the net with the correct number of modes for U and Nut";
107 mkDir(
"ITHACAoutput/NN/coeffs");
109 PtrList<volVectorField> UfieldTrain;
110 PtrList<volScalarField> PfieldTrain;
111 PtrList<volScalarField> nutFieldsTrain;
113 "./ITHACAoutput/Offline/");
115 "./ITHACAoutput/Offline/");
116 auto nut_train =
_mesh().lookupObject<volScalarField>(
"nut");
118 "./ITHACAoutput/Offline/");
120 std::cout <<
"Computing the coefficients for U train" << std::endl;
124 std::cout <<
"Computing the coefficients for p train" << std::endl;
128 std::cout <<
"Computing the coefficients for nuT train" << std::endl;
132 coeffL2U_train.transposeInPlace();
133 coeffL2P_train.transposeInPlace();
134 coeffL2Nut_train.transposeInPlace();
135 cnpy::save(coeffL2U_train,
"ITHACAoutput/NN/coeffs/coeffL2UTrain.npy");
136 cnpy::save(coeffL2P_train,
"ITHACAoutput/NN/coeffs/coeffL2PTrain.npy");
137 cnpy::save(coeffL2Nut_train,
"ITHACAoutput/NN/coeffs/coeffL2NutTrain.npy");
139 PtrList<volVectorField> UfieldTest;
140 PtrList<volScalarField> PfieldTest;
141 PtrList<volScalarField> nutFieldsTest;
144 "./ITHACAoutput/checkOff/");
146 "./ITHACAoutput/checkOff/");
147 auto nut_test =
_mesh().lookupObject<volScalarField>(
"nut");
149 "./ITHACAoutput/checkOff/");
160 coeffL2U_test.transposeInPlace();
161 coeffL2P_test.transposeInPlace();
162 coeffL2Nut_test.transposeInPlace();
163 cnpy::save(coeffL2U_test,
"ITHACAoutput/NN/coeffs/coeffL2UTest.npy");
164 cnpy::save(coeffL2P_test,
"ITHACAoutput/NN/coeffs/coeffL2PTest.npy");
165 cnpy::save(coeffL2Nut_test,
"ITHACAoutput/NN/coeffs/coeffL2NutTest.npy");
243 Eigen::MatrixXd
evalNet(Eigen::MatrixXd a, Eigen::MatrixXd mu_now)
245 Eigen::MatrixXd xpred(a.rows() + mu_now.rows(), 1);
247 if (xpred.cols() != 1)
249 throw std::runtime_error(
"Predictions for more than one sample not supported yet.");
252 xpred.bottomRows(a.rows()) = a;
253 xpred.topRows(mu_now.rows()) = mu_now;
255 xpred.transposeInPlace();
258 std::vector<torch::jit::IValue> XTensorInp;
259 XTensorInp.push_back(xTensor);
262 g.transposeInPlace();
283 PtrList<volVectorField> gradModP;
285 for (label
i = 0;
i < NmodesPproj;
i++)
287 gradModP.append(fvc::grad(
problem->Pmodes[
i]));
295 int NmodesNutProj, Eigen::MatrixXd mu_now,
296 word Folder =
"./ITHACAoutput/Online/")
300 scalar residualNorm(1);
301 scalar residualJump(1);
302 Eigen::MatrixXd uResidualOld = Eigen::MatrixXd::Zero(1, NmodesUproj);
303 Eigen::MatrixXd eResidualOld = Eigen::MatrixXd::Zero(1, NmodesEproj);
304 Eigen::MatrixXd pResidualOld = Eigen::MatrixXd::Zero(1, NmodesPproj);
305 Eigen::VectorXd uResidual(Eigen::Map<Eigen::VectorXd>(uResidualOld.data(),
307 Eigen::VectorXd eResidual(Eigen::Map<Eigen::VectorXd>(eResidualOld.data(),
309 Eigen::VectorXd pResidual(Eigen::Map<Eigen::VectorXd>(pResidualOld.data(),
313 float residualJumpLim =
314 para->ITHACAdict->lookupOrDefault<
float>(
"residualJumpLim", 1e-5);
315 float normalizedResidualLim =
316 para->ITHACAdict->lookupOrDefault<
float>(
"normalizedResidualLim", 1e-5);
318 para->ITHACAdict->lookupOrDefault<
float>(
"maxIter", 2000);
325 volScalarField& P =
problem->_p();
326 volScalarField& E =
problem->pThermo->he();
328 volScalarField nueff =
problem->turbulence->nuEff();
329 volScalarField&
nut =
const_cast<volScalarField&
>
330 (
problem->_mesh().lookupObject<volScalarField>(
"nut"));
350 Eigen::MatrixXd nutCoeff =
problem->evalNet(u, mu_now);
351 problem->nutModes.reconstruct(
nut, nutCoeff,
"nut");
354 problem->_mesh().boundaryMesh().findPatchID(
"inlet");
355 vector Uinlet(
problem->_U().boundaryFieldRef()[idInl][0][0], 0, 0);
358 while ((residualJump > residualJumpLim
359 || residualNorm > normalizedResidualLim) &&
csolve <
maxIter)
362 Info <<
"csolve:" <<
csolve << endl;
368 uResidualOld = uResidual;
369 eResidualOld = eResidual;
370 pResidualOld = pResidual;
372 List<Eigen::MatrixXd> RedLinSysU;
379 - fvc::div((
rho * nueff) * dev2(
T(fvc::grad(
U))))
380 - fvm::laplacian(
rho * nueff,
U)
386 RedLinSysU =
problem->Umodes.project(UEqnR,
391 RedLinSysU[1] = RedLinSysU[1] - projGradP;
394 problem->Umodes.reconstruct(
U, u,
"U");
402 + fvc::div(
phi, volScalarField(
"Ekp", 0.5 * magSqr(
U) + P /
rho))
403 - fvm::laplacian(
problem->turbulence->alphaEff(), E)
409 List<Eigen::MatrixXd> RedLinSysE =
problem->Emodes.project(EEqnR, NmodesEproj);
411 problem->Emodes.reconstruct(E, e,
"e");
419 surfaceScalarField phiHbyACalculated =
problem->getPhiHbyA(UEqnR,
U, P);
421 List<Eigen::MatrixXd> RedLinSysP;
423 while (
problem->_simple().correctNonOrthogonal())
425 volScalarField
rAU(1.0 /
427 volVectorField
HbyA(constrainHbyA(
rAU * UEqnR.H(),
U,
429 surfaceScalarField
phiHbyA(
"phiHbyA", fvc::interpolate(
rho)*fvc::flux(
HbyA));
430 surfaceScalarField
rhorAUf(
"rhorAUf", fvc::interpolate(
rho *
rAU));
440 problem->_pressureControl().refCell(),
441 problem->_pressureControl().refValue()
443 RedLinSysP =
problem->Pmodes.project(PEqnR, NmodesPproj);
445 problem->Pmodes.reconstruct(P,
p,
"p");
447 if (
problem->_simple().finalNonOrthogonalIter())
449 phi =
problem->getPhiHbyA(UEqnR,
U, P) + PEqnR.flux();
454#include "incompressible/continuityErrs.H"
457 U.correctBoundaryConditions();
464 P += (
problem->_initialMass() - fvc::domainIntegrate(
psi * P))
465 / fvc::domainIntegrate(
psi);
470 P.correctBoundaryConditions();
475 std::cout <<
"Ures = " << (uResidual.cwiseAbs()).sum() /
476 (RedLinSysU[1].cwiseAbs()).sum() << std::endl;
477 std::cout <<
"Eres = " << (eResidual.cwiseAbs()).sum() /
478 (RedLinSysE[1].cwiseAbs()).sum() << std::endl;
479 std::cout <<
"Pres = " << (pResidual.cwiseAbs()).sum() /
480 (RedLinSysP[1].cwiseAbs()).sum() << std::endl;
481 residualNorm = max(max((uResidual.cwiseAbs()).sum() /
482 (RedLinSysU[1].cwiseAbs()).sum(),
483 (pResidual.cwiseAbs()).sum() / (RedLinSysP[1].cwiseAbs()).sum()),
484 (eResidual.cwiseAbs()).sum() / (RedLinSysE[1].cwiseAbs()).sum());
485 residualJump = max(max(((uResidual - uResidualOld).cwiseAbs()).sum() /
486 (RedLinSysU[1].cwiseAbs()).sum(),
487 ((pResidual - pResidualOld).cwiseAbs()).sum() /
488 (RedLinSysP[1].cwiseAbs()).sum()),
489 ((eResidual - eResidualOld).cwiseAbs()).sum() /
490 (RedLinSysE[1].cwiseAbs()).sum());
492 nutCoeff =
problem->evalNet(u, mu_now);
493 problem->nutModes.reconstruct(
nut, nutCoeff,
"nut");
519 middleExport =
para->ITHACAdict->lookupOrDefault<
bool>(
"middleExport",
true);
531 volVectorField&
U =
_U();
533 volScalarField&
p =
_p();
535 volScalarField& E =
_E();
544 auto nut =
_mesh().lookupObject<volScalarField>(
"nut");
551 double UIFinit =
para->ITHACAdict->lookupOrDefault<
double>(
"UIFinit", 250);
552 Vector<double>
Uinl(UIFinit, 0, 0);
555 for (label
i = 0;
i <
mu.rows();
i++)
559 std::cout <<
"Current mu = " <<
mu(
i, 0) << std::endl;
573int main(
int argc,
char* argv[])
582 std::cerr <<
"debug point 1" << std::endl;
585 std::ifstream exFileOff(
"./parsOff_mat.txt");
594 label OffNum =
para->ITHACAdict->lookupOrDefault<label>(
"OffNum", 25);
595 example.
mu = Eigen::VectorXd::LinSpaced(OffNum, 1.00e-05, 1.00e-02);
599 Eigen::MatrixXd parsOn;
600 std::ifstream exFileOn(
"./parsOn_mat.txt");
608 label OnNum =
para->ITHACAdict->lookupOrDefault<label>(
"OnNum", 20);
613 std::cerr <<
"debug point 2" << std::endl;
615 int NmodesUout =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesUout", 15);
616 int NmodesPout =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesPout", 15);
617 int NmodesEout =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesEout", 15);
618 int NmodesNutOut =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesNutOut", 15);
619 int NmodesUproj =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesUproj", 10);
620 int NmodesPproj =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesPproj", 10);
621 int NmodesEproj =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesEproj", 10);
622 int NmodesNutProj =
para->ITHACAdict->lookupOrDefault<
int>(
"NmodesNutProj", 10);
628 std::cerr <<
"debug point 3" << std::endl;
630 std::cerr <<
"debug point 4" << std::endl;
669 PtrList<volVectorField> UfieldCheck;
670 PtrList<volScalarField> PfieldCheck;
671 PtrList<volScalarField> EfieldCheck;
672 PtrList<volScalarField> nutFieldsCheck;
674 "./ITHACAoutput/checkOff/");
676 "./ITHACAoutput/checkOff/");
678 "./ITHACAoutput/checkOff/");
679 auto nutCheck = example.
_mesh().lookupObject<volScalarField>(
"nut");
681 "./ITHACAoutput/checkOff/");
688 Eigen::MatrixXd snapsCheck =
692 for (label k = 0; k < snapsCheck.rows(); k++)
695 fieldNum = fieldNum + snapsCheck(k, 0);
698 "./ITHACAoutput/checkOffSingle/");
700 "./ITHACAoutput/checkOffSingle/");
702 "./ITHACAoutput/checkOffSingle/");
704 "./ITHACAoutput/checkOffSingle/");
712 example.
loadNet(
"ITHACAoutput/NN/Net_" + name(NmodesUproj) +
"_" + name(
713 NmodesNutProj) +
".pt");
718 NmodesUproj) +
"_" + name(NmodesNutProj) +
"/" ) )
722 word OnlineFolder =
"./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" + name(
723 NmodesNutProj) +
"/";
724 cpuTimes.open(OnlineFolder +
"/cpuTimes", std::ios_base::app);
726 for (label k = 0; k < parsOn.rows(); k++)
729 std::clock_t startOn;
730 startOn = std::clock();
732 Eigen::MatrixXd mu_now = parsOn.row(k);
733 mu_now.transposeInPlace();
743 NmodesNutProj, mu_now,
"./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" +
744 name(NmodesNutProj) +
"/");
745 durationOn = std::clock() - startOn;
746 cpuTimes << durationOn << std::endl;
751 NmodesUproj) +
"_" + name(NmodesNutProj) +
"/" ) )
753 PtrList<volVectorField> offlineU, onlineU;
754 PtrList<volScalarField> offlineP, onlineP;
755 PtrList<volScalarField> offlineE, onlineE;
756 PtrList<volScalarField> offlineNut, onlineNut;
759 "./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" + name(NmodesNutProj) +
"/");
761 "./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" + name(NmodesNutProj) +
"/");
763 "./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" + name(NmodesNutProj) +
"/");
764 auto nut = example.
_mesh().lookupObject<volScalarField>(
"nut");
767 "./ITHACAoutput/Online_" + name(NmodesUproj) +
"_" + name(NmodesNutProj) +
"/");
770 "./ITHACAoutput/checkOffSingle/");
772 "./ITHACAoutput/checkOffSingle/");
774 "./ITHACAoutput/checkOffSingle/");
779 for (label j = 0; j < parsOn.rows(); j++)
781 volVectorField Ue = offlineU[j] - onlineU[j];
787 volScalarField Pe = offlineP[j] - onlineP[j];
792 volScalarField Ee = offlineE[j] - onlineE[j];
796 volScalarField Nute = offlineNut[j] - onlineNut[j];
805 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
806 NmodesNutProj) +
"/");
808 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
809 NmodesNutProj) +
"/");
811 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
812 NmodesNutProj) +
"/");
814 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
815 NmodesNutProj) +
"/");
824 "errorU" + name(NmodesUproj) +
"_" + name(NmodesNutProj),
"python",
825 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
826 NmodesNutProj) +
"/");
828 "errorP" + name(NmodesUproj) +
"_" + name(NmodesNutProj),
"python",
829 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
830 NmodesNutProj) +
"/");
832 "errorE" + name(NmodesUproj) +
"_" + name(NmodesNutProj),
"python",
833 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
834 NmodesNutProj) +
"/");
836 "errorNut" + name(NmodesUproj) +
"_" + name(NmodesNutProj),
"python",
837 "./ITHACAoutput/ErrorFields_" + name(NmodesUproj) +
"_" + name(
838 NmodesNutProj) +
"/");
int main(int argc, char *argv[])
Header file of the steadyNS class.
Header file of the ITHACAPOD class.
#define M_Assert(Expr, Msg)
Header file of the ITHACAstream class, it contains the implementation of several methods for input ou...
Header file of the reducedSteadyNS class.
CompressibleSteadyNN(int argc, char *argv[])
Constructor.
Eigen::MatrixXd scale_inp
Eigen::MatrixXd coeffL2Nut
torch::optim::Optimizer * optimizer
Eigen::MatrixXd evalNet(Eigen::MatrixXd a, Eigen::MatrixXd mu_now)
torch::nn::Sequential Net
torch::Tensor coeffL2U_tensor
torch::Tensor coeffL2Nut_tensor
Eigen::MatrixXd scale_out
torch::jit::script::Module netTorchscript
void loadNet(word filename)
Implementation of a parametrized full order steady NS problem and preparation of the the reduced ma...
PtrList< volScalarField > Efield
List of pointers used to store the energy solutions.
CompressibleSteadyNS()
Null constructor.
autoPtr< volScalarField > _p
volScalarModes Emodes
List of pointers used to form the energy modes.
void changeViscosity(double mu_new)
Function to change the viscosity.
bool middleExport
Export also intermediate fields.
autoPtr< volScalarField > _E
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
void projectReducedOperators(int NmodesUproj, int NmodesPproj, int NmodesEproj)
CompressibleSteadyNN * problem
Full problem.
ReducedCompressibleSteadyNN(CompressibleSteadyNN &FOMproblem)
Constructor.
void solveOnlineCompressible(int NmodesUproj, int NmodesPproj, int NmodesEproj, int NmodesNutProj, Eigen::MatrixXd mu_now, word Folder="./ITHACAoutput/Online/")
Class where it is implemented a reduced problem for the steady Navier-stokes problem.
Eigen::MatrixXd projGradModP
Projected gradient of the pressure modes.
ReducedCompressibleSteadyNS()
Construct Null.
PtrList< volScalarField > nutFields
List of snapshots for the solution for eddy viscosity.
volScalarModes nutModes
List of POD modes for eddy viscosity.
static Eigen::MatrixXd solveLinearSys(List< Eigen::MatrixXd > LinSys, Eigen::MatrixXd x, Eigen::VectorXd &residual, const Eigen::MatrixXd &bc=Eigen::MatrixXd::Zero(0, 0), const std::string solverType="fullPivLu")
Linear system solver for the online problem.
ITHACAparameters * para
parameters to be read from the ITHACAdict file
Eigen::MatrixXd mu_samples
Matrix of parameters to be used for PODI, where each row corresponds to a sample point....
void assignIF(T &s, G &value)
Assign internal field condition.
bool offline
Boolean variable, it is 1 if the Offline phase has already been computed, else 0.
Eigen::MatrixXd mu
Row matrix of parameters.
bool podex
Boolean variable, it is 1 if the POD has already been computed, else 0.
void truthSolve()
Perform a TruthSolve.
void restart()
set U and P back to the values into the 0 folder
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
volVectorModes Umodes
List of pointers used to form the velocity modes.
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
autoPtr< fvMesh > _mesh
Mesh.
autoPtr< incompressible::turbulenceModel > turbulence
Turbulence model.
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
autoPtr< volVectorField > _U
Velocity field.
volScalarModes Pmodes
List of pointers used to form the pressure modes.
autoPtr< volScalarField > _p
Pressure field.
void offlineSolve()
Perform an Offline solve.
volScalarField & p
Pressure field.
void offlineSolve(word folder="./ITHACAoutput/Offline/")
Perform an Offline solve.
volVectorField & U
Velocity field.
tutorial03(int argc, char *argv[])
Constructor.
void getModes(PtrList< GeometricField< Type, PatchField, GeoMesh > > &snapshots, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, word fieldName, bool podex, bool supex, bool sup, label nmodes, bool correctBC)
Computes the bases or reads them for a field.
void exportSolution(GeometricField< Type, PatchField, GeoMesh > &s, fileName subfolder, fileName folder, word fieldName)
Export a field to file in a certain folder and subfolder.
void readMiddleFields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, GeometricField< Type, PatchField, GeoMesh > &field, fileName casename)
Funtion to read a list of volVectorField from name of the field including all the intermediate snapsh...
void exportMatrix(Eigen::Matrix< T, -1, dim > &matrix, word Name, word type, word folder)
Export the reduced matrices in numpy (type=python), matlab (type=matlab) and txt (type=eigen) format ...
List< Eigen::MatrixXd > readMatrix(word folder, word mat_name)
Read a three dimensional matrix from a txt file in Eigen format.
void read_fields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, word Name, fileName casename, int first_snap, int n_snap)
Function to read a list of fields from the name of the field and casename.
torch::Tensor eigenMatrix2torchTensor(Eigen::Matrix< type, Eigen::Dynamic, Eigen::Dynamic > _eigenMatrix)
Convert an eigen Matrix to a torch tensor.
template Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > torchTensor2eigenMatrix< double >(torch::Tensor &torchTensor)
Eigen::VectorXd getCoeffs(GeometricField< Type, PatchField, GeoMesh > &snapshot, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Projects a snapshot on a basis function and gets the coefficients of the projection.
double L2Norm(GeometricField< scalar, fvPatchField, volMesh > &field)
double errorL2Rel(GeometricField< T, fvPatchField, volMesh > &field1, GeometricField< T, fvPatchField, volMesh > &field2, List< label > *labels)
Computes the relative error between two geometric Fields in L2 norm.
Eigen::MatrixXd rand(label rows, label cols, double min, double max)
Generates random matrix with random values in an interval.
void assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.
bool check_folder(word folder)
Checks if a folder exists.
bool check_file(std::string fileName)
Function that returns true if a file exists.
void save(const Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
Eigen::Matrix< T, -1, dim > load(Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
volScalarField rAU(1.0/Ueqn.A())
constrainPressure(p, rho, U, phiHbyA, rhorAtU, MRF)
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho *rAU))
Header file of the torch2Eigen namespace.