Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AlephIndexTest.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* Service du test du service Aleph+Index. */
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
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27using namespace Arcane;
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
33: public ArcaneAlephIndexTestObject
34{
35 public:
37 ~AlephIndexTest(void);
38 void init(void);
39 void compute(void);
40
41 private:
42 void setValues(const Real, AlephMatrix*);
43 void postSolver(const Integer, Real, Array<Real>&, Array<Integer>&);
44 static Real geoFaceSurface(Face, VariableItemReal3&);
45
46 public:
47 Integer m_total_nb_cell;
48 Integer m_local_nb_cell;
49 UniqueArray<Real> m_vector_zeroes;
50 AlephKernel* m_aleph_kernel;
51 UniqueArray<AlephMatrix*> m_aleph_mat;
52 UniqueArray<AlephVector*> m_aleph_rhs;
53 UniqueArray<AlephVector*> m_aleph_sol;
54 UniqueArray<AlephParams*> m_aleph_params;
55 Integer m_get_solution_idx;
56 Integer m_nb_solver;
57};
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62AlephIndexTest::
63AlephIndexTest(const ModuleBuildInfo& mbi)
64: ArcaneAlephIndexTestObject(mbi)
65, m_total_nb_cell(0)
66, m_local_nb_cell(0)
67, m_vector_zeroes(0)
68, m_aleph_kernel(0)
69, m_get_solution_idx(0)
70, m_nb_solver(0)
71{}
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76AlephIndexTest::
77~AlephIndexTest(void)
78{
79 debug() << "[AlephIndexTest::AlephIndexTest] Delete & Free";
80}
81
82/***************************************************************************
83 * AlephIndexTest::init *
84 ***************************************************************************/
85void AlephIndexTest::
86init(void)
87{
88 m_nb_solver = options()->alephNumberOfSolvers;
89
90 m_aleph_mat.resize(m_nb_solver);
91 m_aleph_rhs.resize(m_nb_solver);
92 m_aleph_sol.resize(m_nb_solver);
93 m_aleph_params.resize(m_nb_solver);
94
95 // On set notre pas de temps
96 m_global_deltat = 1.0;
97
98 // initialisation de la temperature sur toutes les mailles et faces
99 m_cell_temperature.fill(options()->initTemperature());
100 m_face_temperature.fill(options()->initTemperature());
101
102 // initialisation de la température aux limites, boucle sur les conditions aux limites
103 for (int i = options()->boundaryCondition.size() - 1; i >= 0; --i) {
104 Real temperature = options()->boundaryCondition[i]->value();
105 FaceGroup face_group = options()->boundaryCondition[i]->surface();
106 // boucle sur les faces de la surface
108 m_face_temperature[iFace] = temperature;
109 }
110 mesh()->checkValidMeshFull();
111
112 // On instancie un kernel minimaliste qui va prendre en charge l'init à notre place
113 // L'AlephKernel(subDomain(),0,0); semble poser soucis, mais pas le 2,0, ni le 0,1:
114 // problème d'initialisation de topologie pre-kernel?
115 // La valeur 2 correspond au Kernel pour Hypre.
116 m_aleph_kernel = new AlephKernel(subDomain(), 2, 1);
117
118 // Encore une initialisation des indices des vecteurs
119 ENUMERATE_CELL (cell, ownCells()) {
120 m_vector_zeroes.add(0.0);
121 }
122}
123
124/***************************************************************************
125 * Entry points leads us here
126 ***************************************************************************/
127void AlephIndexTest::
128compute(void)
129{
133 Real residual_norm[4];
134
135 if (m_nb_solver == 0) {
136 subDomain()->timeLoopMng()->stopComputeLoop(true);
137 return;
138 }
139
140 indexs.resize(m_nb_solver);
141 values.resize(m_nb_solver);
142 for (int i = 0; i < m_nb_solver; ++i)
143 postSolver(i, options()->deltaT, values[i], indexs[i]);
144
145 // And should be able to get the solutions after the last resolution was fired
146 for (int i = m_nb_solver - 1; i >= 0; --i) {
147 debug() << "[AlephIndexTest::compute] Getting solution #" << i;
148 AlephVector* solution = m_aleph_kernel->syncSolver(i, nb_iteration, &residual_norm[0]);
149 if (i != m_get_solution_idx)
150 continue;
151 debug() << "Solved in \33[7m" << nb_iteration << "\33[m iterations,"
152 << "residuals=[\33[1m" << residual_norm[0] << "\33[m," << residual_norm[3] << "]";
153 debug() << "[AlephIndexTest::compute] Applying solution #" << m_get_solution_idx;
154 solution->getLocalComponents(values[i]);
155 m_get_solution_idx += 1;
156 }
157 m_get_solution_idx %= m_nb_solver;
158
159 // Sinon, on recopie les résultats
160 debug() << "[AlephIndexTest::compute] Now get our results";
161 ENUMERATE_CELL (cell, ownCells())
162 m_cell_temperature[cell] = values[m_get_solution_idx][m_aleph_kernel->indexing()->get(m_cell_temperature, *cell)];
163
164 // Si on a atteint notre maximum d'itérations, on sort
165 if (subDomain()->commonVariables().globalIteration() >= options()->iterations)
166 subDomain()->timeLoopMng()->stopComputeLoop(true);
167
168 debug() << "[AlephIndexTest::compute] done";
169}
170
171/***************************************************************************
172 * job
173 ***************************************************************************/
174void AlephIndexTest::
175postSolver(const Integer i, Real optionDeltaT,
176 Array<Real>& values,
177 Array<Integer>& indexs)
178{
179 // On force les deltaT à être différents pour avoir des temps de calculs que l'on pourra ordonnancer
180 Real deltaT = (1.0 + (Real)i) * optionDeltaT;
182 Real fake_residual_norm[4];
183
184 m_aleph_params[i] = new AlephParams(traceMng(),
185 1.0e-10, // m_param_epsilon epsilon de convergence
186 2000, // m_param_max_iteration nb max iterations
187 TypesSolver::AMG, // m_param_preconditioner_method préconditionnement: DIAGONAL, AMG, IC
188 TypesSolver::PCG, // m_param_solver_method méthode de résolution
189 -1, // m_param_gamma
190 -1.0, // m_param_alpha
191 false, // m_param_xo_user par défaut Xo n'est pas égal à 0
192 false, // m_param_check_real_residue
193 false, // m_param_print_real_residue
194 false, // m_param_debug_info
195 1.e-40, // m_param_min_rhs_norm
196 false, // m_param_convergence_analyse
197 true, // m_param_stop_error_strategy
198 false, // m_param_write_matrix_to_file_error_strategy
199 "SolveErrorAlephMatrix.dbg", // m_param_write_matrix_name_error_strategy
200 false, // m_param_listing_output
201 0., // m_param_threshold
202 false, // m_param_print_cpu_time_resolution
203 0, // m_param_amg_coarsening_method: par défault celui de Sloop,
204 0, // m_param_output_level
205 1, // m_param_amg_cycle: 1-cycle amg en V, 2= cycle amg en W, 3=cycle en Full Multigrid V
206 1, // m_param_amg_solver_iterations
207 1, // m_param_amg_smoother_iterations
208 TypesSolver::SymHybGSJ_smoother, // m_param_amg_smootherOption
209 TypesSolver::ParallelRugeStuben, // m_param_amg_coarseningOption
210 TypesSolver::CG_coarse_solver, // m_param_amg_coarseSolverOption
211 false, // m_param_keep_solver_structure
212 false, // m_param_sequential_solver
213 TypesSolver::RB); // m_param_criteria_stop
214
215 // Remplissage du second membre: conditions limites + second membre
216 debug() << "[AlephIndexTest::compute] Resize (" << m_vector_zeroes.size() << ") + remplissage du second membre";
217 values.resize(m_vector_zeroes.size());
218 indexs.resize(m_vector_zeroes.size());
219 ENUMERATE_CELL (cell, ownCells()) {
220 Integer row = m_aleph_kernel->indexing()->get(m_cell_temperature, cell);
221 indexs[row] = row;
222 values[row] = m_cell_temperature[cell];
223 }
224
225 debug() << "[AlephIndexTest::compute] ENUMERATE_FACE";
226 ENUMERATE_FACE (iFace, allCells().outerFaceGroup()) {
227 if (!iFace->cell(0).isOwn())
228 continue;
229 values[m_aleph_kernel->indexing()->get(m_cell_temperature, iFace->cell(0))] +=
230 deltaT * (m_face_temperature[iFace]) / geoFaceSurface(*iFace, nodesCoordinates());
231 }
232
233 // Création de la matrice MatVec et des besoins Aleph
234 m_aleph_mat[i] = m_aleph_kernel->createSolverMatrix();
235 m_aleph_rhs[i] = m_aleph_kernel->createSolverVector(); // First vector returned IS the rhs
236 m_aleph_sol[i] = m_aleph_kernel->createSolverVector(); // Next one IS the solution
237
238 m_aleph_mat[i]->create();
239 m_aleph_rhs[i]->create();
240 m_aleph_sol[i]->create();
241 m_aleph_mat[i]->reset();
242
243 // Remplissage de la matrice et assemblage
244 setValues(deltaT, m_aleph_mat[i]);
245 m_aleph_mat[i]->assemble();
246
247 debug() << "[AlephIndexTest::job] setLocalComponents";
248 //m_aleph_rhs[i]->setLocalComponents(indexs.size(), indexs.view(), values.view());
249 m_aleph_rhs[i]->setLocalComponents(values.view());
250 m_aleph_rhs[i]->assemble();
251
252 //m_aleph_sol[i]->setLocalComponents(indexs.size(), indexs.view(), m_vector_zeroes.view());
253 m_aleph_sol[i]->setLocalComponents(m_vector_zeroes.view());
254 m_aleph_sol[i]->assemble();
255 debug() << "[AlephIndexTest::job] done setLocalComponents";
256 traceMng()->flush();
257
258 // Now solve with Aleph
259 debug() << "[AlephIndexTest::job] Now solve with Aleph";
260 m_aleph_mat[i]->solve(m_aleph_sol[i],
261 m_aleph_rhs[i],
264 m_aleph_params[i],
265 true); // On souhaite poster de façon asynchrone
266 debug() << "[AlephIndexTest::job] done with Aleph solve";
267 traceMng()->flush();
268}
269
270/***************************************************************************
271 * AlephTestModule::_FaceComputeSetValues *
272 ***************************************************************************/
273void AlephIndexTest::setValues(const Real deltaT, AlephMatrix* aleph_mat)
274{
275 // On flush les coefs
276 ENUMERATE_CELL (iCell, ownCells())
277 m_cell_coefs[iCell] = 0.;
278 // Faces 'inner'
279 debug() << "[AlephIndexTest::setValues] inner-faces";
280 ENUMERATE_FACE (iFace, allCells().innerFaceGroup()) {
281 if (iFace->backCell().isOwn()) {
282 const Real surface = geoFaceSurface(*iFace, nodesCoordinates());
283 aleph_mat->setValue(m_cell_temperature, iFace->backCell(),
284 m_cell_temperature, iFace->frontCell(),
285 -deltaT / surface);
286 m_cell_coefs[iFace->backCell()] += 1.0 / surface;
287 }
288 if (iFace->frontCell().isOwn()) {
289 const Real surface = geoFaceSurface(*iFace, nodesCoordinates());
290 aleph_mat->setValue(m_cell_temperature, iFace->frontCell(),
291 m_cell_temperature, iFace->backCell(),
292 -deltaT / surface);
293 m_cell_coefs[iFace->frontCell()] += 1.0 / surface;
294 }
295 }
296 debug() << "[AlephIndexTest::setValues] outer-faces";
297 ENUMERATE_FACE (iFace, allCells().outerFaceGroup()) {
298 if (!iFace->cell(0).isOwn())
299 continue;
300 m_cell_coefs[iFace->cell(0)] += 1.0 / geoFaceSurface(*iFace, nodesCoordinates());
301 }
302 debug() << "[AlephIndexTest::setValues] diagonale";
303 ENUMERATE_CELL (cell, ownCells()) {
304 aleph_mat->setValue(m_cell_temperature, cell,
305 m_cell_temperature, cell,
306 1.0 + deltaT * m_cell_coefs[cell]);
307 }
308 debug() << "[AlephIndexTest::setValues] done";
309}
310
311/***************************************************************************
312 * geoFaceSurface
313 ***************************************************************************/
314Real AlephIndexTest::geoFaceSurface(Face face, VariableItemReal3& nodes_coords)
315{
316 if (face.nbNode() == 4) {
317 const Real3 xyz0 = nodes_coords[face.node(0)];
318 const Real3 xyz1 = nodes_coords[face.node(1)];
319 const Real3 xyz3 = nodes_coords[face.node(3)];
320 return (xyz0 - xyz1).normL2() * (xyz0 - xyz3).normL2();
321 }
322 if (face.nbNode() == 2) {
323 const Real3 xyz0 = nodes_coords[face.node(0)];
324 const Real3 xyz1 = nodes_coords[face.node(1)];
325 return (xyz0 - xyz1).normL2();
326 }
327 throw FatalErrorException("geoFace", "Nb nodes != 4 !=2");
328}
329
330/*---------------------------------------------------------------------------*/
331/*---------------------------------------------------------------------------*/
332
333ARCANE_DEFINE_STANDARD_MODULE(AlephIndexTest, AlephIndexTest);
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
AlephVector * createSolverVector(void)
AlephVector * syncSolver(Integer, Integer &, Real *)
Matrice d'un système linéaire.
Definition AlephMatrix.h:33
Paramètres d'un système linéraire.
Definition AlephParams.h:34
Vecteur d'un système linéaire.
Definition AlephVector.h:33
Tableau d'items de types quelconques.
Face d'une maille.
Definition Item.h:932
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:768
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Informations pour construire un module.
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Integer size() const
Nombre d'éléments du vecteur.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Exception lorsqu'une erreur fatale est survenue.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.