OGS
VectorMatrixAssembler.cpp
Go to the documentation of this file.
1
12
13#include <cassert>
14
19
20namespace ProcessLib
21{
23 AbstractJacobianAssembler& jacobian_assembler)
24 : _jacobian_assembler(jacobian_assembler)
25{
26}
27
29 const std::size_t mesh_item_id, LocalAssemblerInterface& local_assembler,
30 const NumLib::LocalToGlobalIndexMap& dof_table, const double t,
31 double const dt, const GlobalVector& x)
32{
33 auto const indices = NumLib::getIndices(mesh_item_id, dof_table);
34 auto const local_x = x.get(indices);
35
36 local_assembler.preAssemble(t, dt, local_x);
37}
38
40 const std::size_t mesh_item_id, LocalAssemblerInterface& local_assembler,
41 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_tables,
42 const double t, double const dt, std::vector<GlobalVector*> const& x,
43 std::vector<GlobalVector*> const& x_prev, int const process_id,
45{
46 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
47 indices_of_processes.reserve(dof_tables.size());
48 transform(cbegin(dof_tables), cend(dof_tables),
49 back_inserter(indices_of_processes),
50 [&](auto const dof_table)
51 { return NumLib::getIndices(mesh_item_id, *dof_table); });
52
53 auto const& indices = indices_of_processes[process_id];
54 _local_M_data.clear();
55 _local_K_data.clear();
56 _local_b_data.clear();
57
58 std::size_t const number_of_processes = x.size();
59 // Monolithic scheme
60 if (number_of_processes == 1)
61 {
62 auto const local_x = x[process_id]->get(indices);
63 auto const local_x_prev = x_prev[process_id]->get(indices);
64 local_assembler.assemble(t, dt, local_x, local_x_prev, _local_M_data,
66 }
67 else // Staggered scheme
68 {
69 auto local_coupled_xs =
70 getCoupledLocalSolutions(x, indices_of_processes);
71 auto const local_x = MathLib::toVector(local_coupled_xs);
72
73 auto local_coupled_x_prevs =
74 getCoupledLocalSolutions(x_prev, indices_of_processes);
75 auto const local_x_prev = MathLib::toVector(local_coupled_x_prevs);
76
77 local_assembler.assembleForStaggeredScheme(
78 t, dt, local_x, local_x_prev, process_id, _local_M_data,
80 }
81
82 auto const num_r_c = indices.size();
83 auto const r_c_indices =
85
86 if (!_local_M_data.empty())
87 {
88 auto const local_M = MathLib::toMatrix(_local_M_data, num_r_c, num_r_c);
89 M.add(r_c_indices, local_M);
90 }
91 if (!_local_K_data.empty())
92 {
93 auto const local_K = MathLib::toMatrix(_local_K_data, num_r_c, num_r_c);
94 K.add(r_c_indices, local_K);
95 }
96 if (!_local_b_data.empty())
97 {
98 assert(_local_b_data.size() == num_r_c);
99 b.add(indices, _local_b_data);
100 }
101
102 _local_output(t, process_id, mesh_item_id, _local_M_data, _local_K_data,
104}
105
107 std::size_t const mesh_item_id, LocalAssemblerInterface& local_assembler,
108 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_tables,
109 const double t, double const dt, std::vector<GlobalVector*> const& x,
110 std::vector<GlobalVector*> const& x_prev, int const process_id,
112{
113 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
114 indices_of_processes.reserve(dof_tables.size());
115 transform(cbegin(dof_tables), cend(dof_tables),
116 back_inserter(indices_of_processes),
117 [&](auto const dof_table)
118 { return NumLib::getIndices(mesh_item_id, *dof_table); });
119
120 auto const& indices = indices_of_processes[process_id];
121
122 _local_M_data.clear();
123 _local_K_data.clear();
124 _local_b_data.clear();
125 _local_Jac_data.clear();
126
127 std::size_t const number_of_processes = x.size();
128 // Monolithic scheme
129 if (number_of_processes == 1)
130 {
131 auto const local_x = x[process_id]->get(indices);
132 auto const local_x_prev = x_prev[process_id]->get(indices);
134 local_assembler, t, dt, local_x, local_x_prev, _local_M_data,
136 }
137 else // Staggered scheme
138 {
139 auto local_coupled_xs =
140 getCoupledLocalSolutions(x, indices_of_processes);
141 auto const local_x = MathLib::toVector(local_coupled_xs);
142
143 auto local_coupled_x_prevs =
144 getCoupledLocalSolutions(x_prev, indices_of_processes);
145 auto const local_x_prev = MathLib::toVector(local_coupled_x_prevs);
146
148 local_assembler, t, dt, local_x, local_x_prev, process_id,
150 }
151
152 auto const num_r_c = indices.size();
153 auto const r_c_indices =
155
156 if (!_local_M_data.empty())
157 {
158 auto const local_M = MathLib::toMatrix(_local_M_data, num_r_c, num_r_c);
159 M.add(r_c_indices, local_M);
160 }
161 if (!_local_K_data.empty())
162 {
163 auto const local_K = MathLib::toMatrix(_local_K_data, num_r_c, num_r_c);
164 K.add(r_c_indices, local_K);
165 }
166 if (!_local_b_data.empty())
167 {
168 assert(_local_b_data.size() == num_r_c);
169 b.add(indices, _local_b_data);
170 }
171 if (!_local_Jac_data.empty())
172 {
173 auto const local_Jac =
174 MathLib::toMatrix(_local_Jac_data, num_r_c, num_r_c);
175 Jac.add(r_c_indices, local_Jac);
176 }
177 else
178 {
179 OGS_FATAL(
180 "No Jacobian has been assembled! This might be due to programming "
181 "errors in the local assembler of the current process.");
182 }
183
184 _local_output(t, process_id, mesh_item_id, _local_M_data, _local_K_data,
186}
187
188} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
int add(IndexType row, IndexType col, double val)
Definition EigenMatrix.h:86
Global vector based on Eigen vector.
Definition EigenVector.h:25
void add(IndexType rowId, double v)
add entry
Definition EigenVector.h:76
double get(IndexType rowId) const
get entry
Definition EigenVector.h:58
MathLib::RowColumnIndices< GlobalIndexType > RowColumnIndices
Base class for Jacobian assemblers.
virtual void assembleWithJacobianForStaggeredScheme(LocalAssemblerInterface &, double const, double const, Eigen::VectorXd const &, Eigen::VectorXd const &, int const, std::vector< double > &, std::vector< double > &, std::vector< double > &, std::vector< double > &)
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_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)=0
virtual void preAssemble(double const, double const, std::vector< double > const &)
virtual void assembleForStaggeredScheme(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, int const process_id, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data)
virtual void assemble(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data)
void assembleWithJacobian(std::size_t const mesh_item_id, LocalAssemblerInterface &local_assembler, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, const double t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalMatrix &M, GlobalMatrix &K, GlobalVector &b, GlobalMatrix &Jac)
VectorMatrixAssembler(AbstractJacobianAssembler &jacobian_assembler)
void assemble(std::size_t const mesh_item_id, LocalAssemblerInterface &local_assembler, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, double const t, double const dt, std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id, GlobalMatrix &M, GlobalMatrix &K, GlobalVector &b)
void preAssemble(const std::size_t mesh_item_id, LocalAssemblerInterface &local_assembler, const NumLib::LocalToGlobalIndexMap &dof_table, const double t, double const dt, const GlobalVector &x)
Assembly::LocalMatrixOutput _local_output
AbstractJacobianAssembler & _jacobian_assembler
Used to assemble the Jacobian.
Eigen::Map< const Vector > toVector(std::vector< double > const &data, Eigen::VectorXd::Index size)
Creates an Eigen mapped vector from the given data vector.
Eigen::Map< const Matrix > toMatrix(std::vector< double > const &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)