Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
differentiable_solver.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include <memory>
16 #include <functional>
17 
18 namespace mfem {
19 class Solver;
20 class Vector;
21 class HypreParMatrix;
22 class BlockOperator;
23 } // namespace mfem
24 
25 namespace smith {
26 
27 class EquationSolver;
28 class BoundaryConditionManager;
29 class FiniteElementState;
30 class FiniteElementDual;
31 class Mesh;
32 struct NonlinearSolverOptions;
33 struct LinearSolverOptions;
34 
38  public:
40  virtual ~DifferentiableSolver() {}
41 
44  virtual void completeSetup(const smith::FiniteElementState& u) = 0;
45 
51  virtual std::shared_ptr<smith::FiniteElementState> solve(
52  const smith::FiniteElementState& u_guess, std::function<mfem::Vector(const smith::FiniteElementState&)> equation,
53  std::function<std::unique_ptr<mfem::HypreParMatrix>(const smith::FiniteElementState&)> jacobian) const = 0;
54 
59  virtual std::shared_ptr<smith::FiniteElementState> solveAdjoint(
60  const smith::FiniteElementDual& u_bar, std::unique_ptr<mfem::HypreParMatrix> jacobian_transposed) const = 0;
61 
63  virtual void clearMemory() const {}
64 };
65 
69  public:
71  LinearDifferentiableSolver(std::unique_ptr<mfem::Solver> s, std::unique_ptr<mfem::Solver> p);
72 
74  void completeSetup(const smith::FiniteElementState& u) override;
75 
77  std::shared_ptr<smith::FiniteElementState> solve(
78  const smith::FiniteElementState& u_guess, std::function<mfem::Vector(const smith::FiniteElementState&)> equation,
79  std::function<std::unique_ptr<mfem::HypreParMatrix>(const smith::FiniteElementState&)> jacobian) const override;
80 
82  std::shared_ptr<smith::FiniteElementState> solveAdjoint(
83  const smith::FiniteElementDual& u_bar, std::unique_ptr<mfem::HypreParMatrix> jacobian_transposed) const override;
84 
85  mutable std::unique_ptr<mfem::Solver> mfem_solver;
86  mutable std::unique_ptr<mfem::Solver> mfem_preconditioner;
87 };
88 
92  public:
94  NonlinearDifferentiableSolver(std::unique_ptr<EquationSolver> s);
95 
97  void completeSetup(const smith::FiniteElementState& u) override;
98 
100  std::shared_ptr<smith::FiniteElementState> solve(
101  const smith::FiniteElementState& u_guess, std::function<mfem::Vector(const smith::FiniteElementState&)> equation,
102  std::function<std::unique_ptr<mfem::HypreParMatrix>(const smith::FiniteElementState&)> jacobian) const override;
103 
105  std::shared_ptr<smith::FiniteElementState> solveAdjoint(
106  const smith::FiniteElementDual& u_bar, std::unique_ptr<mfem::HypreParMatrix> jacobian_transposed) const override;
107 
109  void clearMemory() const override;
110 
111  mutable std::unique_ptr<mfem::HypreParMatrix> J_;
112  mutable std::unique_ptr<EquationSolver>
114 };
115 
119  public:
122 
124  using FieldPtr = std::shared_ptr<FieldT>;
126  using DualPtr = std::shared_ptr<FieldD>;
127  using MatrixPtr = std::unique_ptr<mfem::HypreParMatrix>;
128 
131  virtual void completeSetup(const std::vector<FieldT>& us) = 0;
132 
139  virtual std::vector<FieldPtr> solve(
140  const std::vector<FieldPtr>& u_guesses,
141  std::function<std::vector<mfem::Vector>(const std::vector<FieldPtr>&)> residuals,
142  std::function<std::vector<std::vector<MatrixPtr>>(const std::vector<FieldPtr>&)> jacobians) const = 0;
143 
148  virtual std::vector<FieldPtr> solveAdjoint(const std::vector<DualPtr>& u_bars,
149  std::vector<std::vector<MatrixPtr>>& jacobian_transposed) const = 0;
150 
152  virtual void clearMemory() const {}
153 };
154 
158  public:
160  LinearDifferentiableBlockSolver(std::unique_ptr<mfem::Solver> s, std::unique_ptr<mfem::Solver> p);
161 
163  void completeSetup(const std::vector<FieldT>& us) override;
164 
166  std::vector<FieldPtr> solve(
167  const std::vector<FieldPtr>& u_guesses,
168  std::function<std::vector<mfem::Vector>(const std::vector<FieldPtr>&)> residuals,
169  std::function<std::vector<std::vector<MatrixPtr>>(const std::vector<FieldPtr>&)> jacobians) const override;
170 
172  std::vector<FieldPtr> solveAdjoint(const std::vector<DualPtr>& u_bars,
173  std::vector<std::vector<MatrixPtr>>& jacobian_transposed) const override;
174 
175  mutable std::unique_ptr<mfem::Solver> mfem_solver;
176  mutable std::unique_ptr<mfem::Solver> mfem_preconditioner;
177 };
178 
182  public:
184  NonlinearDifferentiableBlockSolver(std::unique_ptr<EquationSolver> s);
185 
187  void completeSetup(const std::vector<FieldT>& us) override;
188 
190  std::vector<FieldPtr> solve(
191  const std::vector<FieldPtr>& u_guesses,
192  std::function<std::vector<mfem::Vector>(const std::vector<FieldPtr>&)> residuals,
193  std::function<std::vector<std::vector<MatrixPtr>>(const std::vector<FieldPtr>&)> jacobians) const override;
194 
196  std::vector<FieldPtr> solveAdjoint(const std::vector<DualPtr>& u_bars,
197  std::vector<std::vector<MatrixPtr>>& jacobian_transposed) const override;
198 
199  mutable std::unique_ptr<mfem::BlockOperator>
201  mutable std::vector<std::vector<MatrixPtr>>
204 
205  mutable std::unique_ptr<EquationSolver>
207 };
208 
212 std::shared_ptr<LinearDifferentiableSolver> buildDifferentiableLinearSolver(LinearSolverOptions linear_opts,
213  const smith::Mesh& mesh);
214 
219 std::shared_ptr<NonlinearDifferentiableSolver> buildDifferentiableNonlinearSolver(NonlinearSolverOptions nonlinear_opts,
220  LinearSolverOptions linear_opts,
221  const smith::Mesh& mesh);
222 
227 std::shared_ptr<NonlinearDifferentiableBlockSolver> buildDifferentiableNonlinearBlockSolver(
228  NonlinearSolverOptions nonlinear_opts, LinearSolverOptions linear_opts, const smith::Mesh& mesh);
229 
230 } // namespace smith
Abstract interface to DifferentiableBlockSolver interface. Each differentiable block solve should pro...
virtual std::vector< FieldPtr > solveAdjoint(const std::vector< DualPtr > &u_bars, std::vector< std::vector< MatrixPtr >> &jacobian_transposed) const =0
Solve the (linear) adjoint set of equations with a vector of FiniteElementState as unknown.
std::shared_ptr< FieldD > DualPtr
using
virtual std::vector< FieldPtr > solve(const std::vector< FieldPtr > &u_guesses, std::function< std::vector< mfem::Vector >(const std::vector< FieldPtr > &)> residuals, std::function< std::vector< std::vector< MatrixPtr >>(const std::vector< FieldPtr > &)> jacobians) const =0
Solve a set of equations with a vector of FiniteElementState as unknown.
virtual void clearMemory() const
Interface option to clear memory between solves to avoid high-water mark memory usage.
std::unique_ptr< mfem::HypreParMatrix > MatrixPtr
using
virtual void completeSetup(const std::vector< FieldT > &us)=0
Required for certain solvers/preconditions, e.g. when multigrid algorithms want a near null-space For...
std::shared_ptr< FieldT > FieldPtr
using
Abstract interface to DifferentiableSolver interface. Each differentiable solve should provide both i...
virtual std::shared_ptr< smith::FiniteElementState > solve(const smith::FiniteElementState &u_guess, std::function< mfem::Vector(const smith::FiniteElementState &)> equation, std::function< std::unique_ptr< mfem::HypreParMatrix >(const smith::FiniteElementState &)> jacobian) const =0
Solve a set of equations with a FiniteElementState as unknown.
virtual std::shared_ptr< smith::FiniteElementState > solveAdjoint(const smith::FiniteElementDual &u_bar, std::unique_ptr< mfem::HypreParMatrix > jacobian_transposed) const =0
Solve the (linear) adjoint set of equations with a FiniteElementState as unknown.
virtual void completeSetup(const smith::FiniteElementState &u)=0
Required for certain solvers/preconditioners, e.g. when multigrid algorithms want a near null-space F...
virtual void clearMemory() const
Interface option to clear memory between solves to avoid high-water mark memory usage.
virtual ~DifferentiableSolver()
destructor
Class for encapsulating the dual vector space of a finite element space (i.e. the space of linear for...
Class for encapsulating the critical MFEM components of a primal finite element field.
Implementation of the DifferentiableBlockSolver interface for the special case of linear solves with ...
std::vector< FieldPtr > solve(const std::vector< FieldPtr > &u_guesses, std::function< std::vector< mfem::Vector >(const std::vector< FieldPtr > &)> residuals, std::function< std::vector< std::vector< MatrixPtr >>(const std::vector< FieldPtr > &)> jacobians) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::unique_ptr< mfem::Solver > mfem_preconditioner
stored mfem block preconditioner
std::vector< FieldPtr > solveAdjoint(const std::vector< DualPtr > &u_bars, std::vector< std::vector< MatrixPtr >> &jacobian_transposed) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::unique_ptr< mfem::Solver > mfem_solver
stored mfem block solver
LinearDifferentiableBlockSolver(std::unique_ptr< mfem::Solver > s, std::unique_ptr< mfem::Solver > p)
Construct from a linear solver and linear block precondition which may be used by the linear solver.
void completeSetup(const std::vector< FieldT > &us) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
Implementation of the DifferentiableSolver interface for the special case of linear solves with linea...
std::unique_ptr< mfem::Solver > mfem_preconditioner
optionally used preconditioner
std::shared_ptr< smith::FiniteElementState > solve(const smith::FiniteElementState &u_guess, std::function< mfem::Vector(const smith::FiniteElementState &)> equation, std::function< std::unique_ptr< mfem::HypreParMatrix >(const smith::FiniteElementState &)> jacobian) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void completeSetup(const smith::FiniteElementState &u) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::unique_ptr< mfem::Solver > mfem_solver
linear solver
LinearDifferentiableSolver(std::unique_ptr< mfem::Solver > s, std::unique_ptr< mfem::Solver > p)
Construct from a linear solver and linear precondition which may also be used by a nonlinear solver.
std::shared_ptr< smith::FiniteElementState > solveAdjoint(const smith::FiniteElementDual &u_bar, std::unique_ptr< mfem::HypreParMatrix > jacobian_transposed) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
Helper class for constructing a mesh consistent with Smith.
Definition: mesh.hpp:37
Implementation of the DifferentiableBlockSolver interface for the special case of nonlinear solves wi...
std::vector< std::vector< MatrixPtr > > matrix_of_jacs_
void completeSetup(const std::vector< FieldT > &us) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< FieldPtr > solveAdjoint(const std::vector< DualPtr > &u_bars, std::vector< std::vector< MatrixPtr >> &jacobian_transposed) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< FieldPtr > solve(const std::vector< FieldPtr > &u_guesses, std::function< std::vector< mfem::Vector >(const std::vector< FieldPtr > &)> residuals, std::function< std::vector< std::vector< MatrixPtr >>(const std::vector< FieldPtr > &)> jacobians) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
NonlinearDifferentiableBlockSolver(std::unique_ptr< EquationSolver > s)
Construct from a linear solver and linear block precondition which may be used by the linear solver.
std::unique_ptr< mfem::BlockOperator > block_jac_
Need to hold an instance of a block operator to work with the mfem solver interface.
std::unique_ptr< EquationSolver > nonlinear_solver_
the nonlinear equation solver used for the forward pass
Implementation of the DifferentiableSolver interface for the special case of nonlinear solves with li...
std::shared_ptr< smith::FiniteElementState > solveAdjoint(const smith::FiniteElementDual &u_bar, std::unique_ptr< mfem::HypreParMatrix > jacobian_transposed) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void completeSetup(const smith::FiniteElementState &u) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::unique_ptr< mfem::HypreParMatrix > J_
stored linearized Jacobian matrix for memory reuse
void clearMemory() const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
NonlinearDifferentiableSolver(std::unique_ptr< EquationSolver > s)
Consruct from a smith nonlinear EquationSolver.
std::unique_ptr< EquationSolver > nonlinear_solver_
the nonlinear equation solver used for the forward pass
std::shared_ptr< smith::FiniteElementState > solve(const smith::FiniteElementState &u_guess, std::function< mfem::Vector(const smith::FiniteElementState &)> equation, std::function< std::unique_ptr< mfem::HypreParMatrix >(const smith::FiniteElementState &)> jacobian) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
Accelerator functionality.
Definition: smith.cpp:36
std::shared_ptr< NonlinearDifferentiableSolver > buildDifferentiableNonlinearSolver(NonlinearSolverOptions nonlinear_opts, LinearSolverOptions linear_opts, const smith::Mesh &mesh)
Create a differentiable nonlinear solver.
std::shared_ptr< LinearDifferentiableSolver > buildDifferentiableLinearSolver(LinearSolverOptions linear_opts, const smith::Mesh &mesh)
Create a differentiable linear solver.
std::shared_ptr< NonlinearDifferentiableBlockSolver > buildDifferentiableNonlinearBlockSolver(NonlinearSolverOptions nonlinear_opts, LinearSolverOptions linear_opts, const smith::Mesh &mesh)
Create a differentiable nonlinear block solver.
Parameters for an iterative linear solution scheme.
Nonlinear solution scheme parameters.