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/common/log.h>
15#include <format>
16#include <limits>
17#include <mpi.h>
18#include <numeric>
19#include <span>
20#include <stdexcept>
21#include <type_traits>
22#include <vector>
23
24namespace dolfinx::refinement
25{
26
52template <std::floating_point T>
53std::vector<std::int32_t> mark_maximum(std::span<const T> values,
54 const common::IndexMap& index_map,
55 std::type_identity_t<T> theta)
56{
57 if ((theta <= 0) or (theta > 1))
58 {
59 throw std::invalid_argument(
60 std::format("theta must satisfy 0 < theta <= 1, got {}.", theta));
61 }
62
63 std::int32_t n = values.size();
64 std::int32_t size = index_map.size_local() + index_map.num_ghosts();
65 if (n != size)
66 {
67 throw std::invalid_argument(
68 std::format("values must have size index_map.size_local() + "
69 "index_map.num_ghosts() = {}, got {}.",
70 size, n));
71 }
72
73 T local_max = index_map.size_local() == 0
74 ? std::numeric_limits<T>::lowest()
75 : std::ranges::max(values.first(index_map.size_local()));
76
77 T max = 0;
78 MPI_Allreduce(&local_max, &max, 1, dolfinx::MPI::mpi_t<T>, MPI_MAX,
79 index_map.comm());
80
81 T threshold = theta * max;
82
83 auto mark = [threshold](T e) { return e > threshold; };
84
85 std::vector<std::int32_t> indices;
86 indices.reserve(std::ranges::count_if(values, mark));
87 for (std::int32_t i = 0; i < n; ++i)
88 {
89 if (mark(values[i]))
90 indices.push_back(i);
91 }
92
93 logger().info("Marking (maximum): marked {} of {} local entries (owned + "
94 "ghost).",
95 indices.size(), n);
96
97 return indices;
98}
99
129template <std::floating_point T>
130std::vector<std::int32_t>
131mark_equidistribution(std::span<const T> values,
132 const common::IndexMap& index_map,
133 std::type_identity_t<T> theta)
134{
135 if ((theta <= 0) or (theta > 1))
136 {
137 throw std::invalid_argument(
138 std::format("theta must satisfy 0 < theta <= 1, got {}.", theta));
139 }
140
141 std::int32_t n = values.size();
142 std::int32_t size = index_map.size_local() + index_map.num_ghosts();
143 if (n != size)
144 {
145 throw std::invalid_argument(
146 std::format("values must have size index_map.size_local() + "
147 "index_map.num_ghosts() = {}, got {}.",
148 size, n));
149 }
150
151 auto owned = values.first(index_map.size_local());
152 T local_squared_norm = std::accumulate(owned.begin(), owned.end(), T{0});
153
154 T squared_norm;
155 MPI_Allreduce(&local_squared_norm, &squared_norm, 1, dolfinx::MPI::mpi_t<T>,
156 MPI_SUM, index_map.comm());
157
158 T threshold
159 = theta * theta * squared_norm / static_cast<T>(index_map.size_global());
160
161 auto mark = [threshold](T e) { return e > threshold; };
162
163 std::vector<std::int32_t> indices;
164 indices.reserve(std::ranges::count_if(values, mark));
165 for (std::int32_t i = 0; i < n; ++i)
166 {
167 if (mark(values[i]))
168 indices.push_back(i);
169 }
170
171 logger().info(
172 "Marking (equidistribution): marked {} of {} local entries (owned + "
173 "ghost).",
174 indices.size(), n);
175
176 return indices;
177}
178
179} // namespace dolfinx::refinement
Distribution of a global index range [0, N) across MPI ranks.
Definition IndexMap.h:191
std::int32_t num_ghosts() const noexcept
Return the number of ghost indices.
Definition IndexMap.cpp:1076
std::int32_t size_local() const noexcept
Return the number of owned indices.
Definition IndexMap.cpp:1081
std::int64_t size_global() const noexcept
Return the total number of indices across the communicator.
Definition IndexMap.cpp:1086
MPI_Comm comm() const
Return the communicator that the map is defined on.
Definition IndexMap.cpp:1170
MPI_Datatype mpi_t
Retrieves the MPI data type associated to the provided type.
Definition MPI.h:328
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:131
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:53
auto logger() -> spdlog::logger &
Dolfinx's logger.
Definition log.cpp:24