Arcane  v4.1.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MaterialHeatTestModule.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* MaterialHeatTestModule.cc (C) 2000-2025 */
9/* */
10/* Module de test des matériaux. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#define ARCANE_TRACE_ENUMERATOR
15
16#include "arcane/utils/ValueConvert.h"
17#include "arcane/utils/IProfilingService.h"
18#include "arcane/utils/IMemoryRessourceMng.h"
19
20#include "arcane/utils/Profiling.h"
21#include "arccore/base/internal/ProfilingInternal.h"
22
23#include "arcane/core/VariableTypes.h"
24#include "arcane/core/IMesh.h"
25#include "arcane/core/Item.h"
26#include "arcane/core/ITimeLoopMng.h"
27#include "arcane/core/IParallelMng.h"
30#include "arcane/core/IVariableMng.h"
31#include "arcane/core/ItemInfoListView.h"
32#include "arcane/core/internal/IVariableInternal.h"
33#include "arcane/core/internal/ItemGroupImplInternal.h"
34#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
35#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
36
37#include "arcane/materials/MeshMaterialVariableRef.h"
38#include "arcane/materials/MeshEnvironmentBuildInfo.h"
39#include "arcane/materials/MeshMaterialInfo.h"
40#include "arcane/materials/CellToAllEnvCellConverter.h"
41#include "arcane/materials/MeshMaterialModifier.h"
42#include "arcane/materials/ComponentItemVectorView.h"
43
44#include "arcane/accelerator/core/IAcceleratorMng.h"
45#include "arcane/accelerator/core/RunCommand.h"
46#include "arcane/accelerator/core/RunQueue.h"
47#include "arcane/accelerator/core/Runner.h"
48#include "arccore/common/accelerator/internal/RunnerInternal.h"
53#include "arcane/accelerator/RunCommandLoop.h"
54#include "arcane/accelerator/Filter.h"
55#include "arcane/accelerator/SpanViews.h"
56#include "arcane/accelerator/NumArrayViews.h"
57#include "arcane/accelerator/Reduce.h"
58
59#include "arcane/tests/ArcaneTestGlobal.h"
60#include "arcane/tests/MaterialHeatTest_axl.h"
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65namespace ArcaneTest
66{
67
68using namespace Arcane;
69using namespace Arcane::Materials;
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
76class MaterialHeatTestModule
77: public ArcaneMaterialHeatTestObject
78{
79 public:
80
101
103 struct MaterialWorkArray
104 {
105 MaterialWorkArray(eMemoryRessource mem)
106 : mat_cells_to_add_value(_allocator(mem))
107 , mat_cells_to_add(_allocator(mem))
108 , mat_cells_to_remove(_allocator(mem))
110 {
111 }
112
113 public:
114
115 void clear()
116 {
118 mat_cells_to_add.clear();
119 mat_cells_to_remove.clear();
120 mat_cells_remove_filter.resize(0);
121 }
122
123 void resizeNbAdd(Int32 new_size)
124 {
125 mat_cells_to_add_value.resize(new_size);
126 mat_cells_to_add.resize(new_size);
127 }
128
129 void resizeNbRemove(Int32 new_size)
130 {
131 mat_cells_to_remove.resize(new_size);
132 mat_cells_remove_filter.resize(new_size);
133 }
134
135 public:
136
137 static MemoryAllocationOptions _allocator(eMemoryRessource mem)
138 {
140 }
141
142 public:
143
152 };
153
154 public:
155
156 explicit MaterialHeatTestModule(const ModuleBuildInfo& mbi);
157 ~MaterialHeatTestModule();
158
159 public:
160
161 void buildInit() override;
162 void compute() override;
163 void startInit() override;
164 void continueInit() override;
165
166 private:
167
168 IMeshMaterialMng* m_material_mng = nullptr;
169 UniqueArray<HeatObject> m_heat_objects;
170 IProfilingService* m_profiling_service = nullptr;
171 RunQueue m_queue;
172 Runner m_sequential_runner;
173 UniqueArray<MeshMaterialVariableRef*> m_additional_variables;
174 bool m_is_init_with_zero = false;
175 bool m_is_check_init_new_cells = false;
176
177 private:
178
179 void _computeCellsCenter();
180 void _buildHeatObjects();
181 IMeshMaterial* _findMaterial(const String& name);
182
183 public:
184
185 void _addHeat(const HeatObject& heat_object);
186 void _addCold(const HeatObject& heat_object);
187 void _computeGlobalTemperature();
188 void _computeCellsToAdd(const HeatObject& heat_object, MaterialWorkArray& wa);
189 void _computeCellsToRemove(const HeatObject& heat_object, MaterialWorkArray& wa);
190 void _copyToGlobal(const HeatObject& heat_object);
191 void _initNewCells(const HeatObject& heat_object, MaterialWorkArray& wa);
192 void _computeTotalTemperature(const HeatObject& heat_object, bool do_check);
193
194 private:
195
196 void _compute();
197 void _printCellsTemperature(Int32ConstArrayView ids);
198 void _changeVariableAllocator();
199};
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204/*---------------------------------------------------------------------------*/
205/*---------------------------------------------------------------------------*/
206
207MaterialHeatTestModule::
208MaterialHeatTestModule(const ModuleBuildInfo& mbi)
209: ArcaneMaterialHeatTestObject(mbi)
210, m_material_mng(IMeshMaterialMng::getReference(mbi.meshHandle()))
211{
212 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_PROFILE_HEATTEST", true))
213 if (v.value() != 0)
214 m_profiling_service = platform::getProfilingService();
215 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_MATERIAL_NEW_ITEM_INIT", true)) {
216 Int32 vv = v.value();
217 // 0 -> initialisation à partir de la maille globale et pas de vérification
218 // 1 -> initialisation à zéro et pas de vérification
219 // 2 -> initialisation à zéro et vérification
220 // 3 -> initialisation à partir de la maille globale et vérification
221 m_is_init_with_zero = (vv == 1 || vv == 2);
222 m_is_check_init_new_cells = (vv == 2 || vv == 3);
223 }
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229MaterialHeatTestModule::
230~MaterialHeatTestModule()
231{
232 for (MeshMaterialVariableRef* v : m_additional_variables)
233 delete v;
234 m_additional_variables.clear();
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240void MaterialHeatTestModule::
241buildInit()
242{
243 m_sequential_runner.initialize(Accelerator::eExecutionPolicy::Sequential);
244 m_queue = *acceleratorMng()->defaultQueue();
246
247 // La création des milieux et des matériaux doit se faire dans un point
248 // d'entrée de type 'build' pour que la liste des variables créés par les
249 // milieux et les matériaux soit accessibles dans le post-traitement.
250 info() << "MaterialHeatTestModule::buildInit()";
251
252 IMesh* mesh = defaultMesh();
253 Materials::IMeshMaterialMng* mm = IMeshMaterialMng::getReference(mesh);
254
255 int flags = options()->modificationFlags();
256
257 info() << "MaterialHeatTestModule modification_flags=" << flags;
258
259 m_material_mng->setModificationFlags(flags);
260 m_material_mng->setMeshModificationNotified(true);
261 m_material_mng->setUseMaterialValueWhenRemovingPartialValue(true);
262 m_material_mng->setDataInitialisationWithZero(m_is_init_with_zero);
263 if (subDomain()->isContinue()) {
264 mm->recreateFromDump();
265 }
266 else {
267 UniqueArray<MeshMaterialInfo*> materials_info;
268 // Lit les infos des matériaux du JDD et les enregistre dans le gestionnaire
269 for (Integer i = 0, n = options()->material().size(); i < n; ++i) {
270 String mat_name = options()->material[i].name;
271 info() << "Found material name=" << mat_name;
272 materials_info.add(mm->registerMaterialInfo(mat_name));
273 }
274
275 UniqueArray<IMeshEnvironment*> saved_envs;
276
277 // Créé les milieux
278 for (Integer i = 0, n = options()->environment().size(); i < n; ++i) {
279 String env_name = options()->environment[i].name;
280 info() << "Found environment name=" << env_name;
281 Materials::MeshEnvironmentBuildInfo env_build(env_name);
282 for (Integer k = 0, kn = options()->environment[i].material.size(); k < kn; ++k) {
283 String mat_name = options()->environment[i].material[k];
284 info() << "Add material " << mat_name << " for environment " << env_name;
285 env_build.addMaterial(mat_name);
286 }
287 IMeshEnvironment* env = mm->createEnvironment(env_build);
288 saved_envs.add(env);
289 }
290
291 mm->endCreate(false);
292
293 info() << "List of materials:";
294 for (MeshMaterialInfo* m : materials_info) {
295 info() << "MAT=" << m->name();
296 for (String s : m->environmentsName())
297 info() << " In ENV=" << s;
298 }
299 }
300
301 // Créé les éventuelles variables scalaires additionnelles.
302 {
303 Int32 nb_var_to_add = options()->nbAdditionalVariable();
304 info() << "NbVariableToAdd = " << nb_var_to_add;
305 for (Int32 i = 0; i < nb_var_to_add; ++i) {
306 String var_name = "MaterialAdditionalVar" + String::fromNumber(i);
307 auto* v = new MaterialVariableCellInt32(VariableBuildInfo(mesh, var_name));
308 m_additional_variables.add(v);
309 v->fill(i + 2);
310 }
311 }
312
313 // Créé les éventuelles variables tableaux additionnelles.
314 {
315 Int32 nb_var_to_add = options()->nbAdditionalArrayVariable();
316 info() << "NbArrayVariableToAdd = " << nb_var_to_add;
317 for (Int32 i = 0; i < nb_var_to_add; ++i) {
318 String var_name = "MaterialAdditionalArrayVar" + String::fromNumber(i);
319 auto* v = new MaterialVariableCellArrayInt32(VariableBuildInfo(mesh, var_name));
320 v->resize(1 + (i % 3));
321 m_additional_variables.add(v);
322 v->globalVariable().fill(i + 5);
323 v->fillPartialValuesWithSuperValues(LEVEL_ALLENVIRONMENT);
324 }
325 }
326}
327
328/*---------------------------------------------------------------------------*/
329/*---------------------------------------------------------------------------*/
330
331void MaterialHeatTestModule::
332startInit()
333{
334 _buildHeatObjects();
335 m_global_deltat.assign(1.0);
336 m_mat_temperature.globalVariable().fill(0.0);
337 m_material_mng->forceRecompute();
338 _computeCellsCenter();
339 MeshUtils::markMeshConnectivitiesAsMostlyReadOnly(defaultMesh(), &m_queue, true);
340 VariableUtils::markVariableAsMostlyReadOnly(m_cell_center);
341 VariableUtils::markVariableAsMostlyReadOnly(defaultMesh()->nodesCoordinates());
342
343 eMemoryRessource mem_ressource = eMemoryRessource::UnifiedMemory;
344 if (m_queue.isAcceleratorPolicy() && m_material_mng->_internalApi()->runQueue().isAcceleratorPolicy())
345 mem_ressource = eMemoryRessource::Device;
346
347 const bool do_change_allocator = true;
348 if (do_change_allocator) {
349 info() << "Changing allocator to use device memory to '" << mem_ressource << "'";
350 VariableUtils::experimentalChangeAllocator(m_mat_device_temperature.materialVariable(), mem_ressource);
351 }
352 {
353 eMemoryRessource group_mem_ressource = mem_ressource;
354 // En mode check il ne faut pas utiliser la mémoire du device car il y a des tests
355 // effectués uniquement sur CPU
356 if (arcaneIsCheck())
357 group_mem_ressource = eMemoryRessource::UnifiedMemory;
358 ENUMERATE_MAT (imat, m_material_mng) {
359 IMeshMaterial* mat = *imat;
360 mat->cells()._internalApi()->setMemoryRessourceForItemLocalId(group_mem_ressource);
361 }
362 ENUMERATE_ENV (ienv, m_material_mng) {
363 IMeshEnvironment* env = *ienv;
364 env->cells()._internalApi()->setMemoryRessourceForItemLocalId(group_mem_ressource);
365 }
366 }
367}
368
369/*---------------------------------------------------------------------------*/
370/*---------------------------------------------------------------------------*/
371
372void MaterialHeatTestModule::
373_changeVariableAllocator()
374{
375 VariableCollection used_variables = subDomain()->variableMng()->usedVariables();
376 MemoryAllocationOptions host_mem_opts(MemoryUtils::getAllocationOptions(eMemoryRessource::Host));
377 for (VariableCollection::Enumerator ivar(used_variables); ++ivar;) {
378 IVariable* var = *ivar;
379 if (var->name().startsWith("TimeHistoryMng")) {
380 var->_internalApi()->changeAllocator(host_mem_opts);
381 info() << "Change allocator for '" << var->fullName() << "'";
382 }
383 }
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389void MaterialHeatTestModule::
390continueInit()
391{
392 info() << "MaterialHeatTestModule::continueInit()";
393 _buildHeatObjects();
394}
395
396/*---------------------------------------------------------------------------*/
397/*---------------------------------------------------------------------------*/
398
399void MaterialHeatTestModule::
400compute()
401{
402 info() << "MaterialHeatTestModule::compute()";
403 Int32 iteration = m_global_iteration();
404 if (iteration <= 2)
405 _changeVariableAllocator();
406
407 if (iteration>=2){
408 Runner runner = *acceleratorMng()->defaultRunner();
409 ostringstream o;
411 info() << o.str();
412 }
413
414 bool is_end = (iteration >= options()->nbIteration());
415 if (is_end)
416 subDomain()->timeLoopMng()->stopComputeLoop(true);
417
418 _compute();
419
420 bool do_check = is_end && options()->checkNumericalResult();
421 for (const HeatObject& ho : m_heat_objects) {
422 _computeTotalTemperature(ho, do_check);
423 }
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429void MaterialHeatTestModule::
430_compute()
431{
432 RunQueue* queue = acceleratorMng()->defaultQueue();
433 eMemoryRessource mem = eMemoryRessource::UnifiedMemory;
434 if (queue->isAcceleratorPolicy())
435 mem = eMemoryRessource::Device;
436
437 const Int32 nb_heat = m_heat_objects.size();
438 UniqueArray<MaterialWorkArray> work_arrays;
439 work_arrays.reserve(nb_heat);
440 for (Int32 i = 0; i < nb_heat; ++i)
441 work_arrays.add(MaterialWorkArray(mem));
442
443 // Ajoute de la chaleur à chaque matériau
444 for (const HeatObject& ho : m_heat_objects)
445 _addHeat(ho);
446
447 // Calcule les mailles à ajouter et supprimer
448 for (const HeatObject& ho : m_heat_objects) {
449 MaterialWorkArray& wa = work_arrays[ho.index];
450 _computeCellsToRemove(ho, wa);
451 _computeCellsToAdd(ho, wa);
452 }
453
454 // Effectue les modifications des matériaux
455 {
456 ProfilingSentryWithInitialize ps_sentry(m_profiling_service);
457 MeshMaterialModifier modifier(m_material_mng);
458 for (const HeatObject& ho : m_heat_objects) {
459 MaterialWorkArray& wa = work_arrays[ho.index];
460 IMeshMaterial* mat = ho.material;
461
462 // Supprime les mailles matériaux nécessaires
463 ConstArrayView<Int32> remove_ids = wa.mat_cells_to_remove;
464 if (!remove_ids.empty()) {
465 info() << "MAT_MODIF: Remove n=" << remove_ids.size() << " cells to material=" << mat->name();
466 modifier.removeCells(mat, remove_ids);
467 }
468
469 // Ajoute les mailles matériaux nécessaires
470 ConstArrayView<Int32> add_ids(wa.mat_cells_to_add.constView());
471 if (!add_ids.empty()) {
472 info() << "MAT_MODIF: Add n=" << add_ids.size() << " cells to material=" << mat->name();
473 modifier.addCells(mat, add_ids);
474 }
475 }
476 }
477
478 // Affiche les valeurs pour les mailles modifiées
479 if (options()->verbosityLevel() > 0) {
480 for (const HeatObject& ho : m_heat_objects) {
481 _printCellsTemperature(work_arrays[ho.index].mat_cells_to_add.constView());
482 _printCellsTemperature(work_arrays[ho.index].mat_cells_to_remove.constView());
483 }
484 }
485
486 // Initialise les nouvelles valeurs partielles
487 for (const HeatObject& ho : m_heat_objects)
488 _initNewCells(ho, work_arrays[ho.index]);
489
490 // Refroidit chaque matériau
491 for (const HeatObject& ho : m_heat_objects)
492 _addCold(ho);
493
494 for (const HeatObject& ho : m_heat_objects) {
495 _copyToGlobal(ho);
496 }
497
498 _computeGlobalTemperature();
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504namespace
505{
506 ARCCORE_HOST_DEVICE MatCell _getMatCell(AllEnvCell c, Int32 mat_id)
507 {
508 for (EnvCell env_cell : c.subEnvItems()) {
509 for (MatCell mc : env_cell.subMatItems()) {
510 Int32 mid = mc.materialId();
511 if (mid == mat_id)
512 return mc;
513 }
514 }
515 return {};
516 }
517} // namespace
518
519/*---------------------------------------------------------------------------*/
520/*---------------------------------------------------------------------------*/
521
522void MaterialHeatTestModule::
523_initNewCells(const HeatObject& heat_object, MaterialWorkArray& wa)
524{
525 RunQueue* queue = this->acceleratorMng()->defaultQueue();
526
527 bool init_with_zero = m_material_mng->isDataInitialisationWithZero();
528
529 // Initialise les nouvelles valeurs partielles
530 IMeshMaterial* current_mat = heat_object.material;
531 Int32 mat_id = current_mat->id();
532 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
533 SmallSpan<const Int32> ids(wa.mat_cells_to_add.constView());
534 const Int32 nb_id = ids.size();
535 const bool do_check = m_is_check_init_new_cells;
536 if (do_check) {
537 // Vérifie que la nouvelle valeur est initialisée avec 0 (si init_with_zero
538 // est vrai) où qu'elle est initialisée avec la valeur globale
539 auto command = makeCommand(queue);
540 auto out_mat_temperature = viewInOut(command, m_mat_temperature);
541 Accelerator::ReducerSum2<Int32> sum_error(command);
542 command << RUNCOMMAND_LOOP1(iter, nb_id, sum_error)
543 {
544 auto [i] = iter();
545 AllEnvCell all_env_cell = all_env_cell_converter[CellLocalId(ids[i])];
546 MatCell mc = _getMatCell(all_env_cell, mat_id);
547 MatVarIndex mvi = mc._varIndex();
548 if (mvi.arrayIndex() != 0) {
549 Real v = out_mat_temperature[mc];
550 if (init_with_zero) {
551 if (v != 0.0)
552 sum_error.combine(1);
553 //ARCANE_FATAL("Bad mat temperature (should be 0) i={0} v={1} mc={2}", i, v, mc);
554 }
555 else {
556 Real global_v = out_mat_temperature[mc.globalCellId()];
557 if (v != global_v)
558 sum_error.combine(1);
559 //ARCANE_FATAL("Bad mat temperature i={0} v={1} mc={2} expected_v={3}", i, v, mc, global_v);
560 }
561 }
562 };
563 Int32 nb_error = sum_error.reducedValue();
564 if (nb_error != 0)
565 ARCANE_FATAL("Errors with new cells nb_error={0}", nb_error);
566 }
567 {
568 auto command = makeCommand(queue);
569 auto in_value_to_add = viewIn(command, wa.mat_cells_to_add_value);
570 auto out_mat_temperature = viewInOut(command, m_mat_temperature);
571 command << RUNCOMMAND_LOOP1(iter, nb_id)
572 {
573 auto [i] = iter();
574 AllEnvCell all_env_cell = all_env_cell_converter[CellLocalId(ids[i])];
575 MatCell mc = _getMatCell(all_env_cell, mat_id);
576 out_mat_temperature[mc] = in_value_to_add[i];
577 };
578 }
579}
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
584void MaterialHeatTestModule::
585_addCold(const HeatObject& heat_object)
586{
587 IMeshMaterial* current_mat = heat_object.material;
588 const Real cold_value = heat_object.cold_value;
589
590 RunQueue* queue = this->acceleratorMng()->defaultQueue();
591
592 {
593 auto command = makeCommand(queue);
594 auto inout_mat_temperature = viewInOut(command, m_mat_temperature);
595 command << RUNCOMMAND_MAT_ENUMERATE(MatCell, matcell, current_mat)
596 {
597 Real t = inout_mat_temperature[matcell];
598 t -= cold_value;
599 inout_mat_temperature[matcell] = t;
600 };
601 }
602
603 if (arcaneIsCheck()) {
604 ENUMERATE_MATCELL (imatcell, current_mat) {
605 Real t = m_mat_temperature[imatcell];
606 if (t <= 0)
607 ARCANE_FATAL("Invalid negative temperature '{0}' cell_lid={1}", t, (*imatcell).globalCell().localId());
608 }
609 }
610}
611
612/*---------------------------------------------------------------------------*/
613/*---------------------------------------------------------------------------*/
614
616_addHeat(const HeatObject& heat_object)
617{
618 Real3 heat_center = heat_object.center;
619 heat_center += heat_object.velocity * m_global_time();
620 const Real heat_value = heat_object.heat_value;
621 const Real heat_radius_norm = heat_object.radius * heat_object.radius;
622
623 IMeshMaterial* current_mat = heat_object.material;
624 //RunQueue* queue = this->acceleratorMng()->defaultQueue();
625 //auto queue = makeQueue(m_sequential_runner);
626 auto command = makeCommand(m_queue);
627
628 auto in_cell_center = viewIn(command, m_cell_center);
629 auto inout_mat_temperature = viewInOut(command, m_mat_temperature);
630 auto out_mat_device_temperature = viewInOut(command, m_mat_device_temperature);
631
633 command << RUNCOMMAND_MAT_ENUMERATE(MatAndGlobalCell, iter, current_mat)
634 {
635 auto [matcell, cell] = iter();
636 Real3 center = in_cell_center[cell];
637 Real distance2 = (center - heat_center).squareNormL2();
638 if (distance2 < heat_radius_norm) {
639 Real to_add = heat_value / (1.0 + distance2);
640 inout_mat_temperature[matcell] += to_add;
641 out_mat_device_temperature[matcell] = inout_mat_temperature[matcell];
642 }
643 };
644}
645
646/*---------------------------------------------------------------------------*/
647/*---------------------------------------------------------------------------*/
648
649void MaterialHeatTestModule::
650_computeCellsToAdd(const HeatObject& heat_object, MaterialWorkArray& wa)
651{
652 Real3 heat_center = heat_object.center;
653 heat_center += heat_object.velocity * m_global_time();
654 const Real heat_value = heat_object.heat_value;
655 Real heat_radius = heat_object.radius;
656 const Real heat_radius_norm = heat_radius * heat_radius;
657 IMeshMaterial* current_mat = heat_object.material;
658 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
659
660 const Int32 mat_id = current_mat->id();
661
662 // Détermine les nouvelles à ajouter au matériau
663 {
664 CellVectorView all_cells(allCells().view());
665
666 const Int32 nb_item = all_cells.size();
667 wa.resizeNbAdd(nb_item);
668 Accelerator::GenericFilterer filterer(m_queue);
669 auto in_cell_center = viewIn(m_queue, m_cell_center);
670 auto cells_ids = viewIn(m_queue, all_cells.localIds());
671
672 auto select_functor = [=] ARCCORE_HOST_DEVICE(Int32 index) -> bool {
673 CellLocalId cellid(cells_ids[index]);
674 AllEnvCell all_env_cell = all_env_cell_converter[cellid];
675 Real3 center = in_cell_center[cellid];
676 Real distance2 = (center - heat_center).squareNormL2();
677 if (distance2 < heat_radius_norm) {
678 MatCell mc = _getMatCell(all_env_cell, mat_id);
679 // Si 'mc' est nul cela signifie que ce matériau n'est
680 // pas présent dans la maille. Il faudra donc l'ajouter.
681 // On conserve la valeur à ajouter pour ne pas la recalculer
682 return mc.null();
683 }
684 return false;
685 };
686
687 auto cells_to_add_view = viewOut(m_queue, wa.mat_cells_to_add);
688 auto cells_to_add_value_view = viewOut(m_queue, wa.mat_cells_to_add_value);
689 auto setter_functor = [=] ARCCORE_HOST_DEVICE(Int32 input_index, Int32 output_index) {
690 CellLocalId cellid(cells_ids[input_index]);
691 Real3 center = in_cell_center[cellid];
692 Real distance2 = (center - heat_center).squareNormL2();
693 Real to_add = heat_value / (1.0 + distance2);
694 cells_to_add_view[output_index] = cellid;
695 cells_to_add_value_view[output_index] = to_add;
696 };
697 filterer.applyWithIndex(nb_item, select_functor, setter_functor, A_FUNCINFO);
698 Int32 nb_out = filterer.nbOutputElement();
699 wa.resizeNbAdd(nb_out);
700 }
701}
702
703/*---------------------------------------------------------------------------*/
704/*---------------------------------------------------------------------------*/
705
706void MaterialHeatTestModule::
707_computeCellsToRemove(const HeatObject& heat_object, MaterialWorkArray& wa)
708{
709 IMeshMaterial* current_mat = heat_object.material;
710 const bool is_verbose = false;
711 const Real cold_value = 300.0;
712
713 // Refroidit chaque maille du matériau d'une quantité fixe.
714 // Si la températeure devient inférieure à zéro on supprime la maille
715 // de ce matériau.
716 if (is_verbose)
717 info() << "MAT_BEFORE: " << current_mat->matView()._internalLocalIds();
718 const Int32 nb_cell = current_mat->cells().size();
719 wa.resizeNbRemove(nb_cell);
720
721 {
722 auto command = makeCommand(m_queue);
723 auto out_cells_remove_filter = viewOut(command, wa.mat_cells_remove_filter);
724 auto out_cells_local_id = viewOut(command, wa.mat_cells_to_remove);
725 auto in_mat_temperature = viewIn(command, m_mat_temperature);
726 command << RUNCOMMAND_MAT_ENUMERATE(MatAndGlobalCell, iter, current_mat)
727 {
728 auto [mvi, cid] = iter();
729 Int32 index = iter.index();
730 out_cells_remove_filter[index] = in_mat_temperature[mvi] < cold_value;
731 out_cells_local_id[index] = cid;
732 };
733 }
734
735 {
736 Accelerator::GenericFilterer filterer(m_queue);
737 SmallSpan<const Int32> in_remove_view = wa.mat_cells_to_remove.view();
738 SmallSpan<Int32> out_remove_view = wa.mat_cells_to_remove.view();
739 SmallSpan<const bool> filter_view = wa.mat_cells_remove_filter.to1DSmallSpan();
740 filterer.apply(in_remove_view, out_remove_view, filter_view);
741 Int32 nb_out = filterer.nbOutputElement();
742 wa.resizeNbRemove(nb_out);
743 }
744
745 if (is_verbose)
746 info() << "MAT_AFTER: " << current_mat->matView()._internalLocalIds();
747}
748
749/*---------------------------------------------------------------------------*/
750/*---------------------------------------------------------------------------*/
751
752void MaterialHeatTestModule::
753_copyToGlobal(const HeatObject& heat_object)
754{
755 IMeshMaterial* mat = heat_object.material;
756 Int32 var_index = heat_object.index;
757
758 {
759 auto command = makeCommand(m_queue);
760 auto in_mat_temperature = viewIn(command, m_mat_temperature);
761 auto out_all_temperature = viewOut(command, m_all_temperature);
762 command << RUNCOMMAND_MAT_ENUMERATE(MatAndGlobalCell, iter, mat)
763 {
764 auto [mvi, cid] = iter();
765 Real t = in_mat_temperature[mvi];
766 out_all_temperature[cid][var_index] = t;
767 };
768 }
769}
770
771/*---------------------------------------------------------------------------*/
772/*---------------------------------------------------------------------------*/
773
774void MaterialHeatTestModule::
775_computeTotalTemperature(const HeatObject& heat_object, bool do_check)
776{
777 IMeshMaterial* mat = heat_object.material;
778 Real total_mat_temperature = 0.0;
779
780 {
781 auto command = makeCommand(m_queue);
782 auto in_mat_temperature = viewIn(command, m_mat_temperature);
783 Accelerator::ReducerSum2<double> total_temperature_reducer(command);
784 CellInfoListView cells_info(defaultMesh()->cellFamily());
785 command << RUNCOMMAND_MAT_ENUMERATE(MatAndGlobalCell, iter, mat, total_temperature_reducer)
786 {
787 auto [mvi, cid] = iter();
788 if (cells_info.isOwn(cid)) {
789 Real t = in_mat_temperature[mvi];
790 total_temperature_reducer.combine(t);
791 }
792 };
793 total_mat_temperature = total_temperature_reducer.reducedValue();
794 }
795
796 total_mat_temperature = parallelMng()->reduce(Parallel::ReduceSum, total_mat_temperature);
797 info() << "TotalMatTemperature mat=" << mat->name() << " T=" << total_mat_temperature;
798 if (do_check) {
799 Real ref_value = heat_object.expected_final_temperature;
800 Real current_value = total_mat_temperature;
801 Real epsilon = 1.0e-12;
802 if (!math::isNearlyEqualWithEpsilon(current_value, ref_value, epsilon)) {
803 Real relative_diff = math::abs(ref_value - current_value);
804 if (ref_value != 0.0)
805 relative_diff /= ref_value;
806 ARCANE_FATAL("Bad value for mat '{0}' ref={1} v={2} diff={3}",
807 mat->name(), ref_value, current_value, relative_diff);
808 }
809 }
810}
811
812/*---------------------------------------------------------------------------*/
813/*---------------------------------------------------------------------------*/
814
815void MaterialHeatTestModule::
816_computeCellsCenter()
817{
818 // Calcule le centre des mailles
819 VariableNodeReal3& node_coord = defaultMesh()->nodesCoordinates();
820 ENUMERATE_ (Cell, icell, allCells()) {
821 Cell cell = *icell;
822 Real3 center;
823 auto cell_nodes = cell.nodeIds();
824 for (NodeLocalId nodeid : cell_nodes) {
825 center += node_coord[nodeid];
826 }
827 center /= cell_nodes.size();
828 m_cell_center[icell] = center;
829 }
830}
831
832/*---------------------------------------------------------------------------*/
833/*---------------------------------------------------------------------------*/
834
835void MaterialHeatTestModule::
836_buildHeatObjects()
837{
838 info() << "MaterialHeatTestModule::_buildHeatObjects()";
839
840 {
841 Int32 index = 0;
842 for (const auto& opt : options()->heatObject()) {
843 HeatObject ho;
844 ho.center = opt->center;
845 ho.velocity = opt->velocity;
846 ho.radius = opt->radius;
847 ho.material = _findMaterial(opt->material);
848 ho.index = index;
849 ho.expected_final_temperature = opt->expectedFinalTemperature;
850 m_heat_objects.add(ho);
851 ++index;
852 }
853 }
854
855 m_all_temperature.resize(m_heat_objects.size());
856}
857
858/*---------------------------------------------------------------------------*/
859/*---------------------------------------------------------------------------*/
860
861IMeshMaterial* MaterialHeatTestModule::
862_findMaterial(const String& name)
863{
864 for (IMeshMaterial* mat : m_material_mng->materials())
865 if (mat->name() == name)
866 return mat;
867 ARCANE_FATAL("No material in environment with name '{0}'", name);
868}
869
870/*---------------------------------------------------------------------------*/
871/*---------------------------------------------------------------------------*/
872
873void MaterialHeatTestModule::
874_computeGlobalTemperature()
875{
876 // Calcule dans 'Temperature' la somme des températures des milieux et matériaux
877 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
878 auto command = makeCommand(m_queue);
879 auto inout_mat_temperature = viewInOut(command, m_mat_temperature);
880 command << RUNCOMMAND_ENUMERATE (Cell, cellid, allCells())
881 {
882 //Cell cell = *icell;
883 AllEnvCell all_env_cell = all_env_cell_converter[cellid];
884 Real global_temperature = 0.0;
885 for (EnvCell env_cell : all_env_cell.subEnvItems()) {
886 Real env_temperature = 0.0;
887 for (MatCell mc : env_cell.subMatItems()) {
888 env_temperature += inout_mat_temperature[mc];
889 }
890 inout_mat_temperature[env_cell] = env_temperature;
891 global_temperature += env_temperature;
892 }
893 inout_mat_temperature[cellid] = global_temperature;
894 };
895}
896
897/*---------------------------------------------------------------------------*/
898/*---------------------------------------------------------------------------*/
899
900void MaterialHeatTestModule::
901_printCellsTemperature(Int32ConstArrayView ids)
902{
903 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
904 for (Int32 lid : ids) {
905 CellLocalId cell_id(lid);
906 AllEnvCell all_env_cell = all_env_cell_converter[cell_id];
907 Cell global_cell = all_env_cell.globalCell();
908 info() << "Cell=" << global_cell.uniqueId() << " v=" << m_mat_temperature[global_cell];
909 for (EnvCell ec : all_env_cell.subEnvItems()) {
910 info() << " EnvCell " << m_mat_temperature[ec]
911 << " mv=" << ec._varIndex()
912 << " env=" << ec.component()->name();
913 for (MatCell mc : ec.subMatItems()) {
914 info() << " MatCell " << m_mat_temperature[mc]
915 << " mv=" << mc._varIndex()
916 << " mat=" << mc.component()->name();
917 }
918 }
919 }
920}
921
922/*---------------------------------------------------------------------------*/
923/*---------------------------------------------------------------------------*/
924
925ARCANE_REGISTER_MODULE_MATERIALHEATTEST(MaterialHeatTestModule);
926
927/*---------------------------------------------------------------------------*/
928/*---------------------------------------------------------------------------*/
929
930} // End namespace ArcaneTest
931
932/*---------------------------------------------------------------------------*/
933/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Fonctions utilitaires sur le maillage.
Types et macros pour gérer les énumérations des entités sur les accélérateurs.
#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group,...)
Macro pour itérer sur accélérateur sur un groupe d'entités.
Types et macros pour gérer les énumérations des matériaux et milieux sur les accélérateurs.
#define RUNCOMMAND_MAT_ENUMERATE(ConstituentItemNameType, iter_name, env_or_mat_container,...)
Macro pour itérer sur un matériau ou un milieu.
Fonctions utilitaires sur les variables.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle 1D sur accélérateur avec arguments supplémentaires.
void _addHeat(const HeatObject &heat_object)
bool isAcceleratorPolicy() const
Indique si l'instance est associée à un accélérateur.
Definition RunQueue.cc:331
void printProfilingInfos(std::ostream &o)
Affiche les informations de profiling.
Definition Runner.cc:556
Gestionnaire d'exécution pour accélérateur.
RunnerInternal * _internalApi()
API interne à Arcane.
Definition Runner.cc:492
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
Classe template pour convertir un type.
Interface d'un service de profiling.
virtual void changeAllocator(const MemoryAllocationOptions &alloc_info)=0
Change l'allocateur de la variable.
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille)
virtual String name() const =0
Nom de la variable.
virtual IVariableInternal * _internalApi()=0
API interne à Arcane.
void setMemoryRessourceForItemLocalId(eMemoryRessource mem)
Change la ressource mémoire utilisée pour conserver les localId() des entités.
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
ItemGroupImplInternal * _internalApi() const
API interne à Arcane.
Definition ItemGroup.cc:646
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Definition Item.h:797
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Maille arcane avec info matériaux et milieux.
__host__ __device__ CellEnvCellEnumerator subEnvItems() const
Enumérateur sur les mailles milieux de cette maille.
ConstArrayView< Int32 > _internalLocalIds() const
Tableau des localId() des entités associées.
__host__ __device__ CellLocalId globalCellId() const
localId() de la maille globale
__host__ __device__ bool null() const
Indique s'il s'agit de la maille nulle.
Cell globalCell() const
Maille globale.
IMeshComponent * component() const
Constituant associé.
__host__ __device__ MatVarIndex _varIndex() const
virtual String name() const =0
Nom du composant.
virtual CellGroup cells() const =0
Groupe des mailles de ce matériau.
virtual Int32 id() const =0
Identifiant du composant.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual MeshMaterialInfo * registerMaterialInfo(const String &name)=0
Enregistre les infos du matériau de nom name.
virtual void endCreate(bool is_continue=false)=0
Indique qu'on a fini de créer les milieux.
virtual void recreateFromDump()=0
Recréé les infos des matériaux et milieux à partir des infos de la protection.
virtual IMeshEnvironment * createEnvironment(const MeshEnvironmentBuildInfo &infos)=0
Créé un milieu avec les infos infos.
static IMeshMaterialMng * getReference(const MeshHandleOrMesh &mesh_handle, bool create=true)
Récupère ou créé la référence associée à mesh.
Interface d'un matériau d'un maillage.
virtual MatItemVectorView matView() const =0
Vue associée à ce matériau.
Représente un matériau d'une maille multi-matériau.
constexpr __host__ __device__ Int32 arrayIndex() const
Retourne l'indice du tableau de valeur dans la liste des variables.
Informations pour construire un module.
Tableaux multi-dimensionnels pour les types numériques accessibles sur accélérateurs.
static void setProfilingLevel(Int32 level)
Positionne le niveau de profilage.
Definition Profiling.cc:230
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Chaîne de caractères unicode.
bool startsWith(const String &s) const
Indique si la chaîne commence par les caractères de s.
Definition String.cc:1100
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ENUMERATE_ENV(ienv, container)
Macro pour itérer sur une liste de milieux.
#define ENUMERATE_MATCELL(iname, mat)
Macro pour itérer sur toutes les mailles d'un matériau.
#define ENUMERATE_MAT(imat, container)
Macro pour itérer sur une liste de matériaux.
ItemVectorViewT< Cell > CellVectorView
Vue sur un vecteur de mailles.
Definition ItemTypes.h:304
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
auto viewInOut(const ViewBuildInfo &vbi, CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture/écriture pour les variables materiaux scalaire.
auto viewOut(const ViewBuildInfo &vbi, CellMaterialVariableScalarRef< DataType > &var)
Vue en écriture pour les variables materiaux scalaire.
auto viewIn(const ViewBuildInfo &vbi, const CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture pour les variables materiaux scalaire.
Active toujours les traces dans les parties Arcane concernant les matériaux.
CellMaterialVariableArrayRef< Int32 > MaterialVariableCellArrayInt32
Variable matériau de type tableau de Int32
CellMaterialVariableScalarRef< Int32 > MaterialVariableCellInt32
Variable matériau de type Int32
ARCCORE_COMMON_EXPORT MemoryAllocationOptions getAllocationOptions(eMemoryResource mem_resource)
Allocation par défaut pour la ressource mem_resource.
@ ReduceSum
Somme des valeurs.
constexpr __host__ __device__ Real squareNormL2(const Real2 &v)
Retourne la norme au carré du couple .
Definition Real2.h:451
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:235
IProfilingService * getProfilingService()
Service utilisé pour obtenir pour obtenir des informations de profiling.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:486
double Real
Type représentant un réel.
Arcane::eMemoryResource eMemoryRessource
Typedef pour la version Arcane historique (avec 2's')
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
std::int32_t Int32
Type entier signé sur 32 bits.
Caractéristiques de l'objet qui chauffe (disque ou sphère)
Int32 index
Index de cet objet dans la liste globale.
Real expected_final_temperature
Température attendue au temps final.
IMeshMaterial * material
Matériaux qui sera chauffé par cet objet.
Tableau de travail pour la mise à jour des liste de matériaux.
UniqueArray< Int32 > mat_cells_to_add
Liste des mailles à ajouter.
UniqueArray< Real > mat_cells_to_add_value
Liste des valeurs de température dans les mailles à ajouter.
UniqueArray< Int32 > mat_cells_to_remove
Liste des mailles à supprimer.
NumArray< bool, MDDim1 > mat_cells_remove_filter
Filtre des mailles à supprimer.