OGS
DOFTableUtil.cpp
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#include "DOFTableUtil.h"
5
6#include <algorithm>
7#include <cassert>
8#include <functional>
9
10#include "BaseLib/MPI.h"
12namespace NumLib
13{
14namespace
15{
16template <typename CalculateNorm>
17double norm(GlobalVector const& x, unsigned const global_component,
18 LocalToGlobalIndexMap const& dof_table,
19 CalculateNorm calculate_norm)
20{
21#ifdef USE_PETSC
22 x.setLocalAccessibleVector();
23#endif
24
25 double res = 0.0;
26 auto const& ms = dof_table.getMeshSubset(global_component);
27
28 for (auto const l :
30 {
31 auto const value =
32 getNonGhostNodalValue(x, l, dof_table, global_component);
33 res = calculate_norm(res, value);
34 }
35 return res;
36}
37
38double norm1(GlobalVector const& x, unsigned const global_component,
39 LocalToGlobalIndexMap const& dof_table)
40{
41 double const res =
42 norm(x, global_component, dof_table,
43 [](double res, double value) { return res + std::abs(value); });
44
45#ifdef USE_PETSC
46 return BaseLib::MPI::allreduce(res, MPI_SUM, BaseLib::MPI::Mpi{});
47#endif
48 return res;
49}
50
51double norm2(GlobalVector const& x, unsigned const global_component,
52 LocalToGlobalIndexMap const& dof_table)
53{
54 double const res =
55 norm(x, global_component, dof_table,
56 [](double res, double value) { return res + value * value; });
57
58#ifdef USE_PETSC
59 return std::sqrt(
61#endif
62 return std::sqrt(res);
63}
64
65double normInfinity(GlobalVector const& x, unsigned const global_component,
66 LocalToGlobalIndexMap const& dof_table)
67{
68 double const res =
69 norm(x, global_component, dof_table, [](double res, double value)
70 { return std::max(res, std::abs(value)); });
71
72#ifdef USE_PETSC
73 return BaseLib::MPI::allreduce(res, MPI_MAX, BaseLib::MPI::Mpi{});
74#endif
75 return res;
76}
77} // anonymous namespace
78
80 MeshLib::Location const& location,
81 NumLib::LocalToGlobalIndexMap const& dof_table,
82 std::size_t const global_component_id)
83{
84 auto const index = dof_table.getGlobalIndex(location, global_component_id);
85 assert(index != NumLib::MeshComponentMap::nop);
86
87 if (index < 0)
88 { // ghost node value
89 return 0.0;
90 }
91
92 return x.get(index);
93}
94
95double getNodalValue(GlobalVector const& x, MeshLib::Location const& location,
96 NumLib::LocalToGlobalIndexMap const& dof_table,
97 std::size_t const global_component_id)
98{
99 auto const index = dof_table.getGlobalIndex(location, global_component_id);
100 assert(index != NumLib::MeshComponentMap::nop);
101
102 return x.get(index);
103}
104
105std::vector<GlobalIndexType> getIndices(
106 std::size_t const mesh_item_id,
107 NumLib::LocalToGlobalIndexMap const& dof_table)
108{
109 assert(dof_table.size() > mesh_item_id);
110 std::vector<GlobalIndexType> indices;
111
112 // Local matrices and vectors will always be ordered by component
113 // no matter what the order of the global matrix is.
114 for (int c = 0; c < dof_table.getNumberOfGlobalComponents(); ++c)
115 {
116 auto const& idcs = dof_table(mesh_item_id, c).rows;
117 indices.reserve(indices.size() + idcs.size());
118 indices.insert(indices.end(), idcs.begin(), idcs.end());
119 }
120
121 return indices;
122}
123
124std::vector<GlobalIndexType> getIndices(
125 std::size_t const variable_id,
126 std::size_t const component_id,
127 std::size_t const bulk_element_id,
128 NumLib::LocalToGlobalIndexMap const& dof_table)
129{
130 auto const& ms =
131 dof_table.getMeshSubset(variable_id, component_id).getMesh();
132 std::vector<GlobalIndexType> indices;
133 auto const& bulk_element = ms.getElement(bulk_element_id);
134 auto const global_component =
135 dof_table.getGlobalComponent(variable_id, component_id);
136 auto const mesh_id = ms.getID();
137
138 for (auto const node_id : bulk_element->nodes() | MeshLib::views::ids)
139 {
141 node_id};
142 // TODO: possible issues on higher order meshes with first order
143 // variables (e.g. pressure in HM).
144 indices.push_back(dof_table.getGlobalIndex(loc, global_component));
145 }
146 return indices;
147}
148
150 std::size_t const id,
151 NumLib::LocalToGlobalIndexMap const& dof_table,
152 std::vector<GlobalIndexType>& indices)
153{
154 assert(dof_table.size() > id);
155 indices.clear();
156
157 // Local matrices and vectors will always be ordered by component,
158 // no matter what the order of the global matrix is.
159 for (int c = 0; c < dof_table.getNumberOfGlobalComponents(); ++c)
160 {
161 auto const& idcs = dof_table(id, c).rows;
162 indices.reserve(indices.size() + idcs.size());
163 indices.insert(indices.end(), idcs.begin(), idcs.end());
164 }
165
167}
168
169double norm(GlobalVector const& x, unsigned const global_component,
170 MathLib::VecNormType norm_type,
171 LocalToGlobalIndexMap const& dof_table)
172{
173 switch (norm_type)
174 {
176 return norm1(x, global_component, dof_table);
178 return norm2(x, global_component, dof_table);
180 return normInfinity(x, global_component, dof_table);
181 default:
182 OGS_FATAL("An invalid norm type has been passed.");
183 }
184}
185
186Eigen::VectorXd getLocalX(
187 std::size_t const mesh_item_id,
188 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_tables,
189 std::vector<GlobalVector*> const& x)
190{
191 Eigen::VectorXd local_x_vec;
192
193 auto const n_processes = x.size();
194 for (std::size_t process_id = 0; process_id < n_processes; ++process_id)
195 {
196 auto const indices =
197 NumLib::getIndices(mesh_item_id, *dof_tables[process_id]);
198 assert(!indices.empty());
199 auto const last = local_x_vec.size();
200 local_x_vec.conservativeResize(last + indices.size());
201 auto const local_solution = x[process_id]->get(indices);
202 assert(indices.size() == local_solution.size());
203 local_x_vec.tail(local_solution.size()).noalias() =
204 MathLib::toVector(local_solution);
205 }
206 return local_x_vec;
207}
208
209} // namespace NumLib
#define OGS_FATAL(...)
Definition Error.h:19
MathLib::EigenVector GlobalVector
double get(IndexType rowId) const
get entry
Definition EigenVector.h:52
Mesh const & getMesh() const
Definition MeshSubset.h:83
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition Mesh.h:85
int getGlobalComponent(int const variable_id, int const component_id) const
MathLib::RowColumnIndices< GlobalIndexType > RowColumnIndices
GlobalIndexType getGlobalIndex(MeshLib::Location const &l, int const variable_id, int const component_id) const
MeshLib::MeshSubset const & getMeshSubset(int const variable_id, int const component_id) const
static constexpr NUMLIB_EXPORT GlobalIndexType const nop
static T allreduce(T const &value, MPI_Op const &mpi_op, Mpi const &mpi)
Definition MPI.h:122
Eigen::Map< const Vector > toVector(std::vector< double > const &data, Eigen::VectorXd::Index size)
Creates an Eigen mapped vector from the given data vector.
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
Definition Mesh.h:216
auto meshLocations(Mesh const &mesh, MeshItemType const item_type)
Definition Mesh.h:227
double normInfinity(GlobalVector const &x, unsigned const global_component, LocalToGlobalIndexMap const &dof_table)
double norm1(GlobalVector const &x, unsigned const global_component, LocalToGlobalIndexMap const &dof_table)
double norm2(GlobalVector const &x, unsigned const global_component, LocalToGlobalIndexMap const &dof_table)
double getNodalValue(GlobalVector const &x, MeshLib::Location const &location, NumLib::LocalToGlobalIndexMap const &dof_table, std::size_t const global_component_id)
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
NumLib::LocalToGlobalIndexMap::RowColumnIndices getRowColumnIndices(std::size_t const id, NumLib::LocalToGlobalIndexMap const &dof_table, std::vector< GlobalIndexType > &indices)
Eigen::VectorXd getLocalX(std::size_t const mesh_item_id, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, std::vector< GlobalVector * > const &x)
double getNonGhostNodalValue(GlobalVector const &x, MeshLib::Location const &location, NumLib::LocalToGlobalIndexMap const &dof_table, std::size_t const global_component_id)
double norm(GlobalVector const &x, unsigned const global_component, MathLib::VecNormType norm_type, LocalToGlobalIndexMap const &dof_table)