14#include "arcane/mesh/ItemRefinement.h"
17#include "arcane/utils/Real3.h"
18#include "arcane/utils/ArgumentException.h"
20#include "arcane/core/IParallelMng.h"
22#include "arcane/core/IMesh.h"
23#include "arcane/core/IMeshModifier.h"
24#include "arcane/core/IItemFamily.h"
25#include "arcane/core/Item.h"
26#include "arcane/core/ItemRefinementPattern.h"
27#include "arcane/core/VariableTypes.h"
28#include "arcane/core/GeometricUtilities.h"
29#include "arcane/core/ItemPrinter.h"
30#include "arcane/core/SharedVariable.h"
31#include "arcane/core/ItemVector.h"
34#include "arcane/mesh/MeshRefinement.h"
65, m_orig_nodes_coords(
mesh->nodesCoordinates())
88 Real3 pfc = Real3::null();
89 for (
Node node : face.nodes()) {
90 pfc += nodes_coords[node];
92 pfc /=
static_cast<Real>(face.nbNode());
104 for (
Integer i = 0; i < item->nbNode(); i++)
105 for (
Integer j = i + 1; j < item->nbNode(); j++) {
106 Real3 diff = (m_orig_nodes_coords[item->node(i)] - m_orig_nodes_coords[item->node(j)]);
107 h_min = std::min(h_min, diff.normL2());
109 m_cell_hmin[item] = h_min;
117updateChildHMin(ArrayView<ItemInternal*> refine_cells)
119 for (
Integer k = 0; k < refine_cells.size(); k++) {
120 Cell parent = refine_cells[k];
121 for (
UInt32 i = 0, nc = parent.nbHChildren(); i < nc; i++) {
122 Cell item = parent.hChild(i);
124 for (
Integer i = 0; i < item.nbNode(); i++)
125 for (
Integer j = i + 1; j < item.nbNode(); j++) {
126 Real3 diff = (m_orig_nodes_coords[item.node(i)] - m_orig_nodes_coords[item.node(j)]);
127 h_min = std::min(h_min, diff.normL2());
129 m_cell_hmin[item] = h_min;
141 for (
Integer i = 0; i < item.nbNode(); i++)
142 for (
Integer j = i + 1; j < item.nbNode(); j++) {
143 Real3 diff = (m_orig_nodes_coords[item.node(i)] - m_orig_nodes_coords[item.node(j)]);
144 h_min = std::min(h_min, diff.normL2());
160 ARCANE_ASSERT((item.
isActive()), (
"Refine non-active item is forbidden!"));
169 m_nb_cell_to_add = 0;
170 m_nb_face_to_add = 0;
171 m_nb_node_to_add = 0;
173 if (!has_hChildren) {
175 computeHChildren<typeID>(item, mesh_refinement);
176 debug() <<
"[ItemRefinement::refineOneCell] " << m_nb_cell_to_add <<
" new cells, "
177 << m_nb_node_to_add <<
" new nodes & " << m_nb_face_to_add <<
" faces";
181 m_nodes_lid.resize(m_nb_node_to_add);
182 m_mesh->modifier()->addNodes(m_nodes_unique_id, m_nodes_lid);
183 m_mesh->nodeFamily()->endUpdate();
185 for (
Integer i = 0; i < m_nb_node_to_add; ++i) {
186 m_orig_nodes_coords[nodes[m_nodes_lid[i]]] = m_nodes_to_create_coords[i];
192 m_faces_lid.resize(m_nb_face_to_add);
193 m_mesh->modifier()->addFaces(m_nb_face_to_add, m_faces_infos, m_faces_lid);
198 m_cells_lid.resize(m_nb_cell_to_add);
199 m_mesh->modifier()->addHChildrenCells(item, m_nb_cell_to_add, m_cells_infos, m_cells_lid);
202 for (
Integer i = 0; i < m_nb_cell_to_add; ++i) {
203 Item child = cells[m_cells_lid[i]];
209 for (
Integer c = 0; c < nb_hChildren; c++) {
212 ARCANE_ASSERT((child.isSubactive()), (
"child must be a sub active item!"));
227#if defined(ARCANE_DEBUG_ASSERT)
228 for (
Integer c = 0; c < nb_hChildren; c++) {
231 ARCANE_ASSERT((hParent == item), (
"parent-child relationship is not consistent"));
232 ARCANE_ASSERT((item.
hChild(c).
isActive()), (
"children must be active"));
234 ARCANE_ASSERT((item.
isAncestor()), (
"current item must be an ancestor!"));
248 ARCANE_ASSERT((!item.
isActive()), (
"Item is active!"));
254 computeOrigNodesCoords<typeID>(item, rp, sid);
260 if (mychild.
owner() != sid)
276 ARCANE_ASSERT((item.
isActive()), (
"item must be active!"));
283template <
int typeID>
void ItemRefinement::
289 const Int32 nb_hChildren = rp.getNbHChildren();
291 m_p.resize(nb_hChildren);
292 m_nodes_uid.resize(nb_hChildren);
296 for (
Integer i = 0; i < nb_nodes; ++i)
297 m_coord[i] = m_orig_nodes_coords[item.
node(i)];
300 m_cells_infos.
clear();
301 m_cells_infos.
reserve(nb_hChildren * (head_size + nb_nodes));
302 debug(
Trace::High) <<
"[refineOneCell] cells_infos reserved size is " << (nb_hChildren * (head_size + nb_nodes));
307 m_faces_infos.
clear();
313 typedef std::set<Int64> NodesSet;
315 Integer nb_cnodes_max_total = 0;
318 for (
Integer c = 0; c < nb_hChildren; c++) {
319 const Integer c_type_id = rp.hChildrenTypeId(c);
323 nb_cnodes_max_total += nb_cnodes;
324 m_p[c].resize(nb_cnodes);
325 m_nodes_uid[c].resize(nb_cnodes);
327 for (
Integer nc = 0; nc < nb_cnodes; nc++) {
329 m_p[c][nc] = Real3::null();
330 m_nodes_uid[c][nc] = NULL_ITEM_ID;
332 for (
Integer n = 0; n < nb_nodes; n++) {
334 const Real em_val = rp.refine_matrix(c, nc, n);
337 m_p[c][nc] += m_coord[n] * em_val;
343 nodes_set.insert(m_nodes_uid[c][nc]);
349 if (m_nodes_uid[c][nc] == NULL_ITEM_ID) {
351 debug(
Trace::Highest) <<
"\t[refineOneCell] assigning node " << nc <<
" to l'uid:" << m_nodes_uid[c][nc];
353 m_nb_node_to_add = m_nb_node_to_add + 1;
363 Int64 cell_unique_id = first_cell_uid + c;
364 debug(
Trace::Highest) <<
"[refineOneCell] CELL TYPE:" << c_type_id <<
", uid=" << cell_unique_id;
366 m_cells_infos.add(c_type_id);
367 m_cells_infos.add(cell_unique_id);
368 for (
Integer nc = 0; nc < nb_cnodes; nc++)
369 m_cells_infos.add(m_nodes_uid[c][nc]);
370 m_nb_cell_to_add = m_nb_cell_to_add + 1;
382 for (
Integer f = 0; f < nb_cface; f++) {
384 m_face.resize(nb_node_face);
385 Real3 pfc = Real3::null();
386 for (
Integer nc = 0; nc < nb_node_face; nc++) {
388 m_face[nc] = m_nodes_uid[c][node_face_rank];
389 pfc += m_p[c][node_face_rank];
391 pfc /=
static_cast<Real>(nb_node_face);
393 bool is_added =
false;
398 m_faces_infos.add(new_face_uid);
399 for (
Integer nc = 0; nc < nb_node_face; nc++)
400 m_faces_infos.add(m_face[nc]);
401 m_nb_face_to_add = m_nb_face_to_add + 1;
406 m_nodes_to_create_coords.clear();
407 m_nodes_to_create_coords.reserve(nb_cnodes_max_total);
408 m_nodes_unique_id.clear();
409 m_nodes_unique_id.reserve(nb_cnodes_max_total);
412 debug(
Trace::High) <<
"[refineOneCell] Create nodes and set their coordinates";
413 for (
Integer c = 0; c < nb_hChildren; c++) {
414 const Integer c_type_id = rp.hChildrenTypeId(c);
415 ItemTypeInfo* c_type = itm->
typeFromId(c_type_id);
418 for (
Integer nc = 0; nc < nb_cnodes; nc++) {
419 const Int64 uid = m_nodes_uid[c][nc];
420 if (nodes_set.find(uid) != nodes_set.end())
423 nodes_set.insert(uid);
424 m_nodes_to_create_coords.add(m_p[c][nc]);
425 m_nodes_unique_id.add(uid);
430 m_nb_node_to_add = node_local_id;
436template <
int typeID>
void ItemRefinement::
437computeOrigNodesCoords(
Cell item,
const ItemRefinementPatternT<typeID>& rp,
const Integer sid)
439 const Integer nb_nodes = item.nbNode();
440 m_coord.resize(nb_nodes);
441 for (
Integer i = 0; i < nb_nodes; ++i)
442 m_coord[i] = m_orig_nodes_coords[item.node(i)];
444 for (
Integer c = 0; c < item.nbHChildren(); c++) {
446 Cell mychild = item.hChild(c);
447 if (mychild.owner() != sid)
449 for (
Integer nc = 0; nc < mychild.nbNode(); nc++) {
451 Real3 new_pos = Real3::null();
452 bool calculated_new_pos =
false;
454 for (
Integer n = 0; n < nb_nodes; n++) {
457 const Real em_val = rp.refine_matrix(c, nc, n);
460 if ((em_val != 0.) && (em_val != 1.)) {
461 new_pos += em_val * m_coord[n];
462 calculated_new_pos =
true;
466 if (calculated_new_pos)
468 m_orig_nodes_coords[mychild.node(nc)] = new_pos;
476#define ARCANE_INSTANTIATE(typeID) \
477 template void ItemRefinement::refineOneCell<typeID>(Cell item_internal, MeshRefinement & mesh_refinement); \
478 template void ItemRefinement::coarsenOneCell<typeID>(Cell item_internal, const ItemRefinementPatternT<typeID>& rp); \
479 template void ItemRefinement::computeHChildren<typeID>(Cell item, MeshRefinement & mesh_refinement); \
480 template void ItemRefinement::computeOrigNodesCoords<typeID>(Cell item, const ItemRefinementPatternT<typeID>& rp, const Integer sid)
482ARCANE_INSTANTIATE(IT_Quad4);
483ARCANE_INSTANTIATE(IT_Tetraedron4);
484ARCANE_INSTANTIATE(IT_Pyramid5);
485ARCANE_INSTANTIATE(IT_Pentaedron6);
486ARCANE_INSTANTIATE(IT_Hexaedron8);
487ARCANE_INSTANTIATE(IT_HemiHexa7);
488ARCANE_INSTANTIATE(IT_HemiHexa6);
489ARCANE_INSTANTIATE(IT_HemiHexa5);
490ARCANE_INSTANTIATE(IT_AntiWedgeLeft6);
491ARCANE_INSTANTIATE(IT_AntiWedgeRight6);
492ARCANE_INSTANTIATE(IT_DiTetra5);
Declarations of types used in Arcane.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Int32 nbHChildren() const
Number of children for AMR.
Cell hChild(Int32 i) const
i-th AMR child
bool hasHChildren() const
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
virtual CellGroup allCells()=0
Group of all cells.
virtual ItemTypeMng * itemTypeMng() const =0
Associated entity type manager.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
Int32 flags() const
Flags of the entity.
Flags for entity characteristics.
@ II_Inactive
The entity is inactive //COARSEN_INACTIVE,.
@ II_Refine
The entity is marked for refinement.
@ II_JustAdded
The entity has just been added.
@ II_JustRefined
The entity has just been refined.
@ II_CoarsenInactive
The entity is inactive and has children tagged for coarsening.
@ II_Coarsen
The entity is marked for coarsening.
@ II_JustCoarsened
The entity has just been coarsened.
View of a list to obtain information about entities.
Internal structure of a mesh entity.
Integer node(Integer i) const
Local index in the cell of the i-th node of the face.
Integer typeId() const
Type of the face entity.
Integer nbNode() const
Number of nodes of the face.
Info on a mesh entity type.
LocalFace localFace(Integer id) const
Local connectivity of the i-th face of the cell.
Integer nbLocalNode() const
Number of nodes of the entity.
Integer nbLocalFace() const
Number of faces of the entity.
Mesh entity type manager.
static Int32 nbHChildrenByItemType(Integer type)
AMR.
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
Node node(Int32 i) const
i-th node of the entity
Int32 nbNode() const
Number of nodes of the entity.
Base class for a mesh element.
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
Int32 owner() const
Owner subdomain number of the entity.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
impl::ItemBase itemBase() const
Internal part of the entity.
Int16 type() const
Entity type.
void setFlags(Int32 f)
Sets the entity flags.
void addFlags(Int32 added_flags)
Adds the flags added_flags to those of the entity.
View of node information.
Class managing a 3-dimensional real vector.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
ITraceMng * traceMng() const
Trace manager.
Parameters necessary for building a variable.
ItemRefinement(IMesh *mesh)
static const Real TOLERENCE
AMR.
void refineOneCell(Cell item, MeshRefinement &mesh_refinement)
void coarsenOneCell(Cell item, const ItemRefinementPatternT< typeID > &rp)
Implementation of unstructured mesh refinement adaptation algorithms.
Int64 findOrAddFaceUid(const Real3 &face_center, const Real &tol, bool &is_added)
Int64 getFirstChildNewUid()
const ItemRefinementPatternT< typeID > & getRefinementPattern() const
Int64 findOrAddNodeUid(const Real3 &p, const Real &tol)
std::uint32_t UInt32
Unsigned integer type of 32 bits.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Quantity at the node of coordinate type.
double Real
Type representing a real number.
@ Cell
The mesh is AMR by cell.
std::int32_t Int32
Signed integer type of 32 bits.