OGS
ProcessLib::CentralDifferencesJacobianAssembler Class Referencefinal

Detailed Description

Assembles the Jacobian matrix using central differences.

Definition at line 24 of file CentralDifferencesJacobianAssembler.h.

#include <CentralDifferencesJacobianAssembler.h>

Inheritance diagram for ProcessLib::CentralDifferencesJacobianAssembler:
[legend]
Collaboration diagram for ProcessLib::CentralDifferencesJacobianAssembler:
[legend]

Public Member Functions

 CentralDifferencesJacobianAssembler (std::vector< double > &&absolute_epsilons)
 
void assembleWithJacobian (LocalAssemblerInterface &local_assembler, double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_xdot, const double dxdot_dx, const double dx_dx, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data) override
 
- Public Member Functions inherited from ProcessLib::AbstractJacobianAssembler
virtual void assembleWithJacobianForStaggeredScheme (LocalAssemblerInterface &, double const, double const, Eigen::VectorXd const &, Eigen::VectorXd const &, const double, const double, int const, std::vector< double > &, std::vector< double > &, std::vector< double > &, std::vector< double > &)
 
virtual ~AbstractJacobianAssembler ()=default
 

Private Attributes

std::vector< double > const _absolute_epsilons
 
std::vector< double > _local_M_data
 
std::vector< double > _local_K_data
 
std::vector< double > _local_b_data
 
std::vector< double > _local_x_perturbed_data
 
std::vector< double > _local_xdot_perturbed_data
 

Constructor & Destructor Documentation

◆ CentralDifferencesJacobianAssembler()

ProcessLib::CentralDifferencesJacobianAssembler::CentralDifferencesJacobianAssembler ( std::vector< double > &&  absolute_epsilons)
explicit

Constructs a new instance.

Parameters
absolute_epsilonsperturbations of the components of the local solution vector used for evaluating the finite differences.
Note
The size of absolute_epsilons defines the "number of components" of the local solution vector (This is not the number of elements of the vector!). Therefore the size of the local solution vector must be divisible by the size of absolute_epsilons. This is the only consistency check performed. It is not checked whether said "number of components" is sensible. E.g., one could pass one epsilon per node, which would be valid but would not make sense at all.

Definition at line 20 of file CentralDifferencesJacobianAssembler.cpp.

22  : _absolute_epsilons(std::move(absolute_epsilons))
23 {
24  if (_absolute_epsilons.empty())
25  {
26  OGS_FATAL("No values for the absolute epsilons have been given.");
27  }
28 }
#define OGS_FATAL(...)
Definition: Error.h:26

References _absolute_epsilons, and OGS_FATAL.

Member Function Documentation

◆ assembleWithJacobian()

void ProcessLib::CentralDifferencesJacobianAssembler::assembleWithJacobian ( LocalAssemblerInterface local_assembler,
double const  t,
double const  dt,
std::vector< double > const &  local_x,
std::vector< double > const &  local_xdot,
const double  dxdot_dx,
const double  dx_dx,
std::vector< double > &  local_M_data,
std::vector< double > &  local_K_data,
std::vector< double > &  local_b_data,
std::vector< double > &  local_Jac_data 
)
overridevirtual

Assembles the Jacobian, the matrices \(M\) and \(K\), and the vector \(b\). For the assembly the assemble() method of the given local_assembler is called several times and the Jacobian is built from finite differences. The number of calls of the assemble() method is \(2N+1\) if \(N\) is the size of local_x.

Attention
It is assumed that the local vectors and matrices are ordered by component.

Implements ProcessLib::AbstractJacobianAssembler.

Definition at line 30 of file CentralDifferencesJacobianAssembler.cpp.

37 {
38  // TODO do not check in every call.
39  if (local_x_data.size() % _absolute_epsilons.size() != 0)
40  {
41  OGS_FATAL(
42  "The number of specified epsilons ({:d}) and the number of local "
43  "d.o.f.s ({:d}) do not match, i.e., the latter is not divisible by "
44  "the former.",
45  _absolute_epsilons.size(), local_x_data.size());
46  }
47 
48  auto const num_r_c =
49  static_cast<Eigen::MatrixXd::Index>(local_x_data.size());
50 
51  auto const local_x =
52  MathLib::toVector<Eigen::VectorXd>(local_x_data, num_r_c);
53  auto const local_xdot =
54  MathLib::toVector<Eigen::VectorXd>(local_xdot_data, num_r_c);
55 
56  auto local_Jac =
57  MathLib::createZeroedMatrix(local_Jac_data, num_r_c, num_r_c);
58  _local_x_perturbed_data = local_x_data;
59  _local_xdot_perturbed_data = local_xdot_data;
60 
61  auto const num_dofs_per_component =
62  local_x_data.size() / _absolute_epsilons.size();
63 
64  // Residual res := M xdot + K x - b
65  // Computing Jac := dres/dx
66  // = M dxdot/dx + dM/dx xdot + K dx/dx + dK/dx x - db/dx
67  // (Note: dM/dx and dK/dx actually have the second and
68  // third index transposed.)
69  // The loop computes the dM/dx, dK/dx and db/dx terms, the rest is computed
70  // afterwards.
71  for (Eigen::MatrixXd::Index i = 0; i < num_r_c; ++i)
72  {
73  // assume that local_x_data is ordered by component.
74  auto const component = i / num_dofs_per_component;
75  auto const eps = _absolute_epsilons[component];
76 
77  _local_x_perturbed_data[i] += eps;
78  _local_xdot_perturbed_data[i] = local_xdot_data[i] + eps / dt;
79  local_assembler.assemble(t, dt, _local_x_perturbed_data,
80  _local_xdot_perturbed_data, local_M_data,
81  local_K_data, local_b_data);
82 
83  _local_x_perturbed_data[i] = local_x_data[i] - eps;
84  _local_xdot_perturbed_data[i] = local_xdot_data[i] - eps / dt;
85  local_assembler.assemble(t, dt, _local_x_perturbed_data,
88 
89  _local_x_perturbed_data[i] = local_x_data[i];
90  _local_xdot_perturbed_data[i] = local_xdot_data[i];
91 
92  if (!local_M_data.empty())
93  {
94  auto const local_M_p =
95  MathLib::toMatrix(local_M_data, num_r_c, num_r_c);
96  auto const local_M_m =
97  MathLib::toMatrix(_local_M_data, num_r_c, num_r_c);
98  local_Jac.col(i).noalias() +=
99  // dM/dxi * x_dot
100  (local_M_p - local_M_m) * local_xdot / (2.0 * eps);
101  local_M_data.clear();
102  _local_M_data.clear();
103  }
104  if (!local_K_data.empty())
105  {
106  auto const local_K_p =
107  MathLib::toMatrix(local_K_data, num_r_c, num_r_c);
108  auto const local_K_m =
109  MathLib::toMatrix(_local_K_data, num_r_c, num_r_c);
110  local_Jac.col(i).noalias() +=
111  // dK/dxi * x
112  (local_K_p - local_K_m) * local_x / (2.0 * eps);
113  local_K_data.clear();
114  _local_K_data.clear();
115  }
116  if (!local_b_data.empty())
117  {
118  auto const local_b_p =
119  MathLib::toVector<Eigen::VectorXd>(local_b_data, num_r_c);
120  auto const local_b_m =
121  MathLib::toVector<Eigen::VectorXd>(_local_b_data, num_r_c);
122  local_Jac.col(i).noalias() -=
123  // db/dxi
124  (local_b_p - local_b_m) / (2.0 * eps);
125  local_b_data.clear();
126  _local_b_data.clear();
127  }
128  }
129 
130  // Assemble with unperturbed local x.
131  local_assembler.assemble(t, dt, local_x_data, local_xdot_data, local_M_data,
132  local_K_data, local_b_data);
133 
134  // Compute remaining terms of the Jacobian.
135  if (dxdot_dx != 0.0 && !local_M_data.empty())
136  {
137  auto local_M = MathLib::toMatrix(local_M_data, num_r_c, num_r_c);
138  local_Jac.noalias() += local_M * dxdot_dx;
139  }
140  if (dx_dx != 0.0 && !local_K_data.empty())
141  {
142  auto local_K = MathLib::toMatrix(local_K_data, num_r_c, num_r_c);
143  local_Jac.noalias() += local_K * dx_dx;
144  }
145 }
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
Definition: EigenMapTools.h:32
Eigen::Map< const Matrix > toMatrix(std::vector< double > const &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
Definition: EigenMapTools.h:72

References _absolute_epsilons, _local_b_data, _local_K_data, _local_M_data, _local_x_perturbed_data, _local_xdot_perturbed_data, ProcessLib::LocalAssemblerInterface::assemble(), MathLib::createZeroedMatrix(), OGS_FATAL, and MathLib::toMatrix().

Member Data Documentation

◆ _absolute_epsilons

std::vector<double> const ProcessLib::CentralDifferencesJacobianAssembler::_absolute_epsilons
private

◆ _local_b_data

std::vector<double> ProcessLib::CentralDifferencesJacobianAssembler::_local_b_data
private

Definition at line 70 of file CentralDifferencesJacobianAssembler.h.

Referenced by assembleWithJacobian().

◆ _local_K_data

std::vector<double> ProcessLib::CentralDifferencesJacobianAssembler::_local_K_data
private

Definition at line 69 of file CentralDifferencesJacobianAssembler.h.

Referenced by assembleWithJacobian().

◆ _local_M_data

std::vector<double> ProcessLib::CentralDifferencesJacobianAssembler::_local_M_data
private

Definition at line 68 of file CentralDifferencesJacobianAssembler.h.

Referenced by assembleWithJacobian().

◆ _local_x_perturbed_data

std::vector<double> ProcessLib::CentralDifferencesJacobianAssembler::_local_x_perturbed_data
private

Definition at line 71 of file CentralDifferencesJacobianAssembler.h.

Referenced by assembleWithJacobian().

◆ _local_xdot_perturbed_data

std::vector<double> ProcessLib::CentralDifferencesJacobianAssembler::_local_xdot_perturbed_data
private

Definition at line 72 of file CentralDifferencesJacobianAssembler.h.

Referenced by assembleWithJacobian().


The documentation for this class was generated from the following files: