Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AlephTestSchemeFaces.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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#include "arcane/aleph/tests/AlephTest.h"
8#include "arcane/aleph/tests/AlephTestScheme.h"
9#include "arcane/aleph/tests/AlephTestSchemeFaces.h"
10
11#include "arcane/mesh/CellFamily.h"
12#include "arcane/mesh/FaceFamily.h"
13
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17namespace ArcaneTest
18{
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23using namespace Arcane;
24
25ARCANE_REGISTER_SERVICE_ALEPHTESTSCHEMEFACES(Faces, AlephTestSchemeFaces);
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30AlephTestSchemeFaces::
31AlephTestSchemeFaces(const ServiceBuildInfo& sbi)
33{
34 debug() << "\33[37m\t[AlephTestSchemeFaces::AlephTestSchemeFaces] New"
35 << "\33[0m";
36}
37
38AlephTestSchemeFaces::~AlephTestSchemeFaces(void)
39{
40 debug() << "\33[37m\t[AlephTestSchemeFaces::AlephTestSchemeFaces] Delete"
41 << "\33[0m";
42}
43
44/***************************************************************************
45 * Application des conditions aux limites propres au schéma
46 ***************************************************************************/
47void AlephTestSchemeFaces::
49{
50 ItacFunction(AlephTestSchemeFaces);
51 // boucle sur les conditions aux limites
52 for (int i = module_options->boundaryCondition.size() - 1; i >= 0; --i) {
53 Real temperature = module_options->boundaryCondition[i]->value();
54 FaceGroup face_group = module_options->boundaryCondition[i]->surface();
55 // boucle sur les faces de la surface
57 m_face_temperature[iFace] = temperature;
58 }
59 }
60}
61
62/***************************************************************************
63 * On compte le nombre d'éléments non nuls par ligne de la matrice
64 ***************************************************************************/
65void AlephTestSchemeFaces::
66preFetchNumElementsForEachRow(IntegerArray& rows_nb_element,
67 const Integer rank_row_offset)
68{
69 ItacFunction(AlephTestSchemeFaces);
70 debug() << "\33[37m\t[AlephTestSchemeFaces::preFetchNumElementsForEachRow]"
71 << "\33[0m";
72 // On comptabilise les termes de la diagonale
73 rows_nb_element.fill(1);
74
75 // Et on rajoute les couplages par faces
76 // Attention, il faut bien parcourir toutes les mailles et filtrer les faces des fantômes
77 ENUMERATE_FACE (iFace, INNER_ACTIVE_FACE_GROUP(allCells())) {
78 if (iFace->backCell().isOwn())
79 rows_nb_element[m_cell_matrix_idx[iFace->backCell()] - rank_row_offset] += 1;
80 if (iFace->frontCell().isOwn())
81 rows_nb_element[m_cell_matrix_idx[iFace->frontCell()] - rank_row_offset] += 1;
82 }
83}
84
85/***************************************************************************
86 * AlephTestModule::_FaceComputeSetValues *
87 ***************************************************************************/
88void AlephTestSchemeFaces::
89setValues(const Real deltaT, AlephMatrix* aleph_mat)
90{
91 // On flush les coefs
92 ENUMERATE_CELL (iCell, MESH_OWN_ACTIVE_CELLS(mesh()))
93 m_cell_coefs[iCell] = 0.;
94 // Faces 'inner'
95 debug() << "\33[37m[AlephTestSchemeFaces::setValues] inner-faces"
96 << "\33[0m";
97 ENUMERATE_FACE (iFace, INNER_ACTIVE_FACE_GROUP(allCells())) {
98 if (iFace->backCell().isOwn()) {
99 const Real surface = AlephTestModule::geoFaceSurface(*iFace, nodesCoordinates());
100 aleph_mat->setValue(m_cell_matrix_idx[iFace->backCell()],
101 m_cell_matrix_idx[iFace->frontCell()], -deltaT / surface);
102 m_cell_coefs[iFace->backCell()] += 1.0 / surface;
103 }
104 if (iFace->frontCell().isOwn()) {
105 const Real surface = AlephTestModule::geoFaceSurface(*iFace, nodesCoordinates());
106 aleph_mat->setValue(m_cell_matrix_idx[iFace->frontCell()],
107 m_cell_matrix_idx[iFace->backCell()], -deltaT / surface);
108 m_cell_coefs[iFace->frontCell()] += 1.0 / surface;
109 }
110 }
111 debug() << "\33[37m[AlephTestSchemeFaces::setValues] outer-faces"
112 << "\33[0m";
113 ENUMERATE_FACE (iFace, OUTER_ACTIVE_FACE_GROUP(allCells())) {
114 if (!iFace->cell(0).isOwn())
115 continue;
116 m_cell_coefs[iFace->cell(0)] += 1.0 / AlephTestModule::geoFaceSurface(*iFace, nodesCoordinates());
117 }
118 debug() << "\33[37m[AlephTestSchemeFaces::setValues] diagonale"
119 << "\33[0m";
120 ENUMERATE_CELL (iCell, MESH_OWN_ACTIVE_CELLS(mesh())) {
121 aleph_mat->setValue(m_cell_matrix_idx[iCell], m_cell_matrix_idx[iCell], 1.0 + deltaT * m_cell_coefs[iCell]);
122 }
123 debug() << "\33[37m[AlephTestSchemeFaces::setValues] done"
124 << "\33[0m";
125}
126
127/***************************************************************************
128 * AlephTestModule::_amrRefine *
129 ***************************************************************************/
130bool AlephTestSchemeFaces::
131amrRefine(RealArray& values, const Real trigRefine)
132{
133 ItacFunction(AlephTestSchemeFaces);
134 if (!options()->amr)
135 return false;
136 debug() << "\33[37m[AlephTestModule::_FaceAmrRefine]"
137 << "\33[0m";
139
140 /*ENUMERATE_CELL(iCell, allCells()){
141 debug()<<"\t\t[FaceAmrRefine] cell #"<<(iCell).localId();
142 ENUMERATE_FACE(iFace, (*iCell).faces()){
143 debug()<<"\t\t\t[FaceAmrRefine] face #"<<iFace->localId();
144 }
145 }*/
146
147 ENUMERATE_CELL (iCell, MESH_ALL_ACTIVE_CELLS(mesh())) {
148 if ((*iCell).level() == 1)
149 continue;
151 const Real T1 = values[m_cell_matrix_idx[iCell]];
152 const Real ecart_relatif = ECART_RELATIF(T0, T1);
153 Cell iItem = (*iCell);
154
155 if (ecart_relatif > trigRefine) {
156 //debug()<< "[AlephTestModule::_amrRefine] HIT ecart_relatif="<<ecart_relatif<<", cell_"<<(*iCell).localId();
157 cells_lid.add((*iCell).localId());
158 iItem.mutableItemBase().addFlags(ItemInternal::II_Refine);
159 }
160 }
161
162 if (cells_lid.size() == 0)
163 return false;
164
165 debug() << "\33[37m[AlephTestModule::_amrRefine] NOW refine"
166 << "\33[0m";
167 MESH_MODIFIER_REFINE_ITEMS(mesh());
168 mesh()->modifier()->endUpdate();
169
170 // Now callBack the values
171 CellInfoListView cells(mesh()->cellFamily());
172 //ItemInternalList faces = mesh()->faceFamily()->itemsInternal();
173 for (Integer i = 0, is = cells_lid.size(); i < is; ++i) {
174 Int32 lid = cells_lid[i];
175 Cell cell = cells[lid];
176
177 for (Integer j = 0, js = CELL_NB_H_CHILDREN(cell); j < js; ++j) {
178 //debug()<<"\t\t[amrRefineMesh] child cell #"<<cell.hChild(j).localId();
179 m_cell_temperature[cells[CELL_H_CHILD(cell, j).localId()]] = m_cell_temperature[cells[lid]];
180 auto faces = allCells().view()[CELL_H_CHILD(cell, j).localId()].toCell().faces();
181 Integer index = 0;
182 for (Face face : faces){
183 if (face.isSubDomainBoundary()) {
184 //debug() << "\t\t\t[amrRefineMesh] outer face #"<< iFace->localId()<<", index="<<iFace.index()<<", T="<<m_face_temperature[cell.face(iFace.index())];
185 m_face_temperature[face] = m_face_temperature[cell.face(index)];
186 }
187 else {
188 //debug() << "\t\t\t[amrRefineMesh] inner face #"<< iFace->localId();//<<", T="<<m_face_temperature[face.toFace()];
189 m_face_temperature[face] = 0;
190 }
191 ++index;
192 }
193 }
194 }
195
196 debug() << "\33[37m[AlephTestModule::_amrRefine] done"
197 << "\33[0m";
198 return true;
199}
200
201/***********************************
202 * AlephTestModule::_FaceAmrRefine *
203 ***********************************/
204bool AlephTestSchemeFaces::
205amrCoarsen(RealArray& values, const Real trigCoarsen)
206{
207 ItacFunction(AlephTestSchemeFaces);
208 if (!options()->amr)
209 return false;
210 debug() << "\33[37m[AlephTestModule::_FaceAmrCoarsen]"
211 << "\33[0m";
214 mesh::FaceReorienter faceReorienter(mesh());
215 mesh::DynamicMesh* dynMesh = dynamic_cast<mesh::DynamicMesh*>(mesh());
216 CellInfoListView cells(mesh()->cellFamily());
219
220 // Scan sur toutes les mailles, actives ET non actives
222 Cell cell = *iCell;
223 //onst Real Tp=m_cell_temperature[iCell];
224 Real oldTs[4];
225 Real newTs[4];
226 Real sumTs = 0.0;
227 bool coarsit = true;
228
229 //debug()<<"true="<<true<<", false="<<false;
230 if (cell.level() == 1)
231 continue; // On évite de travailler sur les feuilles
232
233 if (!CELL_HAS_H_CHILDREN(cell))
234 continue; // On évite les mailles qui n'ont pas d'enfants
235
236 // On scrute pour voir si tous les enfants sont bien actifs
237 for (Integer j = 0, js = CELL_NB_H_CHILDREN(cell); j < js; ++j)
238 coarsit &= CELL_H_CHILD(cell, j).isActive();
239 if (coarsit == false)
240 continue;
241
242 //debug()<<"\t\t[FaceAmrCoarsen] parent cell Tp="<<Tp<<", "<<cell.localId();
243 for (Integer j = 0, js = CELL_NB_H_CHILDREN(cell); j < js; ++j) {
244 oldTs[j] = m_cell_temperature[cells[CELL_H_CHILD(cell, j).localId()]];
245 newTs[j] = values[m_cell_matrix_idx[CELL_H_CHILD(cell, j)]];
246 sumTs += newTs[j];
247 coarsit &= (ECART_RELATIF(oldTs[j], newTs[j]) < trigCoarsen);
248 //debug()<<"\t\t\t[FaceAmrCoarsen] child cell #"<<cell.hChild(j).localId()<<", oldT="<<oldTs[j]<<", newT="<<newTs[j];
249 }
250 if (coarsit == false)
251 continue;
252
253 // on regarde les écarts entre enfants
254 for (Integer j = 0, js = CELL_NB_H_CHILDREN(cell); j < js; ++j)
255 coarsit &= (ECART_RELATIF(newTs[j], newTs[(j + 1) % 4]) < trigCoarsen);
256 if (coarsit == false)
257 continue;
258
259 debug() << "\n\t\t\t\t\t\t[FaceAmrCoarsen] parent cell to COARSE #" << cell.localId();
260
261 // On rajoute l'lid du parent au pool de cells à coarsener
262 parents_to_coarsen_lid.add((*iCell).localId());
263
264 // Et on la tag comme Active
265 (*iCell).mutableItemBase().removeFlags(ItemInternal::II_CoarsenInactive);
266 ARCANE_ASSERT(((*iCell).isActive()), ("Parent not active!"));
267
268 // On set la nouvell valeure de la maille
270
271 // On rajoute les lids des enfants pour les remover par la suite
272 for (Integer j = 0, js = CELL_NB_H_CHILDREN(cell); j < js; ++j) {
273 children_to_coarsen_lid.add(CELL_H_CHILD(cell, j).localId());
274 CELL_H_CHILD(cell, j).mutableItemBase().setFlags(CELL_H_CHILD(cell, j).itemBase().flags() | ItemInternal::II_Inactive); //II_Coarsen
275 }
276
277 // Now stare at the children to set up new faces' values
278 Cell parent = cell;
279 //const Cell &parent = cellFamily()->itemsInternal()[parents_to_coarsen_lid[i]];
280 for( Face face : parent.faces()) {
281 if ((!face.backCell().null()) && (!face.frontCell().null())) {
282 debug() << "\t\t\t[FaceAmrCoarsen] FOCUS face #" << face.localId() << ", "
283 << face.backCell().localId() << "->"
284 << face.frontCell().localId();
285 // Maintenant on va ratacher les voisins à notre parent
286 const Cell& neighbour = (face.backCell().localId() == parent.localId()) ? face.frontCell() : face.backCell();
287 debug() << "\t\t\t[FaceAmrCoarsen] neighbour #" << neighbour.localId() << ", level=" << neighbour.level();
288
289 // Le voisin du parent doit être un parent
290 ARCANE_ASSERT((neighbour.level() == 0), ("Wrong neighbour level!"));
291
292 // Si le voisin est actif, la face en cours est celle qui doit être utilisée
293 if (neighbour.isActive()) {
294 debug() << "\t\t\t[FaceAmrCoarsen] neighbour is ACTIVE";
295 debug() << "\t\t\t[FaceAmrCoarsen] hit: face_" << face.localId() << ": " << neighbour.localId() << "->" << parent.localId();
296 //faces_to_attach.add(face.localId());
297 //lids_to_be_attached.add(parent.localId());
298 //dynMesh->trueFaceFamily().replaceBackCellToFace(face.internal(),neighbour.internal());//face.backCell().internal());
299 //dynMesh->trueFaceFamily().replaceFrontCellToFace(face.internal(),parent.internal());//face.frontCell().internal());
300 //faceReorienter.checkAndChangeOrientation(face.internal());
301 continue;
302 }
303
304 {
305 int iFound = 0;
306 bool found[2];
307 found[0] = found[1] = false;
308 // Sinon, on racroche les faces des enfants de notre voisin vers notre parent
309 for (Integer j = 0, js = CELL_NB_H_CHILDREN(neighbour); j < js; ++j) {
310 //debug()<<"\t\t\t\t[FaceAmrCoarsen] neighbour child #"<<neighbour.hChild(j).localId();
311
312 auto faces = CELL_H_CHILD(neighbour, j).faces();
313 for (Face face : faces){
314 if (face.backCell().null())
315 continue;
316 if (face.frontCell().null())
317 continue;
318
319 Cell other = (face.frontCell().localId() == CELL_H_CHILD(neighbour, j).localId()) ? face.backCell() : face.frontCell();
320 //debug()<<"\t\t\t\t[FaceAmrCoarsen] neighbour child face #"<<face.localId()<<", "<< face.backCell().localId()<<"->"<< face.frontCell().localId();
321
322 // Si l''autre' est un parent, c'est pas ce que l'on cherche
323 if (other.level() == 0)
324 continue;
325
326 //debug()<<"\t\t\t\t[FaceAmrCoarsen] parent id="<<other.hParent().localId();
327 if (CELL_H_PARENT(other).localId() != parent.localId())
328 continue;
329
330 debug() << "\t\t\t\t[FaceAmrCoarsen] hit: face_" << face.localId() << ": " << CELL_H_CHILD(neighbour, j).localId() << "->" << parent.localId();
331 faces_to_attach.add(face.localId());
332 lids_to_be_attached.add(parent.localId());
333 found[iFound++] = true;
334 break;
335 }
336 if (iFound == 2)
337 break;
338 }
339 }
340 // ARCANE_ASSERT(((found[0]==true)&&(found[1]==true)),("Not found"));
341 }
342 else if (face.backCell().null()) {
343 debug() << "\t\t\t[FaceAmrCoarsen] skip face #" << face.localId() << ", ?->" << face.frontCell().localId() << " ";
344 }
345 else {
346 debug() << "\t\t\t[FaceAmrCoarsen] skip face #" << face.localId() << ", " << face.backCell().localId() << "->?"
347 << " ";
348 }
349 }
350 }
351
352 // S'il n'y a rien à faire, on exit
353 if (parents_to_coarsen_lid.size() == 0)
354 return false;
355
356 CellInfoListView cells_view(mesh()->cellFamily());
357 FaceInfoListView faces_view(mesh()->faceFamily());
358
359 // On remove les mailles
360 for (Integer j = 0, js = children_to_coarsen_lid.size(); j < js; ++j) {
361 //const Cell &cell=cellFamily()->itemsInternal()[children_to_coarsen_lid[j]];
362 //debug()<<"\t\t[FaceAmrCoarsen] REMOVING CELL_"<<children_to_coarsen_lid[j];
363 dynMesh->trueCellFamily().removeCell(cells_view[children_to_coarsen_lid[j]]);
364 //dynMesh->trueCellFamily().detachCell(cellFamily()->itemsInternal()[children_to_coarsen_lid[j]]);
365 /* ENUMERATE_FACE(iFace, cell.faces()){
366 dynMesh->trueFaceFamily().populateBackFrontCellsFromParentFaces(cell.internal());
367
368 }*/
369 }
370 //mesh()->modifier()->endUpdate();
371
372 // On ré-attache les faces
373 for (Integer j = 0, js = faces_to_attach.size(); j < js; ++j) {
375 if (face.itemBase().flags() & ItemInternal::II_HasBackCell) {
376 debug() << "\t\t[FaceAmrCoarsen] NOW patch face_" << faces_to_attach[j] << ": " << face.backCell().localId() << "->" << lids_to_be_attached[j];
377 //dynMesh->trueFaceFamily().replaceFrontCellToFace(face.internal(),cellFamily()->itemsInternal()[lids_to_be_attached[j]]);
378 dynMesh->trueFaceFamily().addFrontCellToFace(face, cells_view[lids_to_be_attached[j]]);
379 }
380 else {
381 debug() << "\t\t[FaceAmrCoarsen] NOW patch face_" << faces_to_attach[j] << ": " << face.frontCell().localId() << "->" << lids_to_be_attached[j];
382 //dynMesh->trueFaceFamily().replaceBackCellToFace(face.internal(),cellFamily()->itemsInternal()[lids_to_be_attached[j]]);
383 dynMesh->trueFaceFamily().addBackCellToFace(face, cells_view[lids_to_be_attached[j]]);
384 }
385 faceReorienter.checkAndChangeOrientation(face);
386 }
387 //faceFamily()->endUpdate();
388
389 // On met à jour nos changements
390 mesh()->modifier()->endUpdate();
391
392 debug() << "\t\t[FaceAmrCoarsen] nbCell=" << MESH_ALL_ACTIVE_CELLS(mesh()).size();
393
394 //dynMesh->trueCellFamily().allItems().internal()->clear();//m_all_active_cell_group=0;
395 /*ENUMERATE_CELL(iCell, allCells()){
396 debug()<<"\t\t[dump] cell #"<<(iCell).localId()<<" ("<<(*iCell).isActive()<<")";
397 ENUMERATE_FACE(iFace, (*iCell).faces()){
398 if ((!iFace->backCell().null())&&(!iFace->frontCell().null())){
399 debug()<<"\t\t\t[dump] face #"<<iFace->localId()<<", "\
400 <<iFace->backCell().localId()<<"->"\
401 <<iFace->frontCell().localId()\
402 <<" ("<<iFace->isActive()<<")";
403 }else if (iFace->backCell().null()){
404 debug()<<"\t\t\t[dump] face #"<<iFace->localId()<<", ?->" \
405 <<iFace->frontCell().localId()\
406 <<" ("<<iFace->isActive()<<")";
407 }else{
408 debug()<<"\t\t\t[dump] face #"<<iFace->localId()<<", " \
409 <<iFace->backCell().localId()<<"->?" \
410 <<" ("<<iFace->isActive()<<")";
411 }
412 }
413 }*/
414
415 // Et on informe l'appellant comme quoi il y a eu des changements
416 debug() << "[AlephTestModule::FaceAmrCoarsen] done";
417 return true;
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
#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.
Generation de la classe de base du Service.
Arcane::VariableCellReal m_cell_temperature
Variables du service.
CaseOptionsAlephTestSchemeFaces * options() const
Options du jeu de données du service.
Matrice d'un système linéaire.
Definition AlephMatrix.h:33
Tableau d'items de types quelconques.
Vue sur les informations des mailles.
Maille d'un maillage.
Definition Item.h:1178
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1255
Int32 level() const
Definition Item.h:1328
Vue sur les informations des faces.
Face d'une maille.
Definition Item.h:932
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
Definition Item.h:1604
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
Definition Item.h:1598
virtual IMeshModifier * modifier()=0
Interface de modification associée.
Int32 flags() const
Flags de l'entité
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:582
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
CellGroup allCells() const
Retourne le groupe contenant toutes les mailles.
VariableNodeReal3 & nodesCoordinates() const
Retourne les coordonnées des noeuds du maillage.
Structure contenant les informations pour créer un service.
Implémentation d'un maillage.
Definition DynamicMesh.h:97
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.