Arcane  4.2.1.0
Developer documentation
Loading...
Searching...
No Matches
DistributedComplex.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/*---------------------------------------------------------------------------*/
9/*
10 * This file is based on the work on AMGCL library (version march 2026)
11 * which can be found at https://github.com/ddemidov/amgcl.
12 *
13 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
14 * SPDX-License-Identifier: MIT
15 */
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19#include <iostream>
20#include <vector>
21#include <string>
22#include <complex>
23
24#include "arccore/alina/BuiltinBackend.h"
25#include "arccore/alina/ValueTypeComplex.h"
26#include "arccore/alina/Adapters.h"
27
28#include "arccore/alina/DistributedPreconditionedSolver.h"
29#include "arccore/alina/DistributedPreconditioner.h"
30#include "arccore/alina/DistributedSolverRuntime.h"
31
32#include "arccore/alina/IO.h"
33#include "arccore/alina/Profiler.h"
34
35#include "arccore/common/internal/ProgramOptions.h"
36
37using namespace Arcane;
38using namespace Arcane::Alina;
39
40//---------------------------------------------------------------------------
41ptrdiff_t
42assemble_poisson3d(Alina::mpi_communicator comm,
43 ptrdiff_t n, int block_size,
44 std::vector<ptrdiff_t>& ptr,
45 std::vector<ptrdiff_t>& col,
46 std::vector<std::complex<double>>& val,
47 std::vector<std::complex<double>>& rhs)
48{
49 ptrdiff_t n3 = n * n * n;
50
51 ptrdiff_t chunk = (n3 + comm.size - 1) / comm.size;
52 if (chunk % block_size != 0) {
53 chunk += block_size - chunk % block_size;
54 }
55 ptrdiff_t row_beg = std::min(n3, chunk * comm.rank);
56 ptrdiff_t row_end = std::min(n3, row_beg + chunk);
57 chunk = row_end - row_beg;
58
59 ptr.clear();
60 ptr.reserve(chunk + 1);
61 col.clear();
62 col.reserve(chunk * 7);
63 val.clear();
64 val.reserve(chunk * 7);
65
66 rhs.resize(chunk);
67 std::fill(rhs.begin(), rhs.end(), 1.0);
68
69 const double h2i = (n - 1) * (n - 1);
70 ptr.push_back(0);
71
72 for (ptrdiff_t idx = row_beg; idx < row_end; ++idx) {
73 ptrdiff_t k = idx / (n * n);
74 ptrdiff_t j = (idx / n) % n;
75 ptrdiff_t i = idx % n;
76
77 if (k > 0) {
78 col.push_back(idx - n * n);
79 val.push_back(-h2i);
80 }
81
82 if (j > 0) {
83 col.push_back(idx - n);
84 val.push_back(-h2i);
85 }
86
87 if (i > 0) {
88 col.push_back(idx - 1);
89 val.push_back(-h2i);
90 }
91
92 col.push_back(idx);
93 val.push_back(6 * h2i);
94
95 if (i + 1 < n) {
96 col.push_back(idx + 1);
97 val.push_back(-h2i);
98 }
99
100 if (j + 1 < n) {
101 col.push_back(idx + n);
102 val.push_back(-h2i);
103 }
104
105 if (k + 1 < n) {
106 col.push_back(idx + n * n);
107 val.push_back(-h2i);
108 }
109
110 ptr.push_back(col.size());
111 }
112
113 return chunk;
114}
115
116//---------------------------------------------------------------------------
117void solve_scalar(Alina::mpi_communicator comm,
118 ptrdiff_t chunk,
119 const std::vector<ptrdiff_t>& ptr,
120 const std::vector<ptrdiff_t>& col,
121 const std::vector<std::complex<double>>& val,
122 const Alina::PropertyTree& prm,
123 const std::vector<std::complex<double>>& rhs)
124{
125 auto& prof = Alina::Profiler::globalProfiler();
127
130
131 prof.tic("setup");
132 Solver solve(comm, std::tie(chunk, ptr, col, val), prm);
133 prof.toc("setup");
134
135 if (comm.rank == 0) {
136 std::cout << solve << std::endl;
137 }
138
139 std::vector<std::complex<double>> x(chunk);
140
141 prof.tic("solve");
142 Alina::SolverResult r = solve(rhs, x);
143 prof.toc("solve");
144
145 if (comm.rank == 0) {
146 std::cout << "Iterations: " << r.nbIteration() << std::endl
147 << "Error: " << r.residual() << std::endl
148 << prof << std::endl;
149 }
150}
151
152//---------------------------------------------------------------------------
153int main(int argc, char* argv[])
154{
155 auto& prof = Alina::Profiler::globalProfiler();
156 Alina::mpi_init_thread mpi(&argc, &argv);
157 Alina::mpi_communicator comm(MPI_COMM_WORLD);
158
159 if (comm.rank == 0)
160 std::cout << "World size: " << comm.size << std::endl;
161
162 // Read configuration from command line
163 namespace po = Arcane::ProgramOptions;
164 po::options_description desc("Options");
165
166 desc.add_options()("help,h", "show help")(
167 "size,n",
168 po::value<ptrdiff_t>()->default_value(128),
169 "domain size")("prm-file,P",
170 po::value<std::string>(),
171 "Parameter file in json format. ")(
172 "prm,p",
173 po::value<std::vector<std::string>>()->multitoken(),
174 "Parameters specified as name=value pairs. "
175 "May be provided multiple times. Examples:\n"
176 " -p solver.tol=1e-3\n"
177 " -p precond.coarse_enough=300");
178
180 p.add("prm", -1);
181
183 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
184 po::notify(vm);
185
186 if (vm.count("help")) {
187 if (comm.rank == 0)
188 std::cout << desc << std::endl;
189 return 0;
190 }
191
193 if (vm.count("prm-file")) {
194 prm.read_json(vm["prm-file"].as<std::string>());
195 }
196
197 if (vm.count("prm")) {
198 for (const std::string& v : vm["prm"].as<std::vector<std::string>>()) {
199 prm.putKeyValue(v);
200 }
201 }
202
203 ptrdiff_t n;
204 std::vector<ptrdiff_t> ptr;
205 std::vector<ptrdiff_t> col;
206 std::vector<std::complex<double>> val;
207 std::vector<std::complex<double>> rhs;
208
209 prof.tic("assemble");
210 n = assemble_poisson3d(comm, vm["size"].as<ptrdiff_t>(), 1, ptr, col, val, rhs);
211 prof.toc("assemble");
212
213 solve_scalar(comm, n, ptr, col, val, prm, rhs);
214}
Iterative solver wrapper for distributed linear systems.
Result of a solution.
Definition AlinaUtils.h:53
Fluent command-line parser builder.
Describes a set of command-line options.
Describes positional (non-option) arguments.
Stores parsed option values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Convenience wrapper around MPI_Comm.
Convenience wrapper around MPI_Init_threads/MPI_Finalize.