19#include <Kokkos_Core.hpp>
23std::vector<double> generate_random_vector(
int n,
double lower_bound,
double higher_bound)
26 assert(lower_bound < higher_bound);
28 std::random_device rd;
29 std::mt19937 gen(rd());
33 std::uniform_real_distribution<double> dis(-p, +p);
35 double const dx = (higher_bound - lower_bound) / (n - 1);
37 std::vector<double> points(n);
40 for (
int i = 0; i < n; ++i) {
41 points[i] = lower_bound + i * dx;
44 for (
int i = 1; i < n - 1; ++i) {
45 points[i] += dis(gen) * dx;
48 assert(std::is_sorted(points.begin(), points.end()));
54std::vector<double> periodic_extrapolation_left(
int gw, std::vector<double>
const& points)
57 assert(points.size() > gw);
58 assert(std::is_sorted(points.begin(), points.end()));
60 std::vector<double> ghost(gw);
62 double const period = points.back() - points.front();
63 auto const it = std::next(points.crbegin());
64 std::transform(it, std::next(it, gw), ghost.rbegin(), [period](
double pos) {
72std::vector<double> periodic_extrapolation_right(
int gw, std::vector<double>
const& points)
75 assert(points.size() > gw);
76 assert(std::is_sorted(points.begin(), points.end()));
78 std::vector<double> ghost(gw);
80 double const period = points.back() - points.front();
81 auto const it = std::next(points.cbegin());
82 std::transform(it, std::next(it, gw), ghost.begin(), [period](
double pos) {
121template <
class ChunkType>
122void display(
double time, ChunkType temp)
124 double const mean_temp
126 / temp.domain().size();
127 std::cout << std::fixed << std::setprecision(3);
128 std::cout <<
"At t = " << time <<
",\n";
129 std::cout <<
" * mean temperature = " << mean_temp <<
"\n";
134 std::cout << std::setw(6) << temp_slice(ix);
136 std::cout <<
" }\n" << std::flush;
140int main(
int argc,
char** argv)
142 Kokkos::ScopeGuard
const kokkos_scope(argc, argv);
147 double const x_start = -1.;
148 double const x_end = 1.;
149 std::size_t
const nb_x_points = 10;
150 double const kx = .01;
153 double const y_start = -1.;
154 double const y_end = 1.;
155 std::size_t
const nb_y_points = 100;
156 double const ky = .002;
159 double const start_time = 0.;
160 double const end_time = 10.;
162 std::ptrdiff_t
const t_output_period = 10;
166 std::vector<double>
const x_domain_vect = generate_random_vector(nb_x_points, x_start, x_end);
170 std::vector<double>
const x_pre_ghost_vect = periodic_extrapolation_left(1, x_domain_vect);
171 std::vector<double>
const x_post_ghost_vect = periodic_extrapolation_right(1, x_domain_vect);
175 auto const [x_domain, ghosted_x_domain, x_pre_ghost, x_post_ghost]
177 DDimX::init_ghosted<DDimX>(x_domain_vect, x_pre_ghost_vect, x_post_ghost_vect));
181 x_post_mirror(x_post_ghost.front() - x_domain.extents(), x_post_ghost.extents());
183 x_pre_mirror(x_pre_ghost.front() + x_domain.extents(), x_pre_ghost.extents());
186 std::vector<double>
const y_domain_vect = generate_random_vector(nb_y_points, y_start, y_end);
189 std::vector<double>
const y_pre_ghost_vect = periodic_extrapolation_left(1, y_domain_vect);
190 std::vector<double>
const y_post_ghost_vect = periodic_extrapolation_right(1, y_domain_vect);
195 auto const [y_domain, ghosted_y_domain, y_pre_ghost, y_post_ghost]
197 DDimY::init_ghosted<DDimY>(y_domain_vect, y_pre_ghost_vect, y_post_ghost_vect));
201 y_post_mirror(y_post_ghost.front() - y_domain.extents(), y_post_ghost.extents());
204 y_pre_mirror(y_pre_ghost.front() + y_domain.extents(), y_pre_ghost.extents());
228 std::ceil((end_time - start_time) / max_dt) + .2);
259 ghosted_initial_temp(ixy) = 9.999 * ((x * x + y * y) < 0.25);
281 time_domain.remove_first(
ddc::DiscreteVector<DDimT>(1))) {
287 ghosted_last_temp[x_pre_ghost[ix]][y_domain],
288 ghosted_last_temp[x_pre_mirror[ix]][y_domain]);
292 ghosted_last_temp[x_post_ghost[ix]][y_domain],
293 ghosted_last_temp[x_post_mirror[ix]][y_domain]);
297 ghosted_last_temp[x_domain][y_pre_ghost[iy]],
298 ghosted_last_temp[x_domain][y_pre_mirror[iy]]);
302 ghosted_last_temp[x_domain][y_post_ghost[iy]],
303 ghosted_last_temp[x_domain][y_post_mirror[iy]]);
321 double const dx_m = 0.5 * (dx_l + dx_r);
324 double const dy_m = 0.5 * (dy_l + dy_r);
325 next_temp(ix, iy) = last_temp(ix, iy);
328 * (dx_l * last_temp(ix + 1, iy) - 2.0 * dx_m * last_temp(ix, iy)
329 + dx_r * last_temp(ix - 1, iy))
330 / (dx_l * dx_m * dx_r);
333 * (dy_l * last_temp(ix, iy + 1) - 2.0 * dy_m * last_temp(ix, iy)
334 + dy_r * last_temp(ix, iy - 1))
335 / (dy_l * dy_m * dy_r);
340 if (iter - last_output_iter >= t_output_period) {
341 last_output_iter = iter;
349 std::swap(ghosted_last_temp, ghosted_next_temp);
354 if (last_output_iter < time_domain.
back()) {
KOKKOS_FUNCTION constexpr size_type size() const noexcept
KOKKOS_FUNCTION constexpr span_type span_view() const
KOKKOS_FUNCTION constexpr discrete_element_type front() const noexcept
KOKKOS_FUNCTION constexpr discrete_element_type back() const noexcept
A DiscreteElement identifies an element of the discrete dimension.
A DiscreteVector is a vector in the discrete dimension.
The top-level namespace of DDC.
auto parallel_deepcopy(ChunkDst &&dst, ChunkSrc &&src)
Copy the content of a borrowed chunk into another.
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type... > coordinate(DiscreteElement< DDim... > const &c)
void init_discrete_space(Args &&... args)
Initialize (emplace) a global singleton discrete space.
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > distance_at_left(DiscreteElement< DDim > i)
T transform_reduce(Support const &domain, T neutral, BinaryReductionOp &&reduce, UnaryTransformOp &&transform) noexcept
A reduction over a nD domain in serial.
detail::TaggedVector< CoordinateElement, CDims... > Coordinate
A Coordinate represents a coordinate in the continuous space.
std::ptrdiff_t DiscreteVectorElement
A DiscreteVectorElement is a scalar that represents the difference between two coordinates.
void parallel_for_each(std::string const &label, ExecSpace const &execution_space, Support const &domain, Functor &&f) noexcept
iterates over a nD domain using a given Kokkos execution space
void for_each(Support const &domain, Functor &&f) noexcept
iterates over a nD domain in serial
auto create_mirror(Space const &space, ChunkSpan< ElementType, Support, Layout, MemorySpace > const &src)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > distance_at_right(DiscreteElement< DDim > i)