OGS
AbstractJacobianAssembler.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Core>
7#include <range/v3/view.hpp>
8#include <range/v3/view/transform.hpp>
9#include <vector>
10
11#include "BaseLib/Error.h"
12
13namespace ProcessLib
14{
16
19{
20public:
25 std::vector<double> const&& absolute_epsilons)
26 : absolute_epsilons_(std::move(absolute_epsilons))
27 {
28 if (absolute_epsilons_.empty())
29 {
30 OGS_FATAL(
31 "Numerical Jacobian assembler requires perturbation values "
32 "(epsilons) for finite difference approximation, but none were "
33 "provided.\n"
34 "Please specify <epsilons> in the <jacobian_assembler> section "
35 "of your project file.\n"
36 "Example: <epsilons>1e-8 1e-8</epsilons> for a process with 2 "
37 "non-deformation variables.");
38 }
39 }
40
42
45 virtual void assembleWithJacobian(LocalAssemblerInterface& local_assembler,
46 double const t, double const dt,
47 std::vector<double> const& local_x,
48 std::vector<double> const& local_x_prev,
49 std::vector<double>& local_b_data,
50 std::vector<double>& local_Jac_data) = 0;
51
55 LocalAssemblerInterface& /*local_assembler*/, double const /*t*/,
56 double const /*dt*/, Eigen::VectorXd const& /*local_x*/,
57 Eigen::VectorXd const& /*local_x_prev*/, int const /*process_id*/,
58 std::vector<double>& /*local_b_data*/,
59 std::vector<double>& /*local_Jac_data*/)
60 {
61 // TODO make pure virtual.
62 OGS_FATAL("not implemented.");
63 }
64
65 virtual std::unique_ptr<AbstractJacobianAssembler> copy() const = 0;
66
67 virtual ~AbstractJacobianAssembler() = default;
68
74 int const max_non_deformation_dofs_per_node) const
75 {
76 if (absolute_epsilons_.empty())
77 { // No epsilons specified — this assembler is used for the Picard
78 // nonlinear solver or for the Newton nonlinear solver with
79 // analytical Jacobian, so there is nothing to do.
80 return;
81 }
82
83 int const num_abs_eps = static_cast<int>(absolute_epsilons_.size());
84 if (num_abs_eps != max_non_deformation_dofs_per_node)
85 {
87 "Mismatch in numerical Jacobian perturbation configuration:\n"
88 " Provided epsilons: {:d}\n"
89 " Required epsilons: {:d} (one per non-deformation variable "
90 "component)\n\n"
91 "Each non-deformation variable needs exactly one epsilon value "
92 "for numerical differentiation.\n"
93 "Deformation variables use analytical Jacobian and do not "
94 "require epsilons.\n"
95 "Please adjust the <epsilons> array in your project file to "
96 "match the number of required components.",
97 num_abs_eps, max_non_deformation_dofs_per_node);
98 }
99 }
100
102 std::vector<int> const& non_deformation_component_ids)
103 {
104 // Repeated in checkPerturbationSize to cover staggered scheme in TH2M
105 // and THM, which may be supported in future.
106 if (absolute_epsilons_.empty())
107 { // No epsilons specified — this assembler is used for the Picard
108 // nonlinear solver or for the Newton nonlinear solver with
109 // analytical Jacobian, so there is nothing to do.
110 return;
111 }
112
113 // So far, the number of specified perturbations is checked inside this
114 // function, assuming the TH2M and THM processes do not use the
115 // staggered scheme. If the staggered scheme is supported in these
116 // processes, call `checkPerturbationSize(...)` and then
117 // `setNonDeformationComponentIDsNoSizeCheck(...)` instead.
118 checkPerturbationSize(non_deformation_component_ids.size());
119
120 non_deformation_component_ids_ = non_deformation_component_ids;
121 }
122
124 std::vector<int> const& non_deformation_component_ids)
125 {
126 non_deformation_component_ids_ = non_deformation_component_ids;
127 }
128
130 {
131 assert(!non_deformation_component_ids_.empty());
132 namespace rv = ranges::views;
134 rv::transform(
135 [this](int comp_id) -> double const&
136 {
137 return absolute_epsilons_[static_cast<std::size_t>(
138 comp_id)];
139 });
140 }
141
142 auto isPerturbationEnabled() const { return !absolute_epsilons_.empty(); }
143
144protected:
149
158 std::vector<double> const absolute_epsilons_;
159};
160
161} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
void setNonDeformationComponentIDs(std::vector< int > const &non_deformation_component_ids)
virtual void assembleWithJacobian(LocalAssemblerInterface &local_assembler, double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)=0
virtual std::unique_ptr< AbstractJacobianAssembler > copy() const =0
AbstractJacobianAssembler(std::vector< double > const &&absolute_epsilons)
virtual void assembleWithJacobianForStaggeredScheme(LocalAssemblerInterface &, double const, double const, Eigen::VectorXd const &, Eigen::VectorXd const &, int const, std::vector< double > &, std::vector< double > &)
void setNonDeformationComponentIDsNoSizeCheck(std::vector< int > const &non_deformation_component_ids)
virtual ~AbstractJacobianAssembler()=default
void checkPerturbationSize(int const max_non_deformation_dofs_per_node) const