Loading...
Searching...
No Matches
03steadyNS.C

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 "ITHACAPOD.H"
#include "ITHACAstream.H"
#include "forces.H"
#include "steadyNS.H"
class tutorial03 : public steadyNS
{
public:
explicit tutorial03(int argc, char* argv[])
: steadyNS(argc, argv), U(_U()), p(_p()), args(_args()) {}
volVectorField& U;
volScalarField& p;
argList& args;
void offlineSolve()
{
Vector<double> inl(0, 0, 0);
List<scalar> mu_now(1);
// if the offline solution is already performed read the fields
if (offline)
{
ITHACAstream::read_fields(Ufield, U, "./ITHACAoutput/Offline/");
ITHACAstream::read_fields(Pfield, p, "./ITHACAoutput/Offline/");
ITHACAstream::readMatrix("./ITHACAoutput/Offline/mu_samples_mat.txt");
}
else
{
Vector<double> Uinl(0, 0, 0);
for (label i = 0; i < mu.cols(); i++)
{
mu_now[0] = mu(0, i);
truthSolve(mu_now);
}
}
}
};
void offline_stage(tutorial03& example);
void online_stage(tutorial03& example);
int main(int argc, char* argv[])
{
#if OPENFOAM > 1812
// load stage to perform
argList::addOption("stage", "offline", "Perform offline stage");
argList::addOption("stage", "online", "Perform online stage");
// add options for parallel run
HashTable<string> validParOptions;
validParOptions.set
(
"stage",
"offline"
);
validParOptions.set
(
"stage",
"online"
);
Pstream::addValidParOptions(validParOptions);
// Construct the tutorial object
tutorial03 example(argc, argv);
if (example._args().get("stage").match("offline"))
{
// perform the offline stage, extracting the modes from the snapshots'
// dataset corresponding to parOffline
offline_stage(example);
}
else if (example._args().get("stage").match("online"))
{
// load precomputed modes and reduced matrices
offline_stage(example);
// perform online solve with respect to the parameters in parOnline
online_stage(example);
}
else
{
Info << "Pass '-stage offline', '-stage online'" << endl;
}
#else
if (argc == 1)
{
Info << "Pass 'offline' or 'online' as first arguments."
<< endl;
exit(0);
}
// process arguments removing "offline" or "online" keywords
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--;
// Construct the tutorial object
tutorial03 example(argc, argv);
if (std::strcmp(argv[1], "offline") == 0)
{
// perform the offline stage, extracting the modes from the snapshots' dataset corresponding to parOffline
offline_stage(example);
}
else if (std::strcmp(argv[1], "online") == 0)
{
// load precomputed modes and reduced matrices
offline_stage(example);
// perform online solve with respect to the parameters in parOnline
online_stage(example);
}
else
{
Info << "Pass offline, online" << endl;
}
#endif
exit(0);
}
void offline_stage(tutorial03& example)
{
// Read some parameters from file
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);
// Read the par file where the training parameters are stored
word filename("./parOffline");
example.mu = ITHACAstream::readMatrix(filename);
// Set the inlet boundaries patch 0 directions x and y
example.inletIndex.resize(1, 2);
example.inletIndex(0, 0) = 0;
example.inletIndex(0, 1) = 0;
// Perform the offline solve
example.offlineSolve();
// Solve the supremizer problem
example.solvesupremizer();
if (example.bcMethod == "lift")
{
ITHACAstream::read_fields(example.liftfield, example._U(), "./lift/");
// Homogenize the snapshots
example.computeLift(example.Ufield, example.liftfield, example.Uomfield);
// Perform POD on the velocity snapshots
ITHACAPOD::getModes(example.Uomfield, example.Umodes, example._U().name(),
example.podex, 0, 0, NmodesUout);
}
else
{
ITHACAPOD::getModes(example.Ufield, example.Umodes, example._U().name(),
example.podex, 0, 0, NmodesUout);
}
// Perform POD on velocity pressure and supremizers and store the first 10
// modes
ITHACAPOD::getModes(example.Pfield, example.Pmodes, example._p().name(),
example.podex, 0, 0, NmodesPout);
ITHACAPOD::getModes(example.supfield, example.supmodes, example._U().name(),
example.podex, example.supex, 1, NmodesSUPout);
// Perform the Galerkin Projection
example.projectSUP("./Matrices", NmodesUproj, NmodesPproj, NmodesSUPproj);
}
void online_stage(tutorial03& example)
{
// Create the reduced object
reducedSteadyNS reduced(example);
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...
Definition steadyNS.H:70
void change_viscosity(double mu)
Function to change the viscosity.
Definition steadyNS.C:2014
void restart()
set U and P back to the values into the 0 folder
Definition steadyNS.C:2253
bool supex
Boolean variable to check the existence of the supremizer modes.
Definition steadyNS.H:256
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
Definition steadyNS.H:86
volVectorModes supmodes
List of pointers used to form the supremizer modes.
Definition steadyNS.H:104
void solvesupremizer(word type="snapshots")
solve the supremizer either with the use of the pressure snaphots or the pressure modes
Definition steadyNS.C:136
autoPtr< Time > _runTime
Time.
Definition steadyNS.H:290
volVectorModes Umodes
List of pointers used to form the velocity modes.
Definition steadyNS.H:101
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
Definition steadyNS.H:89
steadyNS()
Null constructor.
Definition steadyNS.C:40
autoPtr< fvMesh > _mesh
Mesh.
Definition steadyNS.H:281
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
Definition steadyNS.H:110
PtrList< volVectorField > Uomfield
List of pointers used to form the homogeneous velocity snapshots.
Definition steadyNS.H:113
PtrList< volVectorField > supfield
List of pointers used to form the supremizer snapshots matrix.
Definition steadyNS.H:92
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
Definition steadyNS.H:272
void projectSUP(fileName folder, label NUmodes, label NPmodes, label NSUPmodes)
Project using a supremizer approach.
Definition steadyNS.C:543
autoPtr< volVectorField > _U
Velocity field.
Definition steadyNS.H:263
volScalarModes Pmodes
List of pointers used to form the pressure modes.
Definition steadyNS.H:98
word bcMethod
Boundary Method.
Definition steadyNS.H:317
autoPtr< volScalarField > _p
Pressure field.
Definition steadyNS.H:260
void offlineSolve()
Perform an Offline solve.
Definition 03steadyNS.C:52
volScalarField & p
Pressure field.
Definition 03steadyNS.C:47
argList & args
Arg List.
Definition 03steadyNS.C:49
volVectorField & U
Velocity field.
Definition 03steadyNS.C:45
tutorial03(int argc, char *argv[])
Constructor.
Definition 03steadyNS.C:41
int main(int argc, char *argv[])
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.
Definition ITHACAPOD.C:93
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.
label i
Definition pEqn.H:46
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

/*---------------------------------------------------------------------------*\
██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
* In real Time Highly Advanced Computational Applications for Finite Volumes
* Copyright (C) 2017 by the ITHACA-FV authors
-------------------------------------------------------------------------------
License
This file is part of ITHACA-FV
ITHACA-FV is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ITHACA-FV is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
Description
Example of steady NS Reduction Problem
SourceFiles
03steadyNS.C
\*---------------------------------------------------------------------------*/
#include "IOmanip.H"
#include "ITHACAPOD.H"
#include "ITHACAstream.H"
#include "forces.H"
#include "steadyNS.H"
class tutorial03 : public steadyNS
{
public:
explicit tutorial03(int argc, char* argv[])
: steadyNS(argc, argv), U(_U()), p(_p()), args(_args()) {}
volVectorField& U;
volScalarField& p;
argList& args;
void offlineSolve()
{
Vector<double> inl(0, 0, 0);
List<scalar> mu_now(1);
// if the offline solution is already performed read the fields
if (offline)
{
ITHACAstream::read_fields(Ufield, U, "./ITHACAoutput/Offline/");
ITHACAstream::read_fields(Pfield, p, "./ITHACAoutput/Offline/");
ITHACAstream::readMatrix("./ITHACAoutput/Offline/mu_samples_mat.txt");
}
else
{
Vector<double> Uinl(0, 0, 0);
for (label i = 0; i < mu.cols(); i++)
{
mu_now[0] = mu(0, i);
truthSolve(mu_now);
}
}
}
};
void offline_stage(tutorial03& example);
void online_stage(tutorial03& example);
int main(int argc, char* argv[])
{
#if OPENFOAM > 1812
// load stage to perform
argList::addOption("stage", "offline", "Perform offline stage");
argList::addOption("stage", "online", "Perform online stage");
// add options for parallel run
HashTable<string> validParOptions;
validParOptions.set
(
"stage",
"offline"
);
validParOptions.set
(
"stage",
"online"
);
Pstream::addValidParOptions(validParOptions);
// Construct the tutorial object
tutorial03 example(argc, argv);
if (example._args().get("stage").match("offline"))
{
// perform the offline stage, extracting the modes from the snapshots'
// dataset corresponding to parOffline
offline_stage(example);
}
else if (example._args().get("stage").match("online"))
{
// load precomputed modes and reduced matrices
offline_stage(example);
// perform online solve with respect to the parameters in parOnline
online_stage(example);
}
else
{
Info << "Pass '-stage offline', '-stage online'" << endl;
}
#else
if (argc == 1)
{
Info << "Pass 'offline' or 'online' as first arguments."
<< endl;
exit(0);
}
// process arguments removing "offline" or "online" keywords
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--;
// Construct the tutorial object
tutorial03 example(argc, argv);
if (std::strcmp(argv[1], "offline") == 0)
{
// perform the offline stage, extracting the modes from the snapshots' dataset corresponding to parOffline
offline_stage(example);
}
else if (std::strcmp(argv[1], "online") == 0)
{
// load precomputed modes and reduced matrices
offline_stage(example);
// perform online solve with respect to the parameters in parOnline
online_stage(example);
}
else
{
Info << "Pass offline, online" << endl;
}
#endif
exit(0);
}
void offline_stage(tutorial03& example)
{
// Read some parameters from file
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);
// Read the par file where the training parameters are stored
word filename("./parOffline");
example.mu = ITHACAstream::readMatrix(filename);
// Set the inlet boundaries patch 0 directions x and y
example.inletIndex.resize(1, 2);
example.inletIndex(0, 0) = 0;
example.inletIndex(0, 1) = 0;
// Perform the offline solve
example.offlineSolve();
// Solve the supremizer problem
example.solvesupremizer();
if (example.bcMethod == "lift")
{
ITHACAstream::read_fields(example.liftfield, example._U(), "./lift/");
// Homogenize the snapshots
example.computeLift(example.Ufield, example.liftfield, example.Uomfield);
// Perform POD on the velocity snapshots
ITHACAPOD::getModes(example.Uomfield, example.Umodes, example._U().name(),
example.podex, 0, 0, NmodesUout);
}
else
{
ITHACAPOD::getModes(example.Ufield, example.Umodes, example._U().name(),
example.podex, 0, 0, NmodesUout);
}
// Perform POD on velocity pressure and supremizers and store the first 10
// modes
ITHACAPOD::getModes(example.Pfield, example.Pmodes, example._p().name(),
example.podex, 0, 0, NmodesPout);
ITHACAPOD::getModes(example.supfield, example.supmodes, example._U().name(),
example.podex, example.supex, 1, NmodesSUPout);
// Perform the Galerkin Projection
example.projectSUP("./Matrices", NmodesUproj, NmodesPproj, NmodesSUPproj);
}
void online_stage(tutorial03& example)
{
// Create the reduced object
reducedSteadyNS reduced(example);
// Read the par file where the test parameters are stored
word filename("./parOnline");
example.mu = ITHACAstream::readMatrix(filename);
// Set the inlet velocity
Eigen::MatrixXd vel_now(1, 1);
vel_now(0, 0) = 1;
// used only for penalty approach
reduced.tauU = Eigen::MatrixXd::Zero(1, 1);
reduced.tauU(0, 0) = 1e-1;
// Perform an online solve for the new values of inlet velocities
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;
// Set the reduced viscosity
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);
}
// Save the online solution
ITHACAstream::exportMatrix(reduced.online_solution, "red_coeff", "python",
"./ITHACAoutput/red_coeff");
ITHACAstream::exportMatrix(reduced.online_solution, "red_coeff", "matlab",
"./ITHACAoutput/red_coeff");
ITHACAstream::exportMatrix(reduced.online_solution, "red_coeff", "eigen",
"./ITHACAoutput/red_coeff");
// Reconstruct and export the solution
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 ...