Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EQP ROM workflow for unsteady NS #50

Merged
merged 9 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/multiblock_solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ friend class ParameterizedProblem;
void ComputeSubdomainErrorAndNorm(GridFunction *fom_sol, GridFunction *rom_sol, double &error, double &norm);
void ComputeRelativeError(Array<GridFunction *> fom_sols, Array<GridFunction *> rom_sols, Vector &error);
void CompareSolution(BlockVector &test_U, Vector &error);

protected:
virtual void AssembleROMMat(BlockMatrix &romMat);
};

#endif
2 changes: 2 additions & 0 deletions include/rom_element_collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class ROMLinearElement : public ROMElementCollection
Array<Array<MatrixBlocks *> *> bdr;
Array<MatrixBlocks *> port; // reference ports.

Array<MatrixBlocks *> mass; // Size(num_components);

public:
ROMLinearElement(TopologyHandler *topol_handler_,
const Array<FiniteElementSpace *> &fes_,
Expand Down
48 changes: 29 additions & 19 deletions include/rom_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ enum NonlinearHandling
NUM_NLNHNDL
};

enum class ROMOrderBy
{
VARIABLE,
DOMAIN
};

const BasisTag GetBasisTagForComponent(const int &comp_idx, const TopologyHandler *topol_handler, const std::string var_name="");
const BasisTag GetBasisTag(const int &subdomain_index, const TopologyHandler *topol_handler, const std::string var_name="");

Expand Down Expand Up @@ -90,16 +96,11 @@ class ROMHandlerBase
/*
offset for the global domain ROM blocks.
For i-th subdomain and j-th variable,
index = i * num_var + j
ROMOrderBy::DOMAIN: index = i * num_var + j
ROMOrderBy::VARIABLE: index = j * numSub + i
*/
Array<int> num_basis;
Array<int> rom_block_offsets;
/*
the global domain ROM blocks with index order switched.
For i-th subdomain and j-th variable,
index = j * num_var + i
*/
Array<int> rom_varblock_offsets;

CAROM::Options* rom_options;
CAROM::BasisGenerator *basis_generator;
Expand All @@ -109,6 +110,11 @@ class ROMHandlerBase
bool update_right_SV = false;
bool incremental = false;

ROMOrderBy ordering = ROMOrderBy::DOMAIN;

mfem::BlockVector *reduced_rhs = NULL;
mfem::BlockVector *reduced_sol = NULL;

void ParseInputs();
public:
ROMHandlerBase(TopologyHandler *input_topol, const Array<int> &input_var_offsets,
Expand All @@ -129,7 +135,6 @@ class ROMHandlerBase
const std::string GetBasisPrefix() { return basis_prefix; }
const BasisTag GetRefBasisTag(const int ref_idx) { return basis_tags[ref_idx]; }
const Array<int>* GetBlockOffsets() { return &rom_block_offsets; }
const Array<int>* GetVarBlockOffsets() { return &rom_varblock_offsets; }
virtual SparseMatrix* GetOperator() = 0;
const bool GetNonlinearMode() { return nonlinear_mode; }
void SetNonlinearMode(const bool nl_mode)
Expand All @@ -139,6 +144,12 @@ class ROMHandlerBase
nonlinear_mode = nl_mode;
}
const NonlinearHandling GetNonlinearHandling() { return nlin_handle; }
const ROMOrderBy GetOrdering() { return ordering; }
const int GetBlockIndex(const int m, const int v=-1);
void GetDomainAndVariableIndex(const int &rom_block_index, int &m, int &v);

mfem::BlockVector* GetReducedSolution() { return reduced_sol; }
mfem::BlockVector* GetReducedRHS() { return reduced_rhs; }

/* parse inputs for supremizer. only for Stokes/SteadyNS Solver. */
void ParseSupremizerInput(Array<int> &num_ref_supreme, Array<int> &num_supreme);
Expand All @@ -157,9 +168,9 @@ class ROMHandlerBase
virtual void ProjectToDomainBasis(const Array<int> &idx_i, const Array<int> &idx_j, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;

virtual void ProjectComponentToRefBasis(const int &c, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectComponentToDomainBasis(const int &c, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectComponentToDomainBasis(const int &m, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectInterfaceToRefBasis(const int &c1, const int &c2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectInterfaceToDomainBasis(const int &c1, const int &c2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectInterfaceToDomainBasis(const int &m1, const int &m2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectVariableToDomainBasis(const int &vi, const int &vj, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectGlobalToDomainBasis(const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats) = 0;
virtual void ProjectOperatorOnReducedBasis(const Array2D<Operator*> &mats) = 0;
Expand All @@ -173,12 +184,13 @@ class ROMHandlerBase
virtual void LiftUpFromDomainBasis(const int &i, const Vector &rom_vec, Vector &vec) = 0;
virtual void LiftUpGlobal(const BlockVector &rom_vec, BlockVector &vec) = 0;

virtual void Solve(BlockVector &rhs, BlockVector &sol) = 0;
virtual void Solve(BlockVector* U) = 0;
virtual void NonlinearSolve(Operator &oper, BlockVector* U, Solver *prec=NULL) = 0;

virtual void SaveOperator(const std::string filename) = 0;
virtual void LoadOperatorFromFile(const std::string filename) = 0;
virtual void SetRomMat(BlockMatrix *input_mat) = 0;
virtual void SetRomMat(BlockMatrix *input_mat, const bool init_direct_solver=true) = 0;
virtual void SaveRomSystem(const std::string &input_prefix, const std::string type="mm") = 0;

virtual void SaveBasisVisualization(const Array<FiniteElementSpace *> &fes, const std::vector<std::string> &var_names) = 0;
Expand Down Expand Up @@ -217,9 +229,6 @@ class MFEMROMHandler : public ROMHandlerBase
HYPRE_BigInt sys_row_starts[2];
HypreParMatrix *romMat_hypre = NULL;
MUMPSSolver *mumps = NULL;

mfem::BlockVector *reduced_rhs = NULL;
mfem::BlockVector *reduced_sol = NULL;

public:
MFEMROMHandler(TopologyHandler *input_topol, const Array<int> &input_var_offsets,
Expand All @@ -241,9 +250,9 @@ class MFEMROMHandler : public ROMHandlerBase
virtual void ProjectToDomainBasis(const Array<int> &idx_i, const Array<int> &idx_j, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);

virtual void ProjectComponentToRefBasis(const int &c, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectComponentToDomainBasis(const int &c, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectComponentToDomainBasis(const int &m, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectInterfaceToRefBasis(const int &c1, const int &c2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectInterfaceToDomainBasis(const int &c1, const int &c2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectInterfaceToDomainBasis(const int &m1, const int &m2, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectVariableToDomainBasis(const int &vi, const int &vj, const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectGlobalToDomainBasis(const Array2D<Operator*> &mats, Array2D<SparseMatrix *> &rom_mats);
virtual void ProjectOperatorOnReducedBasis(const Array2D<Operator*> &mats);
Expand All @@ -258,12 +267,13 @@ class MFEMROMHandler : public ROMHandlerBase
virtual void LiftUpFromDomainBasis(const int &i, const Vector &rom_vec, Vector &vec);
virtual void LiftUpGlobal(const BlockVector &rom_vec, BlockVector &vec);

virtual void Solve(BlockVector* U);
virtual void NonlinearSolve(Operator &oper, BlockVector* U, Solver *prec=NULL) override;
void Solve(BlockVector &rhs, BlockVector &sol) override;
void Solve(BlockVector* U) override;
void NonlinearSolve(Operator &oper, BlockVector* U, Solver *prec=NULL) override;

virtual void SaveOperator(const std::string input_prefix="");
virtual void LoadOperatorFromFile(const std::string input_prefix="");
virtual void SetRomMat(BlockMatrix *input_mat);
virtual void SetRomMat(BlockMatrix *input_mat, const bool init_direct_solver=true);
virtual void SaveRomSystem(const std::string &input_prefix, const std::string type="mm");

virtual void SaveBasisVisualization(const Array<FiniteElementSpace *> &fes, const std::vector<std::string> &var_names);
Expand Down
14 changes: 8 additions & 6 deletions include/steady_ns_solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ class SteadyNSROM : public Operator
const int num_var = 2;
int numSub = -1;

/* block offsets of velocity */
Array<int> block_offsets;
/* block index of velocity on FOM variable */
Array<int> midxs;
Array<Array<int> *> block_idxs;
SparseMatrix *linearOp = NULL;

Expand All @@ -71,7 +74,7 @@ class SteadyNSROM : public Operator
HYPRE_BigInt sys_glob_size;
mutable HYPRE_BigInt sys_row_starts[2];
public:
SteadyNSROM(SparseMatrix *linearOp_, const int numSub_, const Array<int> &block_offsets_, const bool direct_solve_=true);
SteadyNSROM(const int numSub_, ROMHandlerBase *rom_handler, const bool direct_solve_=true);

virtual ~SteadyNSROM();

Expand All @@ -85,8 +88,8 @@ class SteadyNSTensorROM : public SteadyNSROM
Array<DenseTensor *> hs; // not owned by SteadyNSTensorROM.

public:
SteadyNSTensorROM(SparseMatrix *linearOp_, Array<DenseTensor *> &hs_, const Array<int> &block_offsets_, const bool direct_solve_=true)
: SteadyNSROM(linearOp_, hs_.Size(), block_offsets_, direct_solve_), hs(hs_) {}
SteadyNSTensorROM(ROMHandlerBase *rom_handler, Array<DenseTensor *> &hs_, const bool direct_solve_=true)
: SteadyNSROM(hs_.Size(), rom_handler, direct_solve_), hs(hs_) {}

virtual ~SteadyNSTensorROM() {}

Expand All @@ -101,13 +104,12 @@ class SteadyNSEQPROM : public SteadyNSROM
ROMInterfaceForm *itf = NULL; // not owned by SteadyNSEQPROM.

Array<int> u_offsets;
Array<int> u_idxs;

mutable Vector x_u, y_u;

public:
SteadyNSEQPROM(SparseMatrix *linearOp_, Array<ROMNonlinearForm *> &hs_, ROMInterfaceForm *itf_,
const Array<int> &block_offsets_, const bool direct_solve_=true);
SteadyNSEQPROM(ROMHandlerBase *rom_handler, Array<ROMNonlinearForm *> &hs_,
ROMInterfaceForm *itf_, const bool direct_solve_=true);

virtual ~SteadyNSEQPROM() {}

Expand Down
28 changes: 18 additions & 10 deletions include/unsteady_ns_solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ friend class SteadyNSOperator;

BlockOperator *Hop = NULL;

/* function coefficients for initial condition */
VectorCoefficient *u_ic = NULL;
VectorCoefficient *p_ic = NULL;

/* mass matrix operator for ROM */
Array<int> rom_u_offsets;
BlockMatrix *rom_mass = NULL;

public:
UnsteadyNSSolver();

Expand All @@ -81,25 +89,23 @@ friend class SteadyNSOperator;

void SetParameterizedProblem(ParameterizedProblem *problem) override;

BlockVector* PrepareSnapshots(std::vector<BasisTag> &basis_tags) override;

void ProjectOperatorOnReducedBasis() override
{ mfem_error("UnsteadyNSSolver::ProjectOperatorOnReducedBasis is not implemented yet!\n"); }

void SolveROM() override
{ mfem_error("UnsteadyNSSolver::SolveROM is not implemented yet!\n"); }
void BuildCompROMLinElems() override;

void SolveROM() override;

void InitROMHandler() override;

void BuildROMTensorElems() override
{ mfem_error("UnsteadyNSSolver::BuildROMTensorElems is not implemented yet!\n"); }
void TrainROMEQPElems(SampleGenerator *sample_generator) override
{ mfem_error("UnsteadyNSSolver::TrainROMEQPElems is not implemented yet!\n"); }
void SaveROMNlinElems(const std::string &input_prefix) override
{ mfem_error("UnsteadyNSSolver::SaveROMNlinElems is not implemented yet!\n"); }
void LoadROMNlinElems(const std::string &input_prefix) override
{ mfem_error("UnsteadyNSSolver::LoadROMNlinElems is not implemented yet!\n"); }
void AssembleROMNlinOper() override
{ mfem_error("UnsteadyNSSolver::AssembleROMNlinOper is not implemented yet!\n"); }

private:
void InitializeTimeIntegration();
void SetupInitialCondition(int &initial_step, double &time);
void Step(double &time, int step);

void SanityCheck(const int step)
Expand All @@ -113,6 +119,8 @@ friend class SteadyNSOperator;
double ComputeCFL(const double dt);
void SetTime(const double time);

void AssembleROMMat(BlockMatrix &romMat) override;

};

#endif
4 changes: 3 additions & 1 deletion src/main_workflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,14 @@ void AuxiliaryTrainROM(MPI_Comm comm, SampleGenerator *sample_generator)
bool separate_variable_basis = config.GetOption<bool>("model_reduction/separate_variable_basis", false);

/* Supremizer enrichment */
if ((separate_variable_basis) && ((solver_type == "stokes") || (solver_type == "steady-ns")))
if ((separate_variable_basis) &&
((solver_type == "stokes") || (solver_type == "steady-ns") || (solver_type == "unsteady-ns")))
{
ParameterizedProblem *problem = InitParameterizedProblem();
StokesSolver *solver = NULL;
if (solver_type == "stokes") { solver = new StokesSolver; }
else if (solver_type == "steady-ns") { solver = new SteadyNSSolver; }
else if (solver_type == "unsteady-ns") { solver = new UnsteadyNSSolver; }

if (!solver->UseRom()) mfem_error("ROM must be enabled for supremizer enrichment!\n");

Expand Down
67 changes: 25 additions & 42 deletions src/multiblock_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,31 +272,33 @@ void MultiBlockSolver::BuildROMLinElems()

void MultiBlockSolver::AssembleROMMat()
{
assert(topol_mode == TopologyHandlerMode::COMPONENT);
assert(rom_elems);

const Array<int> *rom_block_offsets = rom_handler->GetBlockOffsets();
BlockMatrix *romMat = new BlockMatrix(*rom_block_offsets);
romMat->owns_blocks = true;

AssembleROMMat(*romMat);

romMat->Finalize();
rom_handler->SetRomMat(romMat);
}

void MultiBlockSolver::AssembleROMMat(BlockMatrix &romMat)
{
assert(topol_mode == TopologyHandlerMode::COMPONENT);
assert(rom_elems);

// component domain matrix.
for (int m = 0; m < numSub; m++)
{
int c_type = topol_handler->GetMeshType(m);
int num_block = 1;
int midx0 = m;
if (separate_variable_basis)
{
num_block *= num_var;
midx0 *= num_var;
}
int num_block = (separate_variable_basis) ? num_var : 1;

Array<int> midx(num_block);
for (int k = 0; k < num_block; k++)
midx[k] = midx0 + k;
for (int v = 0; v < num_block; v++)
midx[v] = rom_handler->GetBlockIndex(m, v);

MatrixBlocks *comp_mat = rom_elems->comp[c_type];
AddToBlockMatrix(midx, midx, *comp_mat, *romMat);
AddToBlockMatrix(midx, midx, *comp_mat, romMat);

// boundary matrices of each component.
Array<int> *bdr_c2g = topol_handler->GetBdrAttrComponentToGlobalMap(m);
Expand All @@ -312,7 +314,7 @@ void MultiBlockSolver::AssembleROMMat()
continue;

MatrixBlocks *bdr_mat = (*(rom_elems->bdr[c_type]))[b];
AddToBlockMatrix(midx, midx, *bdr_mat, *romMat);
AddToBlockMatrix(midx, midx, *bdr_mat, romMat);
} // for (int b = 0; b < bdr_c2g->Size(); b++)
} // for (int m = 0; m < numSub; m++)

Expand All @@ -325,38 +327,19 @@ void MultiBlockSolver::AssembleROMMat()

const int m1 = pInfo->Mesh1;
const int m2 = pInfo->Mesh2;
const int c1 = topol_handler->GetMeshType(m1);
const int c2 = topol_handler->GetMeshType(m2);

int num_block = 2;
int c1idx0 = c1, c2idx0 = c2;
int m1idx0 = m1, m2idx0 = m2;
if (separate_variable_basis)
{
num_block *= num_var;
c1idx0 *= num_var;
c2idx0 *= num_var;
m1idx0 *= num_var;
m2idx0 *= num_var;
}
int num_block = (separate_variable_basis) ? num_var : 1;

Array<int> midx(num_block), num_basis(num_block);
for (int k = 0, cidx = c1idx0, m = m1idx0; k < num_block/2; k++, cidx++, m++)
{
num_basis[k] = rom_handler->GetRefNumBasis(cidx);
midx[k] = m;
}
for (int k = num_block/2, cidx = c2idx0, m = m2idx0; k < num_block; k++, cidx++, m++)
{
num_basis[k] = rom_handler->GetRefNumBasis(cidx);
midx[k] = m;
}
Array<int> midx(0);

AddToBlockMatrix(midx, midx, *port_mat, *romMat);
}
for (int v = 0; v < num_block; v++)
midx.Append(rom_handler->GetBlockIndex(m1, v));

romMat->Finalize();
rom_handler->SetRomMat(romMat);
for (int v = 0; v < num_block; v++)
midx.Append(rom_handler->GetBlockIndex(m2, v));

AddToBlockMatrix(midx, midx, *port_mat, romMat);
}
}

void MultiBlockSolver::InitVisualization(const std::string& output_path)
Expand Down
Loading
Loading