Introduction to tutorial 3
The problems consists of steady Navier-Stokes problem with parametrized viscosity. The physical problem is the backward facing step depicted in the following image:
At the inlet a uniform and constant
velocity equal to 1 m/s is prescribed.
A detailed look into the code
In this section are explained the main steps necessary to construct the tutorial N°3
The necessary header files
First of all let's have a look to the header files that needs to be included and what they are responsible for:
The header file of ITHACA-FV necessary for this tutorial
\*---------------------------------------------------------------------------*/
#include "IOmanip.H"
#include "forces.H"
{
public:
{
Vector<double> inl(0, 0, 0);
List<scalar> mu_now(1);
{
}
else
{
Vector<double>
Uinl(0, 0, 0);
for (label
i = 0;
i <
mu.cols();
i++)
{
}
}
}
};
int main(
int argc,
char* argv[])
{
#if OPENFOAM > 1812
argList::addOption("stage", "offline", "Perform offline stage");
argList::addOption("stage", "online", "Perform online stage");
HashTable<string> validParOptions;
validParOptions.set
(
"stage",
"offline"
);
validParOptions.set
(
"stage",
"online"
);
Pstream::addValidParOptions(validParOptions);
if (example._args().get("stage").match("offline"))
{
}
else if (example._args().get("stage").match("online"))
{
}
else
{
Info << "Pass '-stage offline', '-stage online'" << endl;
}
#else
if (argc == 1)
{
Info << "Pass 'offline' or 'online' as first arguments."
<< endl;
exit(0);
}
int argc_proc = argc - 1;
char* argv_proc[argc_proc];
argv_proc[0] = argv[0];
if (argc > 2)
{
std::copy(argv + 2, argv + argc, argv_proc + 1);
}
argc--;
if (std::strcmp(argv[1], "offline") == 0)
{
}
else if (std::strcmp(argv[1], "online") == 0)
{
}
else
{
Info << "Pass offline, online" << endl;
}
#endif
exit(0);
}
{
int NmodesUout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesUout", 15);
int NmodesPout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesPout", 15);
int NmodesSUPout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesSUPout", 15);
int NmodesUproj = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesUproj", 10);
int NmodesPproj = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesPproj", 10);
int NmodesSUPproj =
para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesSUPproj", 10);
word filename("./parOffline");
{
example.
podex, 0, 0, NmodesUout);
}
else
{
example.
podex, 0, 0, NmodesUout);
}
example.
podex, 0, 0, NmodesPout);
example.
projectSUP(
"./Matrices", NmodesUproj, NmodesPproj, NmodesSUPproj);
}
{
void online_stage(tutorial02 &example, tutorial02 &FOM_test)
void offline_stage(tutorial02 &example, tutorial02 &FOM_test)
Header file of the ITHACAPOD class.
Header file of the ITHACAstream class, it contains the implementation of several methods for input ou...
Header file of the reducedSteadyNS class.
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
IOdictionary * ITHACAdict
Dictionary for input objects from file.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Class where it is implemented a reduced problem for the steady Navier-stokes problem.
Eigen::MatrixXd mu_samples
Matrix of parameters to be used for PODI, where each row corresponds to a sample point....
void computeLift(T &Lfield, T &liftfield, T &omfield)
Homogenize the snapshot matrix, it works with PtrList of volVectorField and volScalarField.
bool offline
Boolean variable, it is 1 if the Offline phase has already been computed, else 0.
Eigen::MatrixXd mu
Row matrix of parameters.
autoPtr< argList > _args
argList
Eigen::MatrixXi inletIndex
Matrix that contains informations about the inlet boundaries.
bool podex
Boolean variable, it is 1 if the POD has already been computed, else 0.
void truthSolve()
Perform a TruthSolve.
Implementation of a parametrized full order steady NS problem and preparation of the the reduced ma...
void change_viscosity(double mu)
Function to change the viscosity.
void restart()
set U and P back to the values into the 0 folder
bool supex
Boolean variable to check the existence of the supremizer modes.
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
volVectorModes supmodes
List of pointers used to form the supremizer modes.
void solvesupremizer(word type="snapshots")
solve the supremizer either with the use of the pressure snaphots or the pressure modes
autoPtr< Time > _runTime
Time.
volVectorModes Umodes
List of pointers used to form the velocity modes.
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
steadyNS()
Null constructor.
autoPtr< fvMesh > _mesh
Mesh.
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
PtrList< volVectorField > Uomfield
List of pointers used to form the homogeneous velocity snapshots.
PtrList< volVectorField > supfield
List of pointers used to form the supremizer snapshots matrix.
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
void projectSUP(fileName folder, label NUmodes, label NPmodes, label NSUPmodes)
Project using a supremizer approach.
autoPtr< volVectorField > _U
Velocity field.
volScalarModes Pmodes
List of pointers used to form the pressure modes.
word bcMethod
Boundary Method.
autoPtr< volScalarField > _p
Pressure field.
void offlineSolve()
Perform an Offline solve.
volScalarField & p
Pressure field.
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.
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.
void normalizeFields(PtrList< GeometricField< Type, fvPatchField, volMesh > > &fields)
Normalize list of Geometric fields.
Header file of the steadyNS class.
Implementation of the tutorial03 class
Then we can define the tutorial03 class as a child of the steadyNS class
The members of the class are the fields that needs to be manipulated during the resolution of the problem
Inside the class it is defined the offlineSolve method according to the specific parametrized problem that needs to be solved.
If the offline solve has already been performed than read the existing snapshots
else perform the offline solve where a loop over all the parameters is performed:
See also the steadyNS class for the definition of the methods.
Definition of the main function
Once the tutorial03 class is defined the main function is defined, an example of type tutorial03 is constructed:
In this case the vector of parameter is read from a txt file
The inlet boundary is set:
and the offline stage is performed:
and the supremizer problem is solved:
In order to show the functionality of reading fields in this case the lifting function is read from a precomputed simulation with a unitary inlet velocity:
Then the snapshots matrix is homogenized:
and the modes for velocity, pressure and supremizers are obtained:
then the projection onto the POD modes is performed with:
the reduced object is constructed:
and the online solve is performed for some values of the viscosity:
The vel_now matrix in this case is not used since there are no parametrized boundary conditions.
The viscosity is set with the command:
reduced.nu = example.
mu(k,0)
finally the online solution stored during the online solve is exported to file in three different formats with the lines:
and the online solution is reconstructed and exported to file
The plain program
Here there's the plain code
#include "IOmanip.H"
#include "forces.H"
{
public:
{
Vector<double> inl(0, 0, 0);
List<scalar> mu_now(1);
{
}
else
{
Vector<double>
Uinl(0, 0, 0);
for (label
i = 0;
i <
mu.cols();
i++)
{
}
}
}
};
int main(
int argc,
char* argv[])
{
#if OPENFOAM > 1812
argList::addOption("stage", "offline", "Perform offline stage");
argList::addOption("stage", "online", "Perform online stage");
HashTable<string> validParOptions;
validParOptions.set
(
"stage",
"offline"
);
validParOptions.set
(
"stage",
"online"
);
Pstream::addValidParOptions(validParOptions);
if (example.
_args().get(
"stage").match(
"offline"))
{
}
else if (example.
_args().get(
"stage").match(
"online"))
{
}
else
{
Info << "Pass '-stage offline', '-stage online'" << endl;
}
#else
if (argc == 1)
{
Info << "Pass 'offline' or 'online' as first arguments."
<< endl;
exit(0);
}
int argc_proc = argc - 1;
char* argv_proc[argc_proc];
argv_proc[0] = argv[0];
if (argc > 2)
{
std::copy(argv + 2, argv + argc, argv_proc + 1);
}
argc--;
if (std::strcmp(argv[1], "offline") == 0)
{
}
else if (std::strcmp(argv[1], "online") == 0)
{
}
else
{
Info << "Pass offline, online" << endl;
}
#endif
exit(0);
}
{
int NmodesUout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesUout", 15);
int NmodesPout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesPout", 15);
int NmodesSUPout = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesSUPout", 15);
int NmodesUproj = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesUproj", 10);
int NmodesPproj = para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesPproj", 10);
int NmodesSUPproj =
para->
ITHACAdict->lookupOrDefault<
int>(
"NmodesSUPproj", 10);
word filename("./parOffline");
{
example.
podex, 0, 0, NmodesUout);
}
else
{
example.
podex, 0, 0, NmodesUout);
}
example.
podex, 0, 0, NmodesPout);
example.
projectSUP(
"./Matrices", NmodesUproj, NmodesPproj, NmodesSUPproj);
}
{
word filename("./parOnline");
Eigen::MatrixXd vel_now(1, 1);
vel_now(0, 0) = 1;
reduced.tauU = Eigen::MatrixXd::Zero(1, 1);
reduced.tauU(0, 0) = 1e-1;
for (label k = 0; k < example.
mu.size(); k++)
{
Info << "Evaluation of the reduced order model on the test set" << endl;
Info <<
"Inlet Ux = " << vel_now(0, 0) <<
" nu = " << example.
mu(0, k)
<< endl;
reduced.nu = example.
mu(0, k);
reduced.solveOnline_sup(vel_now);
Eigen::MatrixXd tmp_sol(reduced.y.rows() + 1, 1);
tmp_sol(0) = k + 1;
tmp_sol.col(0).tail(reduced.y.rows()) = reduced.y;
reduced.online_solution.append(tmp_sol);
}
"./ITHACAoutput/red_coeff");
"./ITHACAoutput/red_coeff");
"./ITHACAoutput/red_coeff");
reduced.reconstruct(true, "./ITHACAoutput/Reconstruction/");
if (Pstream::parRun())
{
bool endedOnline = true;
reduce(endedOnline, sumOp<label>());
}
}
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 ...