Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2552c43
Adds ProblemOperatorBase class; ProblemOperatorInterface now only con…
May 20, 2024
1b93191
Removes unused equation system operator handle from ProblemOperatorBase.
May 20, 2024
803284f
Adds Width and Height getter/setter to ProblemOperatorInterface; Remo…
May 20, 2024
21e5c75
Removes ProblemOperatorInterface; now using base class ProblemOperato…
May 20, 2024
3562141
Added comments to ProblemOperatorBase methods.
May 20, 2024
19f10a4
Deleted default ProblemOperatorBase constructor and made constructor …
May 20, 2024
0bffc69
Made UpdateOffsetsWithSize non-virtual.
May 20, 2024
8d57a18
Removed UpdateOffsetsWithSize; added GetSolutionVectorSize and GetTri…
May 20, 2024
c76733b
UpdateOffsets and UpdateBlockVector are now private methods; no longe…
May 20, 2024
b890840
Jacobian solver is now stored inside ProblemOperatorBase.
May 20, 2024
9c6e1fb
Moves the Jacobian preconditioner into ProblemOperatorBase.
May 20, 2024
db4e8c6
Moved the nonlinear solver into ProblemOperatorBase.
May 20, 2024
661adaa
Switched to unique pointers for jacobian solvers; Added proper setters.
May 20, 2024
af947c9
Added accessor for JacobianPreconditioner; added documentation.
May 20, 2024
c1e60ea
Moved ODE solver into TimeDomainProblemOperator.
May 22, 2024
63d0c6a
Block vector is now stored in ProblemOperatorBase; Added wrapper Ste…
May 22, 2024
9990315
Removed ODE solver accessor from TimeDomainProblemOperator.
May 22, 2024
58814f8
Removes ConstructJacobianPreconditioner method; moves preconditioner …
May 22, 2024
91275f4
Removed ConstructJacobianSolverWithOptions. All derived ProblemBuilde…
May 22, 2024
ace7f88
Revert "Removed ConstructJacobianSolverWithOptions. All derived Probl…
May 22, 2024
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
2 changes: 1 addition & 1 deletion src/executioners/steady_executioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SteadyExecutioner::Solve() const
{
// Advance time step.
_problem->_preprocessors.Solve();
_problem->GetOperator()->Solve(*(_problem->_f));
_problem->GetOperator()->Solve();
_problem->_postprocessors.Solve();

// Output data
Expand Down
2 changes: 1 addition & 1 deletion src/executioners/transient_executioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ TransientExecutioner::Step(double dt, int it) const

// Advance time step.
_problem->_preprocessors.Solve(_t);
_problem->_ode_solver->Step(*(_problem->_f), _t, dt);
_problem->GetOperator()->Step(_t, dt);
_problem->_postprocessors.Solve(_t);

// Output data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ ComplexMaxwellOperator::Solve(mfem::Vector & X)

auto * jac_z = jac.As<mfem::ComplexHypreParMatrix>()->GetSystemMatrix();

_problem._jacobian_solver->SetOperator(*jac_z);
_problem._jacobian_solver->Mult(rhs, u);
_jacobian_solver->SetOperator(*jac_z);
_jacobian_solver->Mult(rhs, u);
sqlf.RecoverFEMSolution(u, lf, *_u);

_problem._gridfunctions.GetRef(_trial_var_names.at(0)) = _u->real();
Expand Down
16 changes: 6 additions & 10 deletions src/formulations/Dual/dual_formulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,16 @@ DualFormulation::DualFormulation(std::string alpha_coef_name,
}

void
DualFormulation::ConstructJacobianPreconditioner()
DualFormulation::ConstructJacobianSolver()
{
auto precond =
std::make_shared<mfem::HypreAMS>(GetProblem()->GetEquationSystem()->_test_pfespaces.at(0));
std::make_unique<mfem::HypreAMS>(GetProblem()->GetEquationSystem()->_test_pfespaces.at(0));

precond->SetSingularProblem();
precond->SetPrintLevel(-1);

GetProblem()->_jacobian_preconditioner = precond;
}
GetProblem()->GetOperator()->SetJacobianPreconditioner(std::move(precond));

void
DualFormulation::ConstructJacobianSolver()
{
ConstructJacobianSolverWithOptions(SolverType::HYPRE_PCG, {._max_iteration = 1000});
}

Expand Down Expand Up @@ -238,12 +234,12 @@ DualOperator::ImplicitSolve(const double dt, const mfem::Vector & X, mfem::Vecto
logger.info("{} ImplicitSolve: {} seconds", typeid(this).name(), sw);
}

void
DualOperator::UpdateOffsets()
int
DualOperator::GetSolutionVectorSize() const
{
// Blocks for solution vector are smaller than the operator size for DualOperator,
// as curl is stored separately. Block operator only has the HCurl TrueVSize;
return UpdateOffsetsWithSize(_trial_variables.size() - 1);
return static_cast<int>(GetTrialVariablesSize() - 1);
}

} // namespace hephaestus
4 changes: 1 addition & 3 deletions src/formulations/Dual/dual_formulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ class DualFormulation : public TimeDomainEMFormulation

~DualFormulation() override = default;

void ConstructJacobianPreconditioner() override;

void ConstructJacobianSolver() override;

void ConstructOperator() override;
Expand Down Expand Up @@ -74,7 +72,7 @@ class DualOperator : public TimeDomainEquationSystemProblemOperator
mfem::ParGridFunction * _dv{nullptr}; // HDiv vector field

protected:
void UpdateOffsets() override;
int GetSolutionVectorSize() const override;

std::unique_ptr<mfem::ParDiscreteLinearOperator> _curl;
};
Expand Down
10 changes: 3 additions & 7 deletions src/formulations/HCurl/hcurl_formulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,16 @@ HCurlFormulation::ConstructOperator()
}

void
HCurlFormulation::ConstructJacobianPreconditioner()
HCurlFormulation::ConstructJacobianSolver()
{
auto precond =
std::make_shared<mfem::HypreAMS>(GetProblem()->GetEquationSystem()->_test_pfespaces.at(0));
std::make_unique<mfem::HypreAMS>(GetProblem()->GetEquationSystem()->_test_pfespaces.at(0));

precond->SetSingularProblem();
precond->SetPrintLevel(-1);

GetProblem()->_jacobian_preconditioner = precond;
}
GetProblem()->GetOperator()->SetJacobianPreconditioner(std::move(precond));

void
HCurlFormulation::ConstructJacobianSolver()
{
ConstructJacobianSolverWithOptions(SolverType::HYPRE_PCG);
}

Expand Down
2 changes: 0 additions & 2 deletions src/formulations/HCurl/hcurl_formulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class HCurlFormulation : public TimeDomainEMFormulation

void ConstructOperator() override;

void ConstructJacobianPreconditioner() override;

void ConstructJacobianSolver() override;

void RegisterGridFunctions() override;
Expand Down
16 changes: 6 additions & 10 deletions src/formulations/Magnetostatic/statics_formulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,16 @@ StaticsFormulation::StaticsFormulation(std::string alpha_coef_name, std::string
}

void
StaticsFormulation::ConstructJacobianPreconditioner()
StaticsFormulation::ConstructJacobianSolver()
{
std::shared_ptr<mfem::HypreAMS> precond{std::make_shared<mfem::HypreAMS>(
GetProblem()->_gridfunctions.Get(_h_curl_var_name)->ParFESpace())};
auto precond = std::make_unique<mfem::HypreAMS>(
GetProblem()->_gridfunctions.Get(_h_curl_var_name)->ParFESpace());

precond->SetSingularProblem();
precond->SetPrintLevel(-1);

GetProblem()->_jacobian_preconditioner = precond;
}
GetProblem()->GetOperator()->SetJacobianPreconditioner(std::move(precond));

void
StaticsFormulation::ConstructJacobianSolver()
{
ConstructJacobianSolverWithOptions(SolverType::HYPRE_FGMRES,
{._max_iteration = 100, ._k_dim = 10});
}
Expand Down Expand Up @@ -152,8 +148,8 @@ StaticsOperator::Solve(mfem::Vector & X)

// Define and apply a parallel FGMRES solver for AX=B with the AMS
// preconditioner from hypre.
_problem._jacobian_solver->SetOperator(curl_mu_inv_curl);
_problem._jacobian_solver->Mult(rhs_tdofs, sol_tdofs);
_jacobian_solver->SetOperator(curl_mu_inv_curl);
_jacobian_solver->Mult(rhs_tdofs, sol_tdofs);
blf.RecoverFEMSolution(sol_tdofs, lf, gf);

logger.info("{} Solve: {} seconds", typeid(this).name(), sw);
Expand Down
2 changes: 0 additions & 2 deletions src/formulations/Magnetostatic/statics_formulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class StaticsFormulation : public SteadyStateEMFormulation

~StaticsFormulation() override = default;

void ConstructJacobianPreconditioner() override;

void ConstructJacobianSolver() override;

void ConstructOperator() override;
Expand Down
61 changes: 20 additions & 41 deletions src/problem_builders/problem_builder_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@
namespace hephaestus
{

Problem::~Problem()
{
// Ensure that all owned memory is properly freed!
_f.reset();
_ode_solver.reset();
}

void
Problem::Update()
{
Expand Down Expand Up @@ -97,15 +90,15 @@ ProblemBuilder::SetSolverOptions(hephaestus::InputParameters & solver_options)
}

void
ProblemBuilder::SetJacobianPreconditioner(std::shared_ptr<mfem::Solver> preconditioner)
ProblemBuilder::SetJacobianPreconditioner(std::unique_ptr<mfem::Solver> preconditioner)
{
GetProblem()->_jacobian_preconditioner = preconditioner;
GetProblem()->GetOperator()->SetJacobianPreconditioner(std::move(preconditioner));
}

void
ProblemBuilder::SetJacobianSolver(std::shared_ptr<mfem::Solver> jacobian_solver)
ProblemBuilder::SetJacobianSolver(std::unique_ptr<mfem::Solver> jacobian_solver)
{
GetProblem()->_jacobian_solver = jacobian_solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(jacobian_solver));
}

void
Expand Down Expand Up @@ -223,26 +216,16 @@ ProblemBuilder::AddSource(std::string source_name, std::shared_ptr<hephaestus::S
}

void
ProblemBuilder::ConstructJacobianPreconditioner()
ProblemBuilder::ConstructJacobianSolver()
{
auto precond = std::make_shared<mfem::HypreBoomerAMG>();
auto precond = std::make_unique<mfem::HypreBoomerAMG>();
precond->SetPrintLevel(GetGlobalPrintLevel());

GetProblem()->_jacobian_preconditioner = precond;
}
GetProblem()->GetOperator()->SetJacobianPreconditioner(std::move(precond));

void
ProblemBuilder::ConstructJacobianSolver()
{
ConstructJacobianSolverWithOptions(SolverType::HYPRE_GMRES);
}

void
ProblemBuilder::ConstructBlockVector()
{
GetProblem()->_f = std::make_unique<mfem::BlockVector>();
}

void
ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams default_params)
{
Expand All @@ -258,14 +241,13 @@ ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams
solver_options.GetOptionalParam<int>("PrintLevel", default_params._print_level);
const auto k_dim = solver_options.GetOptionalParam<unsigned int>("KDim", default_params._k_dim);

auto preconditioner =
std::dynamic_pointer_cast<mfem::HypreSolver>(GetProblem()->_jacobian_preconditioner);
auto preconditioner = GetProblem()->GetOperator()->JacobianPreconditioner<mfem::HypreSolver>();

switch (type)
{
case SolverType::HYPRE_PCG:
{
auto solver = std::make_shared<mfem::HyprePCG>(GetProblem()->_comm);
auto solver = std::make_unique<mfem::HyprePCG>(GetProblem()->_comm);

solver->SetTol(tolerance);
solver->SetAbsTol(abs_tolerance);
Expand All @@ -275,12 +257,12 @@ ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams
if (preconditioner)
solver->SetPreconditioner(*preconditioner);

GetProblem()->_jacobian_solver = solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(solver));
break;
}
case SolverType::HYPRE_GMRES:
{
auto solver = std::make_shared<mfem::HypreGMRES>(GetProblem()->_comm);
auto solver = std::make_unique<mfem::HypreGMRES>(GetProblem()->_comm);

solver->SetTol(tolerance);
solver->SetAbsTol(abs_tolerance);
Expand All @@ -291,12 +273,12 @@ ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams
if (preconditioner)
solver->SetPreconditioner(*preconditioner);

GetProblem()->_jacobian_solver = solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(solver));
break;
}
case SolverType::HYPRE_FGMRES:
{
auto solver = std::make_shared<mfem::HypreFGMRES>(GetProblem()->_comm);
auto solver = std::make_unique<mfem::HypreFGMRES>(GetProblem()->_comm);

solver->SetTol(tolerance);
solver->SetMaxIter(max_iter);
Expand All @@ -306,25 +288,25 @@ ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams
if (preconditioner)
solver->SetPreconditioner(*preconditioner);

GetProblem()->_jacobian_solver = solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(solver));
break;
}
case SolverType::HYPRE_AMG:
{
auto solver = std::make_shared<mfem::HypreBoomerAMG>();
auto solver = std::make_unique<mfem::HypreBoomerAMG>();

solver->SetTol(tolerance);
solver->SetMaxIter(max_iter);
solver->SetPrintLevel(print_level);

GetProblem()->_jacobian_solver = solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(solver));
break;
}
case SolverType::SUPER_LU:
{
auto solver = std::make_shared<hephaestus::SuperLUSolver>(GetProblem()->_comm);
auto solver = std::make_unique<hephaestus::SuperLUSolver>(GetProblem()->_comm);

GetProblem()->_jacobian_solver = solver;
GetProblem()->GetOperator()->SetJacobianSolver(std::move(solver));
break;
}
default:
Expand All @@ -338,14 +320,14 @@ ProblemBuilder::ConstructJacobianSolverWithOptions(SolverType type, SolverParams
void
ProblemBuilder::ConstructNonlinearSolver()
{
auto nl_solver = std::make_shared<mfem::NewtonSolver>(GetProblem()->_comm);
auto nl_solver = std::make_unique<mfem::NewtonSolver>(GetProblem()->_comm);

// Defaults to one iteration, without further nonlinear iterations
nl_solver->SetRelTol(0.0);
nl_solver->SetAbsTol(0.0);
nl_solver->SetMaxIter(1);

GetProblem()->_nonlinear_solver = nl_solver;
GetProblem()->GetOperator()->SetNonlinearSolver(std::move(nl_solver));
}

void
Expand Down Expand Up @@ -390,13 +372,10 @@ ProblemBuilder::FinalizeProblem(bool build_operator)
ConstructOperator();
}

ConstructBlockVector();

InitializeAuxSolvers();
InitializeSources();
InitializeOperator();

ConstructJacobianPreconditioner();
ConstructJacobianSolver();
ConstructNonlinearSolver();

Expand Down
19 changes: 5 additions & 14 deletions src/problem_builders/problem_builder_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ namespace hephaestus
{

/// Forwards declaration.
class ProblemOperatorInterface;
class ProblemOperatorBase;

/// Base problem class.
class Problem
{
public:
Problem() = default;
virtual ~Problem();
virtual ~Problem() = default;

std::shared_ptr<mfem::ParMesh> _pmesh{nullptr};
hephaestus::BCMap _bc_map;
Expand All @@ -30,13 +30,6 @@ class Problem
hephaestus::Outputs _outputs;
hephaestus::InputParameters _solver_options;

std::unique_ptr<mfem::ODESolver> _ode_solver{nullptr};
std::unique_ptr<mfem::BlockVector> _f{nullptr};

std::shared_ptr<mfem::Solver> _jacobian_preconditioner{nullptr};
std::shared_ptr<mfem::Solver> _jacobian_solver{nullptr};
std::shared_ptr<mfem::NewtonSolver> _nonlinear_solver{nullptr};

hephaestus::FECollections _fecs;
hephaestus::FESpaces _fespaces;
hephaestus::GridFunctions _gridfunctions;
Expand All @@ -46,7 +39,7 @@ class Problem
int _num_procs;

/// Returns a pointer to the operator. See derived classes.
[[nodiscard]] virtual hephaestus::ProblemOperatorInterface * GetOperator() const = 0;
[[nodiscard]] virtual hephaestus::ProblemOperatorBase * GetOperator() const = 0;

/// Virtual method to construct the operator. Call for default problems.
virtual void ConstructOperator() = 0;
Expand Down Expand Up @@ -80,8 +73,8 @@ class ProblemBuilder
void SetSources(hephaestus::Sources & sources);
void SetOutputs(hephaestus::Outputs & outputs);
void SetSolverOptions(hephaestus::InputParameters & solver_options);
void SetJacobianPreconditioner(std::shared_ptr<mfem::Solver> preconditioner);
void SetJacobianSolver(std::shared_ptr<mfem::Solver> solver);
void SetJacobianPreconditioner(std::unique_ptr<mfem::Solver> preconditioner);
void SetJacobianSolver(std::unique_ptr<mfem::Solver> solver);
void SetCoefficients(hephaestus::Coefficients & coefficients);

void AddFESpace(std::string fespace_name,
Expand All @@ -100,10 +93,8 @@ class ProblemBuilder
virtual void RegisterAuxSolvers() = 0;
virtual void RegisterCoefficients() = 0;

virtual void ConstructJacobianPreconditioner();
virtual void ConstructJacobianSolver();
virtual void ConstructNonlinearSolver();
virtual void ConstructBlockVector();

virtual void ConstructOperator() = 0;
virtual void ConstructTimestepper() = 0;
Expand Down
Loading