20 template <
int n_m,
int n_n>
21 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::setConstant(t_self &self,
real R)
24 index iTop = self.Size();
25#if defined(DNDS_DIST_MT_USE_OMP)
26# pragma omp parallel for schedule(static)
28 for (
index i = 0; i < iTop; i++)
29 self.operator[](i).setConstant(R);
32 template <
int n_m,
int n_n>
33 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::setConstant(t_self &self,
const Eigen::Ref<const t_element_mat> &R)
36 index iTop = self.Size();
37#if defined(DNDS_DIST_MT_USE_OMP)
38# pragma omp parallel for schedule(static)
40 for (
index i = 0; i < iTop; i++)
41 self.operator[](i) = R;
44 template <
int n_m,
int n_n>
45 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_plus_assign(t_self &self,
const t_self &R)
49 index iTop = self.Size();
50#if defined(DNDS_DIST_MT_USE_OMP)
51# pragma omp parallel for schedule(static)
53 for (
index i = 0; i < iTop; i++)
54 self.operator[](i) += R.operator[](i);
57 template <
int n_m,
int n_n>
58 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_plus_assign(t_self &self,
real R)
61 index iTop = self.Size();
62#if defined(DNDS_DIST_MT_USE_OMP)
63# pragma omp parallel for schedule(static)
65 for (
index i = 0; i < iTop; i++)
66 self.operator[](i).array() += R;
69 template <
int n_m,
int n_n>
70 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_plus_assign(t_self &self,
const Eigen::Ref<const t_element_mat> &R)
73 index iTop = self.Size();
74#if defined(DNDS_DIST_MT_USE_OMP)
75# pragma omp parallel for schedule(static)
77 for (
index i = 0; i < iTop; i++)
78 self.operator[](i) += R;
81 template <
int n_m,
int n_n>
82 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_minus_assign(t_self &self,
const t_self &R)
86 index iTop = self.Size();
87#if defined(DNDS_DIST_MT_USE_OMP)
88# pragma omp parallel for schedule(static)
90 for (
index i = 0; i < iTop; i++)
91 self.operator[](i) -= R.operator[](i);
94 template <
int n_m,
int n_n>
95 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_mult_assign(t_self &self,
real R)
100 index iTop = self.Size();
101#if defined(DNDS_DIST_MT_USE_OMP)
102# pragma omp parallel for schedule(static)
104 for (
index i = 0; i < iTop; i++)
105 self.operator[](i) *= R;
108 template <
int n_m,
int n_n>
109 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_mult_assign_scalar_arr(t_self &self,
const ArrayDof<1, 1> &R)
113 index iTop = self.Size();
114#if defined(DNDS_DIST_MT_USE_OMP)
115# pragma omp parallel for schedule(static)
117 for (
index i = 0; i < iTop; i++)
118 self.operator[](i).array() *= R[i](0);
121 template <
int n_m,
int n_n>
122 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_mult_assign(t_self &self,
const Eigen::Ref<const t_element_mat> &R)
125 index iTop = self.Size();
126#if defined(DNDS_DIST_MT_USE_OMP)
127# pragma omp parallel for schedule(static)
129 for (
index i = 0; i < iTop; i++)
130 self.operator[](i).array() *= R.array();
133 template <
int n_m,
int n_n>
134 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_mult_assign(t_self &self,
const t_self &R)
138 index iTop = self.Size();
139#if defined(DNDS_DIST_MT_USE_OMP)
140# pragma omp parallel for schedule(static)
142 for (
index i = 0; i < iTop; i++)
143 self.operator[](i).array() *= R.operator[](i).array();
146 template <
int n_m,
int n_n>
147 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_div_assign(t_self &self,
const t_self &R)
151 index iTop = self.Size();
152#if defined(DNDS_DIST_MT_USE_OMP)
153# pragma omp parallel for schedule(static)
155 for (
index i = 0; i < iTop; i++)
156 self.operator[](i).array() /= R.operator[](i).array();
159 template <
int n_m,
int n_n>
160 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::operator_assign(t_self &self,
const t_self &R)
167 DNDS_assert(R.father->RawDataVector().size() == self.father->RawDataVector().size());
168 DNDS_assert(R.son->RawDataVector().size() == self.son->RawDataVector().size());
192 std::copy(R.father->RawDataVector().begin(), R.father->RawDataVector().end(), self.father->RawDataVector().begin());
193 std::copy(R.son->RawDataVector().begin(), R.son->RawDataVector().end(), self.son->RawDataVector().begin());
197 template <
int n_m,
int n_n>
198 void ArrayDofOp<DeviceBackend::Host, n_m, n_n>::addTo(t_self &self,
const t_self &R,
real r)
204 DNDS_assert(R.father->RawDataVector().size() == self.father->RawDataVector().size());
205 auto &RVF = R.father->RawDataVector();
206 auto &TVF = self.father->RawDataVector();
207#if defined(DNDS_DIST_MT_USE_OMP)
208# pragma omp parallel for schedule(static)
210 for (
size_t i = 0; i < RVF.size(); i++)
211 TVF[i] +=
r * RVF[i];
212 DNDS_assert(R.son->RawDataVector().size() == self.son->RawDataVector().size());
213 auto &RVS = R.son->RawDataVector();
214 auto &TVS = self.son->RawDataVector();
215#if defined(DNDS_DIST_MT_USE_OMP)
216# pragma omp parallel for schedule(static)
218 for (
size_t i = 0; i < RVS.size(); i++)
219 TVS[i] +=
r * RVS[i];
222 template <
int n_m,
int n_n>
223 real ArrayDofOp<DeviceBackend::Host, n_m, n_n>::norm2(t_self &self)
226 real sqrSum{0}, sqrSumAll{0};
227 index iTop = self.father->Size();
228#if defined(DNDS_DIST_MT_USE_OMP)
229# pragma omp parallel for schedule(static) reduction(+ : sqrSum)
231 for (
index i = 0; i < iTop; i++)
232 sqrSum += self.father->operator[](i).squaredNorm();
235 return std::sqrt(sqrSumAll);
238 template <
int n_m,
int n_n>
239 real ArrayDofOp<DeviceBackend::Host, n_m, n_n>::norm2(t_self &self,
const t_self &R)
242 real sqrSum{0}, sqrSumAll{0};
243 index iTop = self.father->Size();
244#if defined(DNDS_DIST_MT_USE_OMP)
245# pragma omp parallel for schedule(static) reduction(+ : sqrSum)
247 for (
index i = 0; i < iTop; i++)
248 sqrSum += (self.father->operator[](i) - R.father->operator[](i)).squaredNorm();
251 return std::sqrt(sqrSumAll);
254 template <
int n_m,
int n_n>
255 real ArrayDofOp<DeviceBackend::Host, n_m, n_n>::reduction(t_self &self,
const std::string &op)
258 real sqrSum{0}, sqrSumAll{0};
259 index iTop = self.father->DataSize();
262 sqrSum = sqrSumAll = std::numeric_limits<real>::max();
263#if defined(DNDS_DIST_MT_USE_OMP)
264# pragma omp parallel for schedule(static) reduction(min : sqrSum)
266 for (
index i = 0; i < iTop; i++)
267 sqrSum = std::min(sqrSum, self.father->data()[i]);
270 else if (op ==
"max")
272 sqrSum = sqrSumAll = std::numeric_limits<real>::lowest();
273#if defined(DNDS_DIST_MT_USE_OMP)
274# pragma omp parallel for schedule(static) reduction(max : sqrSum)
276 for (
index i = 0; i < iTop; i++)
277 sqrSum = std::max(sqrSum, self.father->data()[i]);
280 else if (op ==
"sum")
282 sqrSum = sqrSumAll = 0.0;
283#if defined(DNDS_DIST_MT_USE_OMP)
284# pragma omp parallel for schedule(static) reduction(+ : sqrSum)
286 for (
index i = 0; i < iTop; i++)
287 sqrSum = sqrSum + self.father->data()[i];
296 template <
int n_m,
int n_n>
297 typename ArrayDofOp<DeviceBackend::Host, n_m, n_n>::t_element_mat
298 ArrayDofOp<DeviceBackend::Host, n_m, n_n>::componentWiseNorm1(t_self &self)
301 t_element_mat minLocal, min;
303 if (self.father->Size() || (n_m >= 0 && n_n >= 0) || (self.son->Size() == 0))
304 minLocal.resize(self.father->MatRowSize(0), self.father->MatColSize(0));
305 else if (self.son->Size())
306 minLocal.resize(self.son->MatRowSize(0), self.son->MatColSize(0));
307 minLocal.setConstant(0);
309 index iTop = self.father->Size();
310#if defined(DNDS_DIST_MT_USE_OMP)
311# pragma omp declare reduction(EigenVecAdd:t_element_mat : omp_out += omp_in) initializer(omp_priv = omp_orig)
312# pragma omp parallel for schedule(static) reduction(EigenVecAdd : minLocal)
314 for (
index i = 0; i < iTop; i++)
315 minLocal += (self.operator[](i).array().abs()).matrix();
320 template <
int n_m,
int n_n>
321 typename ArrayDofOp<DeviceBackend::Host, n_m, n_n>::t_element_mat
322 ArrayDofOp<DeviceBackend::Host, n_m, n_n>::componentWiseNorm1(t_self &self,
const t_self &R)
325 t_element_mat minLocal, min;
327 if (self.father->Size() || (n_m >= 0 && n_n >= 0))
328 minLocal.resize(self.father->MatRowSize(0), self.father->MatColSize(0));
329 else if (self.son->Size())
330 minLocal.resize(self.son->MatRowSize(0), self.son->MatColSize(0));
331 minLocal.setConstant(0);
333 index iTop = self.father->Size();
334#if defined(DNDS_DIST_MT_USE_OMP)
335# pragma omp declare reduction(EigenVecAdd:t_element_mat : omp_out += omp_in) initializer(omp_priv = omp_orig)
336# pragma omp parallel for schedule(static) reduction(EigenVecAdd : minLocal)
338 for (
index i = 0; i < iTop; i++)
339 minLocal += ((self.operator[](i) - R.operator[](i)).array().abs()).matrix();
344 template <
int n_m,
int n_n>
345 real ArrayDofOp<DeviceBackend::Host, n_m, n_n>::dot(t_self &self,
const t_self &R)
349 real sqrSum{0}, sqrSumAll;
350 index iTop = self.father->Size();
351#if defined(DNDS_DIST_MT_USE_OMP)
352# pragma omp parallel for schedule(static) reduction(+ : sqrSum)
354 for (
index i = 0; i < iTop; i++)
355 sqrSum += (self.operator[](i).array() * (R.operator[](i)).array()).sum();
Degree-of-freedom array with vector-space operations (MPI-collective).
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
Assertion / error-handling macros and supporting helper functions.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
MPI_int Allreduce(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Allreduce.
the host side operators are provided as implemented
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
const MPI_Datatype DNDS_MPI_REAL
MPI datatype matching real (= MPI_REAL8).