19#include "libmesh/dof_map.h"
20#include "libmesh/fuzzy_equals.h"
21#include "libmesh/petsc_matrix.h"
22#include "libmesh/petsc_vector.h"
31 "Name of the nonlinear system representing the forward problem. Multiple and linear solver "
32 "systems are not currently supported.");
34 "adjoint_system",
"Name of the system representing the adjoint problem.");
41 _problem.nlSysNum(getParam<
std::vector<SolverSystemName>>(
"forward_system")[0])),
42 _adjoint_sys_num(_problem.nlSysNum(getParam<NonlinearSystemName>(
"adjoint_system"))),
43 _nl_forward(_problem.getNonlinearSystemBase(_forward_sys_num)),
44 _nl_adjoint(_problem.getNonlinearSystemBase(_adjoint_sys_num))
47 if (
getParam<std::vector<SolverSystemName>>(
"forward_system").size() != 1)
49 "Multiple nonlinear forward systems is not supported at the moment");
53 paramError(
"forward_system",
"Forward system does not appear to be a 'NonlinearSystem'.");
55 paramError(
"adjoint_system",
"Adjoint system does not appear to be a 'NonlinearSystem'.");
67 "We should have forward and adjoint systems as evidenced by our initialization list");
80 TIME_SECTION(
"execute", 1,
"Executing adjoint problem",
false);
83 "I don't see any code path in which this class winds up with an inner solve");
94 _console <<
"MultiApps failed to converge on ADJOINT_TIMESTEP_BEGIN!" << std::endl;
104 auto & matrix = cast_ref<ImplicitSystem &>(
_nl_forward.
system()).get_system_matrix();
110 const auto maxits = es.parameters.get<
unsigned int>(
"linear solver maximum iterations");
112 auto & solver = *cast_ref<ImplicitSystem &>(
_nl_adjoint.
system()).get_linear_solver();
120 solver.adjoint_solve(matrix, solution, rhs,
tol, maxits);
131 if (solver.get_converged_reason() < 0)
133 _console <<
"Adjoint solve failed to converge with reason: "
134 << Utility::enum_to_string(solver.get_converged_reason()) << std::endl;
141 _console <<
"MultiApps failed to converge on ADJOINT_TIMESTEP_END!" << std::endl;
150 const NumericVector<Number> & ,
151 NumericVector<Number> & rhs)
164 const NumericVector<Number> & solution,
165 NumericVector<Number> & rhs)
167 std::vector<dof_id_type> nbc_dofs;
169 if (nbc_warehouse.hasActiveObjects())
174 Node * node = bnode->_node;
176 if (!nbc_warehouse.hasActiveBoundaryObjects(boundary_id) ||
180 for (
const auto & bc : nbc_warehouse.getActiveBoundaryObjects(boundary_id))
181 if (bc->shouldApply())
182 for (
unsigned int c = 0;
c < bc->variable().count(); ++
c)
183 nbc_dofs.push_back(node->dof_number(
_forward_sys_num, bc->variable().number() +
c, 0));
187 auto petsc_matrix =
dynamic_cast<PetscMatrix<Number> *
>(&matrix);
188 auto petsc_solution =
dynamic_cast<const PetscVector<Number> *
>(&solution);
189 auto petsc_rhs =
dynamic_cast<PetscVector<Number> *
>(&rhs);
190 if (petsc_matrix && petsc_solution && petsc_rhs)
191 LibmeshPetscCall(MatZeroRowsColumns(petsc_matrix->mat(),
192 cast_int<PetscInt>(nbc_dofs.size()),
195 petsc_solution->vec(),
198 mooseError(
"Using PETSc matrices and vectors is required for applying homogenized boundary "
207 for (
const auto & adj_var : adj_vars)
212 "User cannot supply scaling factors for adjoint variables. Adjoint system is scaled "
213 "automatically by the forward system.");
223 "The forward and adjoint systems do not seem to be the same size. This could be due to (1) "
224 "the number of variables added to each system is not the same, (2) variables do not have "
225 "consistent family/order, (3) variables do not have the same block restriction.");
boundary_id_type BoundaryID
void applyNodalBCs(SparseMatrix< Number > &matrix, const NumericVector< Number > &solution, NumericVector< Number > &rhs)
Helper function for applying nodal BCs to the adjoint matrix and RHS.
virtual bool solve() override
Solve the adjoint system with the following procedure:
const unsigned int _forward_sys_num
The number of the nonlinear system representing the forward model.
NonlinearSystemBase & _nl_forward
The nonlinear system representing the forward model.
const unsigned int _adjoint_sys_num
The number of the nonlinear system representing the adjoint model.
AdjointSolve(Executioner &ex)
virtual void assembleAdjointSystem(SparseMatrix< Number > &matrix, const NumericVector< Number > &solution, NumericVector< Number > &rhs)
Assembles adjoint system.
NonlinearSystemBase & _nl_adjoint
The nonlinear system representing the adjoint model.
void checkIntegrity()
Checks whether the forward and adjoint systems are consistent.
static InputParameters validParams()
const ConsoleStream _console
virtual void computeJacobian(const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, const unsigned int nl_sys_num)
virtual libMesh::EquationSystems & es() override
virtual std::size_t numSolverSystems() const override
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
SolverParams & solverParams(unsigned int solver_sys_num=0)
bool execMultiApps(ExecFlagType type, bool auto_advance=true)
virtual void computeResidualTag(const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, TagID tag)
virtual void execute(const ExecFlagType &exec_type)
Moose::PetscSupport::PetscOptions & getPetscOptions()
virtual void outputStep(ExecFlagType type)
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
NumericVector< Number > & getResidualNonTimeVector()
const MooseObjectTagWarehouse< NodalBCBase > & getNodalBCWarehouse() const
TagID nonTimeVectorTag() const override
virtual libMesh::System & system() override
SolveObject * _inner_solve
virtual const NumericVector< Number > *const & currentSolution() const override final
bool automaticScaling() const
std::string prefix() const
bool hasVector(const std::string &tag_name) const
unsigned int number() const
void removeVector(const std::string &name)
virtual NumericVector< Number > & getVector(const std::string &name)
const std::vector< MooseVariableFieldBase * > & getVariables(THREAD_ID tid)
NumericVector< Number > & solution()
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
processor_id_type processor_id() const
const T & get(std::string_view) const
dof_id_type n_dofs() const
const DofMap & get_dof_map() const
void petscSetOptions(const PetscOptions &po, const SolverParams &solver_params, FEProblemBase *const problem=nullptr)
void setConvergedReasonFlags(FEProblemBase &fe_problem, std::string prefix)
void storePetscOptions(FEProblemBase &fe_problem, const std::string &prefix, const ParallelParamObject ¶m_object)
const ExecFlagType EXEC_ADJOINT_TIMESTEP_END
const ExecFlagType EXEC_ADJOINT_TIMESTEP_BEGIN
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
PetscInt * numeric_petsc_cast(const numeric_index_type *p)