43 const std::string & name_in,
44 const unsigned int number_in) :
46 Parent (es, name_in, number_in),
48 zero_out_matrix_and_rhs(true),
49 _can_add_matrices (true)
162 pr.second->attach_dof_map (dof_map);
207 libmesh_error_msg(
"ERROR: Too late. Cannot add matrices to the system after initialization" 208 <<
"\n any more. You should have done this earlier.");
216 _matrices.insert (std::make_pair (mat_name, buf));
269 libmesh_error_msg(
"ERROR: matrix " << mat_name <<
" does not exist in this system!");
271 return *(pos->second);
282 libmesh_error_msg(
"ERROR: matrix " << mat_name <<
" does not exist in this system!");
284 return *(pos->second);
313 std::pair<unsigned int, Real>
317 LOG_SCOPE(
"sensitivity_solve()",
"ImplicitSystem");
337 std::pair<unsigned int, Real> solver_params =
339 std::pair<unsigned int, Real> totalrval = std::make_pair(0,0.0);
345 std::pair<unsigned int, Real> rval =
349 solver_params.second,
350 solver_params.first);
352 totalrval.first += rval.first;
353 totalrval.second += rval.second;
357 #ifdef LIBMESH_ENABLE_CONSTRAINTS 371 std::pair<unsigned int, Real>
375 LOG_SCOPE(
"adjoint_solve()",
"ImplicitSystem");
392 std::pair<unsigned int, Real> solver_params =
394 std::pair<unsigned int, Real> totalrval = std::make_pair(0,0.0);
396 for (
unsigned int i=0; i != this->
n_qois(); ++i)
399 const std::pair<unsigned int, Real> rval =
402 solver_params.second,
403 solver_params.first);
405 totalrval.first += rval.first;
406 totalrval.second += rval.second;
412 #ifdef LIBMESH_ENABLE_CONSTRAINTS 413 for (
unsigned int i=0; i != this->
n_qois(); ++i)
424 std::pair<unsigned int, Real>
427 const QoISet & qoi_indices)
430 LOG_SCOPE(
"weighted_sensitivity_adjoint_solve()",
"ImplicitSystem");
446 for (
unsigned int i=0; i != this->
n_qois(); ++i)
456 std::vector<std::unique_ptr<NumericVector<Number>>> temprhs(this->
n_qois());
457 for (
unsigned int i=0; i != this->
n_qois(); ++i)
474 weights.
deep_copy(parameterperturbation);
475 parameterperturbation *= delta_p;
476 parameters += parameterperturbation;
488 for (
unsigned int i=0; i != this->
n_qois(); ++i)
494 *(temprhs[i]) *= -1.0;
498 parameterperturbation *= -1.0;
499 parameters += parameterperturbation;
508 for (
unsigned int i=0; i != this->
n_qois(); ++i)
514 *(temprhs[i]) /= (2.0*delta_p);
537 std::pair<unsigned int, Real> solver_params =
539 std::pair<unsigned int, Real> totalrval = std::make_pair(0,0.0);
541 for (
unsigned int i=0; i != this->
n_qois(); ++i)
544 const std::pair<unsigned int, Real> rval =
547 solver_params.second,
548 solver_params.first);
550 totalrval.first += rval.first;
551 totalrval.second += rval.second;
557 #ifdef LIBMESH_ENABLE_CONSTRAINTS 558 for (
unsigned int i=0; i != this->
n_qois(); ++i)
570 std::pair<unsigned int, Real>
575 LOG_SCOPE(
"weighted_sensitivity_solve()",
"ImplicitSystem");
601 weights.
deep_copy(parameterperturbation);
602 parameterperturbation *= delta_p;
603 parameters += parameterperturbation;
608 std::unique_ptr<NumericVector<Number>> temprhs = this->
rhs->
clone();
611 parameterperturbation *= -1.0;
612 parameters += parameterperturbation;
617 *temprhs -= *(this->
rhs);
618 *temprhs /= (2.0*delta_p);
631 std::pair<unsigned int, Real> solver_params =
634 const std::pair<unsigned int, Real> rval =
637 solver_params.second,
638 solver_params.first);
643 #ifdef LIBMESH_ENABLE_CONSTRAINTS 659 const unsigned int Np = cast_int<unsigned int>
662 for (
unsigned int p=0; p != Np; ++p)
669 Number old_parameter = *parameters[p];
674 *parameters[p] -= delta_p;
679 sensitivity_rhs = *this->
rhs;
681 *parameters[p] = old_parameter + delta_p;
687 sensitivity_rhs -= *this->
rhs;
688 sensitivity_rhs /= (2*delta_p);
689 sensitivity_rhs.
close();
691 *parameters[p] = old_parameter;
704 const unsigned int Np = cast_int<unsigned int>
706 const unsigned int Nq = this->
n_qois();
763 for (
unsigned int j=0; j != Np; ++j)
770 Number old_parameter = *parameters[j];
775 *parameters[j] = old_parameter - delta_p;
777 std::vector<Number> qoi_minus = this->
qoi;
781 *parameters[j] = old_parameter + delta_p;
783 std::vector<Number> & qoi_plus = this->
qoi;
785 std::vector<Number> partialq_partialp(Nq, 0);
786 for (
unsigned int i=0; i != Nq; ++i)
788 partialq_partialp[i] = (qoi_plus[i] - qoi_minus[i]) / (2.*delta_p);
791 *parameters[j] = old_parameter;
793 for (
unsigned int i=0; i != Nq; ++i)
795 sensitivities[i][j] = partialq_partialp[i] +
796 neg_partialR_partialp.
dot(this->get_adjoint_solution(i));
814 const unsigned int Np = cast_int<unsigned int>
816 const unsigned int Nq = this->
n_qois();
848 for (
unsigned int i=0; i != this->
n_qois(); ++i)
852 for (
unsigned int j=0; j != Np; ++j)
858 Number old_parameter = *parameters[j];
863 *parameters[j] = old_parameter - delta_p;
865 std::vector<Number> qoi_minus = this->
qoi;
867 *parameters[j] = old_parameter + delta_p;
869 std::vector<Number> & qoi_plus = this->
qoi;
871 std::vector<Number> partialq_partialp(Nq, 0);
872 for (
unsigned int i=0; i != Nq; ++i)
874 partialq_partialp[i] = (qoi_plus[i] - qoi_minus[i]) / (2.*delta_p);
877 *parameters[j] = old_parameter;
879 for (
unsigned int i=0; i != Nq; ++i)
881 sensitivities[i][j] = partialq_partialp[i] +
909 std::unique_ptr<NumericVector<Number>> tempvec = this->
solution->zero_clone();
911 const unsigned int Np = cast_int<unsigned int>
913 const unsigned int Nq = this->
n_qois();
953 for (
unsigned int k=0; k != Np; ++k)
970 parameterperturbation *= delta_p;
971 parameters += parameterperturbation;
973 Number old_parameter = *parameters[k];
975 *parameters[k] = old_parameter + delta_p;
979 std::vector<Number> partial2q_term = this->
qoi;
980 std::vector<Number> partial2R_term(this->
n_qois());
981 for (
unsigned int i=0; i != Nq; ++i)
983 partial2R_term[i] = this->
rhs->
dot(this->get_adjoint_solution(i));
985 *parameters[k] = old_parameter - delta_p;
989 for (
unsigned int i=0; i != Nq; ++i)
992 partial2q_term[i] -= this->
qoi[i];
997 parameterperturbation *= -1.0;
998 parameters += parameterperturbation;
1001 old_parameter = *parameters[k];
1003 *parameters[k] = old_parameter + delta_p;
1007 for (
unsigned int i=0; i != Nq; ++i)
1010 partial2q_term[i] -= this->
qoi[i];
1014 *parameters[k] = old_parameter - delta_p;
1018 for (
unsigned int i=0; i != Nq; ++i)
1021 partial2q_term[i] += this->
qoi[i];
1025 for (
unsigned int i=0; i != Nq; ++i)
1028 partial2q_term[i] /= (4. * delta_p * delta_p);
1029 partial2R_term[i] /= (4. * delta_p * delta_p);
1032 for (
unsigned int i=0; i != Nq; ++i)
1034 sensitivities[i][k] = partial2q_term[i] - partial2R_term[i];
1052 *parameters[k] = old_parameter + delta_p;
1062 for (
unsigned int i=0; i != Nq; ++i)
1071 *parameters[k] = old_parameter - delta_p;
1081 for (
unsigned int i=0; i != Nq; ++i)
1113 std::unique_ptr<NumericVector<Number>> tempvec = this->
solution->zero_clone();
1117 std::unique_ptr<NumericVector<Number>> oldsolution = this->
solution->clone();
1119 const unsigned int Np = cast_int<unsigned int>
1120 (parameters.
size());
1121 const unsigned int Nq = this->
n_qois();
1153 for (
unsigned int k=0; k != Np; ++k)
1155 Number old_parameterk = *parameters[k];
1161 for (
unsigned int l=0; l != k+1; ++l)
1174 Number old_parameterl = *parameters[l];
1176 *parameters[k] += delta_p;
1177 *parameters[l] += delta_p;
1181 std::vector<Number> partial2q_term = this->
qoi;
1182 std::vector<Number> partial2R_term(this->
n_qois());
1183 for (
unsigned int i=0; i != Nq; ++i)
1185 partial2R_term[i] = this->
rhs->
dot(this->get_adjoint_solution(i));
1187 *parameters[l] -= 2.*delta_p;
1191 for (
unsigned int i=0; i != Nq; ++i)
1194 partial2q_term[i] -= this->
qoi[i];
1198 *parameters[k] -= 2.*delta_p;
1202 for (
unsigned int i=0; i != Nq; ++i)
1205 partial2q_term[i] += this->
qoi[i];
1209 *parameters[l] += 2.*delta_p;
1213 for (
unsigned int i=0; i != Nq; ++i)
1216 partial2q_term[i] -= this->
qoi[i];
1218 partial2q_term[i] /= (4. * delta_p * delta_p);
1219 partial2R_term[i] /= (4. * delta_p * delta_p);
1222 for (
unsigned int i=0; i != Nq; ++i)
1225 Number current_terms = partial2q_term[i] - partial2R_term[i];
1232 *parameters[l] = old_parameterl;
1233 *parameters[k] = old_parameterk;
1249 *parameters[k] = old_parameterk + delta_p;
1256 for (
unsigned int l=0; l != Np; ++l)
1259 for (
unsigned int i=0; i != Nq; ++i)
1275 *parameters[k] = old_parameterk - delta_p;
1282 for (
unsigned int l=0; l != Np; ++l)
1285 for (
unsigned int i=0; i != Nq; ++i)
1302 *parameters[k] = old_parameterk;
1332 for (
unsigned int l=0; l != k+1; ++l)
1335 for (
unsigned int i=0; i != Nq; ++i)
1361 for (
unsigned int l=0; l != k+1; ++l)
1364 for (
unsigned int i=0; i != Nq; ++i)
1402 libmesh_deprecated();
1412 new_solver->
init((this->
name()+
"_").c_str());
1423 return std::make_pair(this->
get_equation_systems().parameters.get<
unsigned int>(
"linear solver maximum iterations"),
1432 libmesh_deprecated();
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
virtual bool initialized() const
virtual void init_data() override
Manages multiples systems of equations.
virtual void qoi_parameter_hessian_vector_product(const QoISet &qoi_indices, const ParameterVector ¶meters, const ParameterVector &vector, SensitivityData &product) override
void deep_copy(ParameterVector &target) const
const SparseMatrix< Number > & get_matrix(const std::string &mat_name) const
bool have_matrix(const std::string &mat_name) const
NumericVector< Number > & add_adjoint_solution(unsigned int i=0)
Specifies parameters for parameter sensitivity calculations.
static std::unique_ptr< LinearSolver< T > > build(const libMesh::Parallel::Communicator &comm_in, const SolverPackage solver_package=libMesh::default_solver_package())
void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const
virtual std::pair< unsigned int, Real > get_linear_solve_parameters() const
Used to specify quantities of interest in a simulation.
void allocate_hessian_data(const QoISet &qoi_indices, const System &sys, const ParameterVector ¶meter_vector)
unsigned int n_qois() const
virtual bool initialized() const
virtual std::pair< unsigned int, Real > weighted_sensitivity_solve(const ParameterVector ¶meters, const ParameterVector &weights) override
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
NumericVector< Number > & get_sensitivity_solution(unsigned int i=0)
NumericVector< Number > & get_sensitivity_rhs(unsigned int i=0)
const EquationSystems & get_equation_systems() const
bool is_attached(SparseMatrix< Number > &matrix)
void attach_matrix(SparseMatrix< Number > &matrix)
virtual void clear() override
virtual void reinit() override
SparseMatrix< Number > & add_matrix(const std::string &mat_name)
NumericVector< Number > * rhs
virtual ~ImplicitSystem()
const Parallel::Communicator & comm() const
virtual std::unique_ptr< NumericVector< T > > clone() const =0
virtual LinearSolver< Number > * get_linear_solver() const
virtual std::pair< unsigned int, Real > sensitivity_solve(const ParameterVector ¶meters) override
NumericVector< Number > & add_sensitivity_rhs(unsigned int i=0)
static const Real TOLERANCE
std::map< std::string, SparseMatrix< Number > * > _matrices
virtual T dot(const NumericVector< T > &v) const =0
bool zero_out_matrix_and_rhs
virtual std::pair< unsigned int, Real > adjoint_solve(const QoISet &qoi_indices=QoISet()) override
NumericVector< Number > & add_weighted_sensitivity_solution()
long double max(long double a, double b)
const MeshBase & get_mesh() const
NumericVector< Number > & get_weighted_sensitivity_solution()
virtual void release_linear_solver(LinearSolver< Number > *) const
void enforce_adjoint_constraints_exactly(NumericVector< Number > &v, unsigned int q) const
NumericVector< Number > & add_weighted_sensitivity_adjoint_solution(unsigned int i=0)
virtual void forward_qoi_parameter_sensitivity(const QoISet &qoi_indices, const ParameterVector ¶meters, SensitivityData &sensitivities) override
Manages the degrees of freedom (DOFs) in a simulation.
bool has_index(std::size_t) const
void allocate_data(const QoISet &qoi_indices, const System &sys, const ParameterVector ¶meter_vector)
virtual void assembly(bool, bool, bool=false, bool=false)
bool has_adjoint_dirichlet_boundaries(unsigned int q) const
Holds completed parameter sensitivity calculations.
virtual void init(const char *name=nullptr)=0
std::vector< Number > qoi
virtual void adjoint_qoi_parameter_sensitivity(const QoISet &qoi_indices, const ParameterVector ¶meters, SensitivityData &sensitivities) override
Manages consistently variables, degrees of freedom, and coefficient vectors.
virtual std::pair< unsigned int, Real > adjoint_solve(SparseMatrix< T > &, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int)
std::unique_ptr< NumericVector< Number > > solution
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int)=0
virtual void disable_cache() override
bool is_adjoint_already_solved() const
virtual void clear() override
const SparseMatrix< Number > * request_matrix(const std::string &mat_name) const
ImplicitSystem(EquationSystems &es, const std::string &name, const unsigned int number)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::map< std::string, SparseMatrix< Number > * >::const_iterator const_matrices_iterator
virtual void reuse_preconditioner(bool)
void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const
const Number & second_derivative(unsigned int qoi_index, unsigned int parameter_index1, unsigned int parameter_index2) const
void remove_matrix(const std::string &mat_name)
SparseMatrix< Number > * matrix
virtual void get_transpose(SparseMatrix< T > &dest) const =0
virtual void assemble_qoi(const QoISet &qoi_indices=QoISet()) override
virtual void assemble_residual_derivatives(const ParameterVector ¶meters) override
std::map< std::string, SparseMatrix< Number > * >::iterator matrices_iterator
virtual void assemble_qoi_derivative(const QoISet &qoi_indices=QoISet(), bool include_liftfunc=true, bool apply_constraints=true) override
const T & get(const std::string &) const
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
virtual void assemble() override
bool on_command_line(std::string arg)
const std::string & name() const
NumericVector< Number > & add_sensitivity_solution(unsigned int i=0)
void compute_sparsity(const MeshBase &)
bool assemble_before_solve
const DofMap & get_dof_map() const
virtual void qoi_parameter_hessian(const QoISet &qoi_indices, const ParameterVector ¶meters, SensitivityData &hessian) override
virtual std::pair< unsigned int, Real > weighted_sensitivity_adjoint_solve(const ParameterVector ¶meters, const ParameterVector &weights, const QoISet &qoi_indices=QoISet()) override
virtual void init_matrices()
void value_copy(ParameterVector &target) const
NumericVector< Number > & get_weighted_sensitivity_adjoint_solution(unsigned int i=0)
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
NumericVector< Number > & get_adjoint_rhs(unsigned int i=0)