21 #ifndef THUNDEREGG_VECTOR_H
22 #define THUNDEREGG_VECTOR_H
53 std::vector<double*> patch_starts;
58 std::array<int, D + 1> strides;
62 std::array<int, D + 1> lengths;
67 int num_ghost_cells = 0;
72 std::vector<double> data;
78 int num_local_cells = 0;
83 void determineStrides()
86 for (
int i = 0; i < D; i++) {
87 strides[i] = curr_stride;
88 curr_stride *= lengths[i] + 2 * num_ghost_cells;
90 strides[D] = curr_stride;
98 void allocateData(
int num_local_patches)
100 int patch_stride = strides[D] * lengths[D];
101 data.resize(patch_stride * num_local_patches);
102 patch_starts.resize(num_local_patches);
103 for (
int i = 0; i < num_local_patches; i++) {
104 patch_starts[i] = data.data() + i * patch_stride;
126 const std::array<int, D>& ns,
128 int num_local_patches,
131 , num_ghost_cells(num_ghost_cells)
133 for (
int i = 0; i < D; i++) {
136 lengths[D] = num_components;
139 for (
int i = 0; i < D; i++) {
141 size *= lengths[i] + 2 * num_ghost_cells;
142 num_local_cells *= lengths[i];
146 int patch_stride = size;
147 size *= num_local_patches;
148 num_local_cells *= num_local_patches;
150 patch_starts.resize(num_local_patches);
151 for (
int i = 0; i < num_local_patches; i++) {
152 patch_starts[i] = data.data() + i * patch_stride;
166 const std::array<int, D>& ns = domain.
getNs();
168 for (
int i = 0; i < D; i++) {
171 lengths[D] = num_components;
174 for (
int i = 0; i < D; i++) {
176 size *= lengths[i] + 2 * num_ghost_cells;
177 num_local_cells *= lengths[i];
181 int patch_stride = size;
182 size *= num_local_patches;
183 num_local_cells *= num_local_patches;
185 patch_starts.resize(num_local_patches);
186 for (
int i = 0; i < num_local_patches; i++) {
187 patch_starts[i] = data.data() + i * patch_stride;
200 const std::vector<double*>& patch_starts,
201 const std::array<int, D + 1>& strides,
202 const std::array<int, D + 1>& lengths,
205 , patch_starts(patch_starts)
208 , num_ghost_cells(num_ghost_cells)
211 for (
int i = 0; i < D; i++) {
212 num_local_cells *= lengths[i];
214 num_local_cells *= patch_starts.size();
225 , lengths(other.lengths)
226 , num_ghost_cells(other.num_ghost_cells)
227 , num_local_cells(other.num_local_cells)
229 if (other.data.empty()) {
234 strides = other.strides;
237 patch_starts.resize(other.patch_starts.size());
238 for (
int i = 0; i < patch_starts.size(); i++) {
239 patch_starts[i] = data.data() + i * patch_stride;
254 lengths = other.lengths;
255 num_ghost_cells = other.num_ghost_cells;
256 num_local_cells = other.num_local_cells;
257 if (other.data.empty()) {
262 strides = other.strides;
265 patch_starts.resize(other.patch_starts.size());
266 for (
int i = 0; i < patch_starts.size(); i++) {
267 patch_starts[i] = data.data() + i * patch_stride;
279 , patch_starts(std::exchange(other.patch_starts, std::vector<double*>()))
280 , num_ghost_cells(std::exchange(other.num_ghost_cells, 0))
281 , data(std::exchange(other.data, std::vector<double>()))
282 , num_local_cells(std::exchange(other.num_local_cells, 0))
285 std::swap(lengths, other.lengths);
287 std::swap(strides, other.strides);
297 std::swap(comm, other.comm);
298 std::swap(lengths, other.lengths);
299 std::swap(num_ghost_cells, other.num_ghost_cells);
300 std::swap(num_local_cells, other.num_local_cells);
301 std::swap(strides, other.strides);
302 std::swap(data, other.data);
303 std::swap(patch_starts, other.patch_starts);
312 int getNumComponents()
const {
return lengths[D]; }
338 return getPatchView(patch_local_index).getComponentView(component_index);
349 return getPatchView(patch_local_index).getComponentView(component_index);
360 if constexpr (ENABLE_DEBUG) {
365 return PatchView<double, D>(patch_starts[patch_local_index], strides, lengths, num_ghost_cells);
377 if constexpr (ENABLE_DEBUG) {
383 patch_starts[patch_local_index], strides, lengths, num_ghost_cells);
395 Loop::OverInteriorIndexes<D + 1>(
396 view, [&](
const std::array<int, D + 1>& coord) { view[coord] = alpha; });
408 Loop::OverAllIndexes<D + 1>(
409 view, [&](
const std::array<int, D + 1>& coord) { view[coord] = alpha; });
421 Loop::OverInteriorIndexes<D + 1>(
422 view, [&](
const std::array<int, D + 1>& coord) { view[coord] *= alpha; });
434 Loop::OverInteriorIndexes<D + 1>(
435 view, [&](
const std::array<int, D + 1>& coord) { view[coord] += delta; });
448 Loop::OverInteriorIndexes<D + 1>(
449 view, [&](
const std::array<int, D + 1>& coord) { view[coord] = b_view[coord]; });
462 Loop::OverAllIndexes<D + 1>(
463 view, [&](
const std::array<int, D + 1>& coord) { view[coord] = b_view[coord]; });
476 Loop::OverInteriorIndexes<D + 1>(
477 view, [&](
const std::array<int, D + 1>& coord) { view[coord] += b_view[coord]; });
488 Loop::OverInteriorIndexes<D + 1>(
489 view, [&](
const std::array<int, D + 1>& coord) { view[coord] += b_view[coord] * alpha; });
501 Loop::OverInteriorIndexes<D + 1>(view, [&](
const std::array<int, D + 1>& coord) {
502 view[coord] += a_view[coord] * alpha + b_view[coord] * beta;
514 Loop::OverInteriorIndexes<D + 1>(view, [&](
const std::array<int, D + 1>& coord) {
515 view[coord] = view[coord] * alpha + b_view[coord];
527 Loop::OverInteriorIndexes<D + 1>(view, [&](
const std::array<int, D + 1>& coord) {
528 view[coord] = view[coord] * alpha + b_view[coord] * beta;
545 Loop::OverInteriorIndexes<D + 1>(view, [&](
const std::array<int, D + 1>& coord) {
546 view[coord] = view[coord] * alpha + b_view[coord] * beta + c_view[coord] * gamma;
558 Loop::OverInteriorIndexes<D + 1>(
559 view, [&](
const std::array<int, D + 1>& coord) { sum += view[coord] * view[coord]; });
562 MPI_Allreduce(&sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, comm.
getMPIComm());
563 return sqrt(global_sum);
573 Loop::OverInteriorIndexes<D + 1>(
574 view, [&](
const std::array<int, D + 1>& coord) { max = fmax(view[coord], max); });
577 MPI_Allreduce(&max, &global_max, 1, MPI_DOUBLE, MPI_MAX, comm.
getMPIComm());
589 Loop::OverInteriorIndexes<D + 1>(
590 view, [&](
const std::array<int, D + 1>& coord) { retval += view[coord] * b_view[coord]; });
592 double global_retval;
593 MPI_Allreduce(&retval, &global_retval, 1, MPI_DOUBLE, MPI_SUM, comm.
getMPIComm());
594 return global_retval;
605 clone.lengths = lengths;
606 clone.num_ghost_cells = num_ghost_cells;
607 clone.num_local_cells = num_local_cells;
608 clone.determineStrides();
613 extern template class Vector<1>;
614 extern template class Vector<2>;
615 extern template class Vector<3>;