DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
mark.h
1// Copyright (C) 2026 Paul T. Kühner and Jack S. Hale
2//
3// This file is part of DOLFINX (https://www.fenicsproject.org)
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6
7#pragma once
8
9#include <algorithm>
10#include <concepts>
11#include <cstdint>
12#include <dolfinx/common/IndexMap.h>
13#include <dolfinx/common/MPI.h>
14#include <dolfinx/la/Vector.h>
15#include <format>
16#include <limits>
17#include <mpi.h>
18#include <numeric>
19#include <span>
20#include <spdlog/spdlog.h>
21#include <stdexcept>
22#include <type_traits>
23#include <vector>
24
25namespace dolfinx::refinement
26{
27
53template <std::floating_point T>
54std::vector<std::int32_t> mark_maximum(std::span<const T> values,
55 const common::IndexMap& index_map,
56 std::type_identity_t<T> theta)
57{
58 if ((theta <= 0) or (theta > 1))
59 {
60 throw std::invalid_argument(
61 std::format("theta must satisfy 0 < theta <= 1, got {}.", theta));
62 }
63
64 std::int32_t n = values.size();
65 std::int32_t size = index_map.size_local() + index_map.num_ghosts();
66 if (n != size)
67 {
68 throw std::invalid_argument(
69 std::format("values must have size index_map.size_local() + "
70 "index_map.num_ghosts() = {}, got {}.",
71 size, n));
72 }
73
74 T local_max = index_map.size_local() == 0
75 ? std::numeric_limits<T>::lowest()
76 : std::ranges::max(values.first(index_map.size_local()));
77
78 T max = 0;
79 MPI_Allreduce(&local_max, &max, 1, dolfinx::MPI::mpi_t<T>, MPI_MAX,
80 index_map.comm());
81
82 T threshold = theta * max;
83
84 auto mark = [threshold](T e) { return e > threshold; };
85
86 std::vector<std::int32_t> indices;
87 indices.reserve(std::ranges::count_if(values, mark));
88 for (std::int32_t i = 0; i < n; ++i)
89 {
90 if (mark(values[i]))
91 indices.push_back(i);
92 }
93
94 spdlog::info("Marking (maximum): marked {} of {} local entries (owned + "
95 "ghost).",
96 indices.size(), n);
97
98 return indices;
99}
100
130template <std::floating_point T>
131std::vector<std::int32_t>
132mark_equidistribution(std::span<const T> values,
133 const common::IndexMap& index_map,
134 std::type_identity_t<T> theta)
135{
136 if ((theta <= 0) or (theta > 1))
137 {
138 throw std::invalid_argument(
139 std::format("theta must satisfy 0 < theta <= 1, got {}.", theta));
140 }
141
142 std::int32_t n = values.size();
143 std::int32_t size = index_map.size_local() + index_map.num_ghosts();
144 if (n != size)
145 {
146 throw std::invalid_argument(
147 std::format("values must have size index_map.size_local() + "
148 "index_map.num_ghosts() = {}, got {}.",
149 size, n));
150 }
151
152 auto owned = values.first(index_map.size_local());
153 T local_squared_norm = std::accumulate(owned.begin(), owned.end(), T{0});
154
155 T squared_norm;
156 MPI_Allreduce(&local_squared_norm, &squared_norm, 1, dolfinx::MPI::mpi_t<T>,
157 MPI_SUM, index_map.comm());
158
159 T threshold
160 = theta * theta * squared_norm / static_cast<T>(index_map.size_global());
161
162 auto mark = [threshold](T e) { return e > threshold; };
163
164 std::vector<std::int32_t> indices;
165 indices.reserve(std::ranges::count_if(values, mark));
166 for (std::int32_t i = 0; i < n; ++i)
167 {
168 if (mark(values[i]))
169 indices.push_back(i);
170 }
171
172 spdlog::info(
173 "Marking (equidistribution): marked {} of {} local entries (owned + "
174 "ghost).",
175 indices.size(), n);
176
177 return indices;
178}
179
180} // namespace dolfinx::refinement
Distribution of a global index range [0, N) across MPI ranks.
Definition IndexMap.h:114
std::int32_t num_ghosts() const noexcept
Return the number of ghost indices.
Definition IndexMap.cpp:1040
std::int32_t size_local() const noexcept
Return the number of owned indices.
Definition IndexMap.cpp:1045
std::int64_t size_global() const noexcept
Return the total number of indices across the communicator.
Definition IndexMap.cpp:1050
MPI_Comm comm() const
Return the communicator that the map is defined on.
Definition IndexMap.cpp:1134
MPI_Datatype mpi_t
Retrieves the MPI data type associated to the provided type.
Definition MPI.h:326
Mesh refinement algorithms.
Definition dolfinx_refinement.h:8
std::vector< std::int32_t > mark_equidistribution(std::span< const T > values, const common::IndexMap &index_map, std::type_identity_t< T > theta)
Return local indices of a set of values whose entry exceeds a fraction of the mean square (MS).
Definition mark.h:132
std::vector< std::int32_t > mark_maximum(std::span< const T > values, const common::IndexMap &index_map, std::type_identity_t< T > theta)
Return local indices of a set of values whose entry exceeds a fraction of the global maximum value.
Definition mark.h:54