Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
AlephIndexTest.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/* AlephIndexTest.cc (C) 2000-2015 */
9/* */
10/* Test service for the Aleph+Index service. */
11/*---------------------------------------------------------------------------*/
12
13#include "arcane/utils/ScopedPtr.h"
14
15#include "arcane/aleph/tests/AlephTest.h"
16#include "arcane/aleph/tests/AlephIndexTest.h"
17#include "arcane/aleph/tests/AlephIndexTest_axl.h"
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace ArcaneTest
23{
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28using namespace Arcane;
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33class AlephIndexTest
34: public ArcaneAlephIndexTestObject
35{
36 public:
37
38 AlephIndexTest(const ModuleBuildInfo&);
39 ~AlephIndexTest(void);
40 void init(void);
41 void compute(void);
42
43 private:
44
45 void setValues(const Real, AlephMatrix*);
46 void postSolver(const Integer, Real, Array<Real>&, Array<Integer>&);
47 static Real geoFaceSurface(Face, VariableItemReal3&);
48
49 public:
50
51 Integer m_total_nb_cell;
52 Integer m_local_nb_cell;
53 UniqueArray<Real> m_vector_zeroes;
54 AlephKernel* m_aleph_kernel;
55 UniqueArray<AlephMatrix*> m_aleph_mat;
56 UniqueArray<AlephVector*> m_aleph_rhs;
57 UniqueArray<AlephVector*> m_aleph_sol;
58 UniqueArray<AlephParams*> m_aleph_params;
59 Integer m_get_solution_idx;
60 Integer m_nb_solver;
61};
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66AlephIndexTest::
67AlephIndexTest(const ModuleBuildInfo& mbi)
69, m_total_nb_cell(0)
70, m_local_nb_cell(0)
71, m_vector_zeroes(0)
72, m_aleph_kernel(0)
73, m_get_solution_idx(0)
74, m_nb_solver(0)
75{}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80AlephIndexTest::
81~AlephIndexTest(void)
82{
83 debug() << "[AlephIndexTest::AlephIndexTest] Delete & Free";
84}
85
86/***************************************************************************
87 * AlephIndexTest::init *
88 ***************************************************************************/
90init(void)
91{
92 m_nb_solver = options()->alephNumberOfSolvers;
93
94 m_aleph_mat.resize(m_nb_solver);
95 m_aleph_rhs.resize(m_nb_solver);
96 m_aleph_sol.resize(m_nb_solver);
97 m_aleph_params.resize(m_nb_solver);
98
99 // Set our time step
100 m_global_deltat = 1.0;
101
102 // initialization of temperature on all cells and faces
103 m_cell_temperature.fill(options()->initTemperature());
104 m_face_temperature.fill(options()->initTemperature());
105
106 // initialization of boundary temperature, loop over boundary conditions
107 for (int i = options()->boundaryCondition.size() - 1; i >= 0; --i) {
108 Real temperature = options()->boundaryCondition[i]->value();
109 FaceGroup face_group = options()->boundaryCondition[i]->surface();
110 // loop over faces of the surface
111 ENUMERATE_FACE (iFace, face_group)
112 m_face_temperature[iFace] = temperature;
113 }
114 mesh()->checkValidMeshFull();
115
116 // We instantiate a minimalistic kernel that will handle the initialization for us
117 // AlephKernel(subDomain(),0,0); seems to cause issues, but 2,0, or 0,1 do not:
118 // pre-kernel topology initialization problem?
119 // The value 2 corresponds to the Kernel for Hypre.
120 m_aleph_kernel = new AlephKernel(subDomain(), 2, 1);
121
122 // Another initialization of vector indices
123 ENUMERATE_CELL (cell, ownCells()) {
124 m_vector_zeroes.add(0.0);
125 }
126}
127
128/***************************************************************************
129 * Entry points leads us here
130 ***************************************************************************/
131void AlephIndexTest::
132compute(void)
133{
136 Integer nb_iteration;
137 Real residual_norm[4];
138
139 if (m_nb_solver == 0) {
141 return;
142 }
143
144 indexs.resize(m_nb_solver);
145 values.resize(m_nb_solver);
146 for (int i = 0; i < m_nb_solver; ++i)
147 postSolver(i, options()->deltaT, values[i], indexs[i]);
148
149 // And should be able to get the solutions after the last resolution was fired
150 for (int i = m_nb_solver - 1; i >= 0; --i) {
151 debug() << "[AlephIndexTest::compute] Getting solution #" << i;
152 AlephVector* solution = m_aleph_kernel->syncSolver(i, nb_iteration, &residual_norm[0]);
153 if (i != m_get_solution_idx)
154 continue;
155 debug() << "Solved in \33[7m" << nb_iteration << "\33[m iterations,"
156 << "residuals=[\33[1m" << residual_norm[0] << "\33[m," << residual_norm[3] << "]";
157 debug() << "[AlephIndexTest::compute] Applying solution #" << m_get_solution_idx;
158 solution->getLocalComponents(values[i]);
159 m_get_solution_idx += 1;
160 }
161 m_get_solution_idx %= m_nb_solver;
162
163 // Otherwise, we copy the results
164 debug() << "[AlephIndexTest::compute] Now get our results";
165 ENUMERATE_CELL (cell, ownCells())
166 m_cell_temperature[cell] = values[m_get_solution_idx][m_aleph_kernel->indexing()->get(m_cell_temperature, *cell)];
167
168 // If we have reached our maximum number of iterations, we exit
169 if (subDomain()->commonVariables().globalIteration() >= options()->iterations)
170 subDomain()->timeLoopMng()->stopComputeLoop(true);
171
172 debug() << "[AlephIndexTest::compute] done";
173}
174
175/***************************************************************************
176 * job
177 ***************************************************************************/
178void AlephIndexTest::
179postSolver(const Integer i, Real optionDeltaT,
180 Array<Real>& values,
181 Array<Integer>& indexs)
182{
183 // We force the deltaTs to be different to have calculation times that can be scheduled
184 Real deltaT = (1.0 + (Real)i) * optionDeltaT;
185 Integer fake_nb_iteration = 0;
186 Real fake_residual_norm[4];
187
188 m_aleph_params[i] = new AlephParams(traceMng(),
189 1.0e-10, // m_param_epsilon convergence epsilon
190 2000, // m_param_max_iteration max iterations
191 TypesSolver::AMG, // m_param_preconditioner_method preconditioning: DIAGONAL, AMG, IC
192 TypesSolver::PCG, // m_param_solver_method solving method
193 -1, // m_param_gamma
194 -1.0, // m_param_alpha
195 false, // m_param_xo_user by default Xo is not equal to 0
196 false, // m_param_check_real_residue
197 false, // m_param_print_real_residue
198 false, // m_param_debug_info
199 1.e-40, // m_param_min_rhs_norm
200 false, // m_param_convergence_analyse
201 true, // m_param_stop_error_strategy
202 false, // m_param_write_matrix_to_file_error_strategy
203 "SolveErrorAlephMatrix.dbg", // m_param_write_matrix_name_error_strategy
204 false, // m_param_listing_output
205 0., // m_param_threshold
206 false, // m_param_print_cpu_time_resolution
207 0, // m_param_amg_coarsening_method: by default Sloop's,
208 0, // m_param_output_level
209 1, // m_param_amg_cycle: 1-cycle amg in V, 2= amg cycle in W, 3=cycle in Full Multigrid V
210 1, // m_param_amg_solver_iterations
211 1, // m_param_amg_smoother_iterations
212 TypesSolver::SymHybGSJ_smoother, // m_param_amg_smootherOption
213 TypesSolver::ParallelRugeStuben, // m_param_amg_coarseningOption
214 TypesSolver::CG_coarse_solver, // m_param_amg_coarseSolverOption
215 false, // m_param_keep_solver_structure
216 false, // m_param_sequential_solver
217 TypesSolver::RB); // m_param_criteria_stop
218
219 // Filling the right-hand side: boundary conditions + right-hand side
220 debug() << "[AlephIndexTest::compute] Resize (" << m_vector_zeroes.size() << ") + filling the right-hand side";
221 values.resize(m_vector_zeroes.size());
222 indexs.resize(m_vector_zeroes.size());
223 ENUMERATE_CELL (cell, ownCells()) {
224 Integer row = m_aleph_kernel->indexing()->get(m_cell_temperature, cell);
225 indexs[row] = row;
226 values[row] = m_cell_temperature[cell];
227 }
228
229 debug() << "[AlephIndexTest::compute] ENUMERATE_FACE";
230 ENUMERATE_FACE (iFace, allCells().outerFaceGroup()) {
231 if (!iFace->cell(0).isOwn())
232 continue;
233 values[m_aleph_kernel->indexing()->get(m_cell_temperature, iFace->cell(0))] +=
234 deltaT * (m_face_temperature[iFace]) / geoFaceSurface(*iFace, nodesCoordinates());
235 }
236
237 // Creation of the MatVec matrix and Aleph requirements
238 m_aleph_mat[i] = m_aleph_kernel->createSolverMatrix();
239 m_aleph_rhs[i] = m_aleph_kernel->createSolverVector(); // First vector returned IS the rhs
240 m_aleph_sol[i] = m_aleph_kernel->createSolverVector(); // Next one IS the solution
241
242 m_aleph_mat[i]->create();
243 m_aleph_rhs[i]->create();
244 m_aleph_sol[i]->create();
245 m_aleph_mat[i]->reset();
246
247 // Filling the matrix and assembly
248 setValues(deltaT, m_aleph_mat[i]);
249 m_aleph_mat[i]->assemble();
250
251 debug() << "[AlephIndexTest::job] setLocalComponents";
252 //m_aleph_rhs[i]->setLocalComponents(indexs.size(), indexs.view(), values.view());
253 m_aleph_rhs[i]->setLocalComponents(values.view());
254 m_aleph_rhs[i]->assemble();
255
256 //m_aleph_sol[i]->setLocalComponents(indexs.size(), indexs.view(), m_vector_zeroes.view());
257 m_aleph_sol[i]->setLocalComponents(m_vector_zeroes.view());
258 m_aleph_sol[i]->assemble();
259 debug() << "[AlephIndexTest::job] done setLocalComponents";
260 traceMng()->flush();
261
262 // Now solve with Aleph
263 debug() << "[AlephIndexTest::job] Now solve with Aleph";
264 m_aleph_mat[i]->solve(m_aleph_sol[i],
265 m_aleph_rhs[i],
266 fake_nb_iteration,
267 &fake_residual_norm[0],
268 m_aleph_params[i],
269 true); // We wish to post asynchronously
270 debug() << "[AlephIndexTest::job] done with Aleph solve";
271 traceMng()->flush();
272}
273
274/***************************************************************************
275 * AlephTestModule::_FaceComputeSetValues *
276 ***************************************************************************/
277void AlephIndexTest::setValues(const Real deltaT, AlephMatrix* aleph_mat)
278{
279 // Flush the coefficients
280 ENUMERATE_CELL (iCell, ownCells())
281 m_cell_coefs[iCell] = 0.;
282 // 'inner' faces
283 debug() << "[AlephIndexTest::setValues] inner-faces";
284 ENUMERATE_FACE (iFace, allCells().innerFaceGroup()) {
285 if (iFace->backCell().isOwn()) {
286 const Real surface = geoFaceSurface(*iFace, nodesCoordinates());
287 aleph_mat->setValue(m_cell_temperature, iFace->backCell(),
288 m_cell_temperature, iFace->frontCell(),
289 -deltaT / surface);
290 m_cell_coefs[iFace->backCell()] += 1.0 / surface;
291 }
292 if (iFace->frontCell().isOwn()) {
293 const Real surface = geoFaceSurface(*iFace, nodesCoordinates());
294 aleph_mat->setValue(m_cell_temperature, iFace->frontCell(),
295 m_cell_temperature, iFace->backCell(),
296 -deltaT / surface);
297 m_cell_coefs[iFace->frontCell()] += 1.0 / surface;
298 }
299 }
300 debug() << "[AlephIndexTest::setValues] outer-faces";
301 ENUMERATE_FACE (iFace, allCells().outerFaceGroup()) {
302 if (!iFace->cell(0).isOwn())
303 continue;
304 m_cell_coefs[iFace->cell(0)] += 1.0 / geoFaceSurface(*iFace, nodesCoordinates());
305 }
306 debug() << "[AlephIndexTest::setValues] diagonal";
307 ENUMERATE_CELL (cell, ownCells()) {
308 aleph_mat->setValue(m_cell_temperature, cell,
309 m_cell_temperature, cell,
310 1.0 + deltaT * m_cell_coefs[cell]);
311 }
312 debug() << "[AlephIndexTest::setValues] done";
313}
314
315/***************************************************************************
316 * geoFaceSurface
317 ***************************************************************************/
318Real AlephIndexTest::geoFaceSurface(Face face, VariableItemReal3& nodes_coords)
319{
320 if (face.nbNode() == 4) {
321 const Real3 xyz0 = nodes_coords[face.node(0)];
322 const Real3 xyz1 = nodes_coords[face.node(1)];
323 const Real3 xyz3 = nodes_coords[face.node(3)];
324 return (xyz0 - xyz1).normL2() * (xyz0 - xyz3).normL2();
325 }
326 if (face.nbNode() == 2) {
327 const Real3 xyz0 = nodes_coords[face.node(0)];
328 const Real3 xyz1 = nodes_coords[face.node(1)];
329 return (xyz0 - xyz1).normL2();
330 }
331 throw FatalErrorException("geoFace", "Nb nodes != 4 !=2");
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
337ARCANE_DEFINE_STANDARD_MODULE(AlephIndexTest, AlephIndexTest);
338
339/*---------------------------------------------------------------------------*/
340/*---------------------------------------------------------------------------*/
341
342} // namespace ArcaneTest
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
#define ENUMERATE_FACE(name, group)
Generic enumerator for a face group.
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
void init(void)
points d'entrée
Generation de la classe de base du Module.
CaseOptionsAlephIndexTest * options() const
Options du jeu de données du module.
Arcane::VariableCellReal m_cell_temperature
Variables du module.
ITraceMng * traceMng() const override
Trace manager.
ISubDomain * subDomain() const override
Sub-domain associated with the module.
AlephVector * syncSolver(Integer, Integer &, Real *)
Matrix of a linear system.
Definition AlephMatrix.h:33
void setValue(const VariableRef &, const Item &, const VariableRef &, const Item &, const Real)
setValue from arguments in IVariables, Items, and Real
Vector of a linear system.
Definition AlephVector.h:33
Base class for 1D data vectors.
void resize(Int64 s)
Changes the number of elements in the array to s.
Int32 globalIteration() const
Current iteration number.
VariableScalarReal m_global_deltat
Global Delta T.
Face of a cell.
Definition Item.h:1032
virtual ITimeLoopMng * timeLoopMng()=0
Returns the time loop manager.
virtual void stopComputeLoop(bool is_final_time, bool has_error=false)=0
Indicates that the compute loop must stop.
virtual void flush()=0
Flushes all streams.
Node node(Int32 i) const
i-th node of the entity
Definition Item.h:840
Int32 nbNode() const
Number of nodes of the entity.
Definition Item.h:837
CellGroup allCells() const
Returns the group containing all cells.
CellGroup ownCells() const
Returns the group containing all cells specific to this domain.
VariableNodeReal3 & nodesCoordinates() const
Returns the coordinates of the mesh nodes.
Information for building a module.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
1D data vector with value semantics (STL style).
ItemGroupT< Face > FaceGroup
Group of faces.
Definition ItemTypes.h:179
ItemVariableScalarRefT< Real3 > VariableItemReal3
3D coordinate type quantity
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.