15#include "arcane/utils/StringBuilder.h"
17#include "arcane/core/IGhostLayerMng.h"
18#include "arcane/core/IItemFamily.h"
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IMeshFactoryMng.h"
21#include "arcane/core/IMeshMng.h"
22#include "arcane/core/IMeshModifier.h"
23#include "arcane/core/IPrimaryMesh.h"
24#include "arcane/core/MeshBuildInfo.h"
25#include "arcane/core/IMeshSection.h"
26#include "arcane/core/IVariableMng.h"
27#include "arcane/core/VariableMetaData.h"
29#include "arcane/core/internal/IVariableInternal.h"
30#include "arcane/core/internal/IVariableMngInternal.h"
32#include "arcane/std/MeshCut_axl.h"
54 NodeOnEdge(
const Node first_node,
const Node second_node)
56 const Int64 a = first_node.uniqueId();
57 const Int64 b = second_node.uniqueId();
60 m_node1 = second_node;
65 m_node0 = second_node;
72 NodeOnEdge(
Int64 first_node,
Int64 second_node)
74 if (first_node < second_node) {
75 m_uid_node0 = first_node;
76 m_uid_node1 = second_node;
79 m_uid_node0 = second_node;
80 m_uid_node1 = first_node;
84 NodeOnEdge() =
default;
86 bool operator<(
const NodeOnEdge& other)
const
88 if (m_uid_node0 != other.m_uid_node0) {
89 return m_uid_node0 < other.m_uid_node0;
91 return m_uid_node1 < other.m_uid_node1;
94 bool operator==(
const NodeOnEdge& other)
const
96 return m_uid_node0 == other.m_uid_node0 && m_uid_node1 == other.m_uid_node1;
102 Int64 m_uid_node0 = -1;
103 Int64 m_uid_node1 = -1;
105 Int64 m_uid_new_node = -1;
106 Int32 m_owner_new_node = -1;
117 FaceLite(
const Ref<NodeOnEdge>& node0,
const Ref<NodeOnEdge>& node1)
118 : m_node0(node0->m_uid_node0 < node1->m_uid_node0 ? node0 : node1)
119 , m_node1(node0->m_uid_node0 < node1->m_uid_node0 ? node1 : node0)
121 const Int64 node00 = node0->m_uid_node0;
122 const Int64 node01 = node0->m_uid_node1;
123 const Int64 node10 = node1->m_uid_node0;
124 const Int64 node11 = node1->m_uid_node1;
126 if (node00 < node10) {
130 else if (node00 > node10) {
135 if (node01 == node11) {
138 if (node01 < node11) {
149 bool operator<(
const FaceLite& other)
const
151 return m_node0->operator<(*(other.m_node0.get())) || (m_node0->operator==(*(other.m_node0.get())) && m_node1->operator<(*(other.m_node1.get())));
154 bool operator==(
const FaceLite& other)
const
156 return m_node0->operator==(*(other.m_node0.get())) && m_node1->operator==(*(other.m_node1.get()));
159 Ref<NodeOnEdge> m_node0;
160 Ref<NodeOnEdge> m_node1;
162 Int64 m_uid_new_face = -1;
163 Int32 m_owner_new_face = -1;
172struct NodeIntersection
174 NodeIntersection(
const Node first_node,
const Node second_node,
const Real3& intersection_pos)
175 : m_new_node(
makeRef(new NodeOnEdge(first_node, second_node)))
176 , m_intersection_pos(intersection_pos)
179 NodeIntersection(
Int64 first_node,
Int64 second_node,
const Real3& intersection_pos)
180 : m_new_node(
makeRef(new NodeOnEdge(first_node, second_node)))
181 , m_intersection_pos(intersection_pos)
184 NodeIntersection() =
default;
186 bool operator<(
const NodeIntersection& other)
const
188 return m_new_node->operator<(*(other.m_new_node.get()));
191 bool operator==(
const NodeIntersection& other)
const
193 return m_new_node->operator==(*(other.m_new_node.get()));
196 Ref<NodeOnEdge> m_new_node;
197 Real3 m_intersection_pos{ -1 };
203struct UnknownNodeOrFace
205 UnknownNodeOrFace(
Int64 node0_uid,
Int64 node1_uid,
Int32 who) : m_node0_uid(node0_uid), m_node1_uid(node1_uid), m_who(who){}
206 bool null()
const {
return m_who == -1;}
207 bool operator==(
const UnknownNodeOrFace& other)
const{
return m_node0_uid == other.m_node0_uid && m_node1_uid == other.m_node1_uid;}
222 UniqueArray<ArrayView<T>> dim1;
223 UniqueArray<Array2View<T>> dim2;
227struct VariableGroupType
229 bool isUnknownUsed() {
return !(unknown.dim1.empty() && unknown.dim2.empty()); }
230 bool isCellsUsed() {
return !(cells.dim1.empty() && cells.dim2.empty()); }
231 bool isFacesUsed() {
return !(faces.dim1.empty() && faces.dim2.empty()); }
232 bool isNodesUsed() {
return !(nodes.dim1.empty() && nodes.dim2.empty()); }
234 VariableGroup<T> unknown;
235 VariableGroup<T> cells;
236 VariableGroup<T> faces;
237 VariableGroup<T> nodes;
241struct VariableOriClone
243 VariableGroupType<T> ori;
244 VariableGroupType<T> clone;
285 return m_cloned_mesh->handle();
291 void _createVariables();
314 void _updateArrayVariable(
UniqueArray<Cell>& ori_cells, T, VariableOriClone<T>& voc);
323 Int32 m_mesh_uid = -1;
329ARCANE_REGISTER_SERVICE_MESHCUT(MeshCut, MeshCutService);
358 m_mesh_uid = unique_id;
367 return m_variables_cloned;
376 if (
mesh()->ghostLayerMng()->nbGhostLayer() < 1) {
377 ARCANE_FATAL(
"A ghost layer is required for this service");
389 if (m_cloned_mesh !=
nullptr) {
393 if (mesh()->dimension() != 3) {
397 IMeshMng* mm = subDomain()->meshMng();
399 if (m_mesh_uid == -1) {
401 m_mesh_uid =
options()->getUniqueIdServiceMesh();
408 String service_mesh_name = mesh()->name() +
"_MeshCut" + m_mesh_uid;
410 MeshHandle* mesh_handle = mm->findMeshHandle(service_mesh_name,
false);
412 if (mesh_handle ==
nullptr) {
413 IParallelMng* pm = subDomain()->parallelMng();
414 MeshBuildInfo mbi(service_mesh_name);
418 mbi.addParallelMng(
makeRef(pm));
419 m_cloned_mesh = mm->meshFactoryMng()->createMesh(mbi);
420 m_cloned_mesh->modifier()->setDynamic(
true);
421 m_cloned_mesh->setDimension(2);
422 m_cloned_mesh->endAllocate();
425 m_cloned_mesh = mesh_handle->mesh()->toPrimaryMesh();
426 m_cloned_mesh->modifier()->clearItems();
437 IVariableMng* variable_mng = m_cloned_mesh->variableMng();
438 for (VariableCollection::Enumerator i(m_variables_ori); ++i;) {
440 Ref vmd(var->createMetaDataRef());
441 const String& mesh_name = vmd->meshName();
442 if (mesh_name.null()) {
443 ARCANE_FATAL(
"Only variables with support are supported.");
445 if (vmd->isPartial()) {
448 const String& full_type = vmd->fullType();
449 const String& base_name = vmd->baseName();
450 Integer property = vmd->property();
451 const String& family_name = vmd->itemFamilyName();
455 VariableBuildInfo vbi(m_cloned_mesh, base_name, family_name, property);
456 VariableRef* variable_ref = variable_mng->_internalApi()->createVariableFromType(full_type, vbi);
459 m_variables_cloned.add(variable_ref->variable());
469 auto [p0, normal] = m_plans[plan_pos];
471 const Int32 mesh_dim = mesh()->dimension();
476 UniqueArray<Int32> face_already_computed;
489 UniqueArray<NodeIntersection> point_coords_tmp;
494 bool has_face_on_plane =
false;
496 bool cell_useful =
true;
497 Int32 nb_node_on_plane = 0;
502 bool has_neg =
false;
503 bool has_pos =
false;
504 for (Node node : cell.nodes()) {
505 Real d = node_dist[node];
516 if (!(has_neg && has_pos))
524 if (nb_node_on_plane >= mesh_dim) {
525 for (Face face : cell.faces()) {
529 if (face.nbNode() != nb_node_on_plane)
532 bool has_egal =
true;
533 for (Node node : face.nodes()) {
534 if (node_dist[node] != 0) {
544 if (face_already_computed.contains(face.localId())) {
553 face_already_computed.add(face.localId());
554 for (Node node : face.nodes()) {
555 auto ni = NodeIntersection{ node, node, node_coord[node] };
556 point_coords_tmp.add(ni);
558 has_face_on_plane =
true;
569 if (!has_face_on_plane) {
573 static constexpr Integer edges_tetraedron4[6][2] = {
574 { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 }
576 static constexpr Integer edges_pyramid5[8][2] = {
577 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 }, { 2, 4 }, { 3, 4 }
579 static constexpr Integer edges_pentaedron6[9][2] = {
580 { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 4 }, { 4, 5 }, { 5, 3 }
582 static constexpr Integer edges_hexaedron8[12][2] = {
583 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }
587 const Integer(*edge_def)[2] =
nullptr;
589 auto type = cell.itemTypeId();
591 if (type == ITI_Tetraedron4) {
593 edge_def = edges_tetraedron4;
595 else if (type == ITI_Pyramid5) {
597 edge_def = edges_pyramid5;
599 else if (type == ITI_Pentaedron6) {
601 edge_def = edges_pentaedron6;
603 else if (type == ITI_Hexaedron8) {
605 edge_def = edges_hexaedron8;
609 ARCANE_FATAL(
"Cell type not supported -- type: {0}", type);
613 for (
Integer i = 0; i < nb_edges; ++i) {
614 Node node0 = cell.node(edge_def[i][0]);
615 Node node1 = cell.node(edge_def[i][1]);
617 bool need_compute_intersection =
true;
620 if (node_dist[node0] == 0) {
621 const Real3 p = node_coord[node0];
623 auto ni = NodeIntersection{ node0, node0, p };
625 if (!point_coords_tmp.contains(ni)) {
626 point_coords_tmp.add(ni);
628 need_compute_intersection =
false;
632 if (node_dist[node1] == 0) {
633 const Real3 p = node_coord[node1];
635 auto ni = NodeIntersection{ node1, node1, p };
637 if (!point_coords_tmp.contains(ni)) {
638 point_coords_tmp.add(ni);
640 need_compute_intersection =
false;
644 if (need_compute_intersection && node_dist[node0] * node_dist[node1] < 0) {
648 Real t = std::abs(node_dist[node0]) / (std::abs(node_dist[node0]) + std::abs(node_dist[node1]));
652 p.x = node_coord[node0].x + t * (node_coord[node1].x - node_coord[node0].x);
653 p.y = node_coord[node0].y + t * (node_coord[node1].y - node_coord[node0].y);
654 p.z = node_coord[node0].z + t * (node_coord[node1].z - node_coord[node0].z);
656 auto ni = NodeIntersection{ node0, node1, p };
658 if (!point_coords_tmp.contains(ni)) {
659 point_coords_tmp.add(ni);
666 if (point_coords_tmp.size() >= mesh_dim) {
669 if (point_coords_tmp.size() > 6)
670 ARCANE_FATAL(
"Pas implem : {0}", point_coords_tmp.size());
672 new_cells.add(point_coords_tmp.size());
673 new_cells.add(sd_nb_cell);
679 for (
const auto& node : point_coords_tmp) {
680 bary += node.m_intersection_pos;
682 bary /= point_coords_tmp.size();
686 const Real3 arbitrary = (std::abs(normal.x) > 0.9) ? Real3{ 0.0, 1.0, 0.0 } : Real3{ 1.0, 0.0, 0.0 };
694 UniqueArray<Int64> indices;
695 indices.reserve(point_coords_tmp.size());
696 for (
Int64 i = 0; i < point_coords_tmp.size(); ++i) {
700 std::sort(indices.begin(), indices.end(),
702 const Real3& pa = point_coords_tmp[ia].m_intersection_pos;
703 const Real3& pb = point_coords_tmp[ib].m_intersection_pos;
706 const Real3 va{ pa - bary };
707 const Real3 vb{ pb - bary };
717 const Real angle_a = std::atan2(a_y, a_x);
718 const Real angle_b = std::atan2(b_y, b_x);
720 return angle_a < angle_b;
729 for (
Int64& idx : indices) {
731 std::optional<Int64> pos = new_nodes.span().findFirst(point_coords_tmp[idx]);
737 new_cells.add(
static_cast<Int32>(pos.value()) + ajust_node_pos);
742 NodeIntersection& elem = point_coords_tmp[idx];
745 if (elem.m_new_node->m_node0.owner() == elem.m_new_node->m_node1.owner()) {
746 elem.m_new_node->m_owner_new_node = elem.m_new_node->m_node0.owner();
752 if (elem.m_new_node->m_node0.isOwn()) {
753 elem.m_new_node->m_uid_new_node = sd_nb_node++;
757 elem.m_new_node->m_uid_new_node = -2;
760 new_cells.add(new_nodes.size() + ajust_node_pos);
761 idx = new_nodes.size();
767 Int64 idxm1 = indices[indices.size() - 1];
768 for (
Int64 idx : indices) {
769 FaceLite fl(new_nodes[idx].m_new_node, new_nodes[idxm1].m_new_node);
770 if (!new_faces.contains(fl)) {
778 if (new_nodes[idx].m_new_node->m_owner_new_node == new_nodes[idxm1].m_new_node->m_owner_new_node) {
779 fl.m_owner_new_face = new_nodes[idx].m_new_node->m_owner_new_node;
780 if (fl.m_owner_new_face == subDomain()->subDomainId()) {
781 fl.m_uid_new_face = sd_nb_face++;
784 fl.m_uid_new_face = -2;
794 point_coords_tmp.clear();
802_makeUniqueCellUID(Int32 sd_nb_cell, UniqueArray<Int64>& new_cells, UniqueArray<NodeIntersection>& new_nodes)
804 IParallelMng* pm = subDomain()->parallelMng();
806 Int32 decal = sd_nb_cell;
807 pm->scan(MessagePassing::ReduceSum, ArrayView{ 1, &decal });
820 while (pos0 < new_cells.size()) {
821 Int64 type = new_cells[pos0++];
822 new_cells[pos0++] += decal;
824 for (Int32 i = 0; i < type; ++i) {
825 Int64& pos_to_uid = new_cells[pos0++];
826 pos_to_uid = new_nodes[pos_to_uid].m_new_node->m_uid_new_node;
836_fillNodeUID(Int32& sd_nb_node, UniqueArray<NodeIntersection>& new_nodes)
846 IParallelMng* pm = subDomain()->parallelMng();
847 Int32 my_proc = pm->commRank();
848 UniqueArray<UniqueArray<Ref<NodeOnEdge>>> requested_nodes(subDomain()->nbSubDomain());
909 UniqueArray<UniqueArray<Int64>> request_uid(subDomain()->nbSubDomain());
911 debug() <<
"[Node][" << my_proc <<
"] Step 1";
913 for (
auto& elem : new_nodes) {
915 if (elem.m_new_node->m_uid_new_node >= 0) {
920 if (elem.m_new_node->m_owner_new_node < 0) {
922 Node node0 = elem.m_new_node->m_node0;
923 Node node1 = elem.m_new_node->m_node1;
929 Int64 min_uid = INT64_MAX;
930 Int32 owner_min = -1;
931 for (Cell cell0 : node0.cells()) {
932 for (Cell cell1 : node1.cells()) {
933 if (cell0 == cell1) {
934 if (cell0.uniqueId() < min_uid) {
935 min_uid = cell0.uniqueId();
936 owner_min = cell0.owner();
943 if (owner_min == subDomain()->subDomainId()) {
944 elem.m_new_node->m_owner_new_node = subDomain()->subDomainId();
945 elem.m_new_node->m_uid_new_node = sd_nb_node++;
955 elem.m_new_node->m_owner_new_node = owner_min;
956 elem.m_new_node->m_uid_new_node = -2;
962 request_uid[elem.m_new_node->m_owner_new_node].add(elem.m_new_node->m_uid_node0);
963 request_uid[elem.m_new_node->m_owner_new_node].add(elem.m_new_node->m_uid_node1);
965 requested_nodes[elem.m_new_node->m_owner_new_node].add(elem.m_new_node);
975 request_uid[elem.m_new_node->m_owner_new_node].add(elem.m_new_node->m_uid_node0);
976 request_uid[elem.m_new_node->m_owner_new_node].add(elem.m_new_node->m_uid_node1);
978 requested_nodes[elem.m_new_node->m_owner_new_node].add(elem.m_new_node);
988 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain() * 2);
990 debug() <<
"[Node][" << my_proc <<
"] Step 1.2";
992 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
993 if (sr == subDomain()->subDomainId()) {
996 Int32 size = request_uid[sr].size();
997 requests[sr * 2] = pm->send(ArrayView{ 1, &size }, sr,
false);
998 requests[sr * 2 + 1] = pm->send(request_uid[sr], sr,
false);
1002 pm->waitAllRequests(requests);
1073 UniqueArray<UniqueArray<Int64>> answers_uid(subDomain()->nbSubDomain());
1075 UniqueArray<UnknownNodeOrFace> unknown_node;
1076 debug() <<
"[Node][" << my_proc <<
"] Step 2";
1078 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1079 if (sr == subDomain()->subDomainId()) {
1083 pm->recv(ArrayView{ 1, &size }, sr);
1085 UniqueArray<Int64> requested_uid(size);
1086 pm->recv(requested_uid, sr);
1089 answers_uid[sr].add(0);
1092 for (Int32 ipair_uid = 0; ipair_uid < requested_uid.size(); ipair_uid += 2) {
1094 std::optional<Int64> pos = new_nodes.span().findFirst(NodeIntersection{ requested_uid[ipair_uid], requested_uid[ipair_uid + 1], Real3{ 0 } });
1096 answers_uid[sr].add(new_nodes[pos.value()].m_new_node->m_uid_new_node);
1110 answers_uid[sr].add(-1);
1111 unknown_node.add({ requested_uid[ipair_uid], requested_uid[ipair_uid + 1], sr });
1117 answers_uid[sr][0] = answers_uid[sr].size() - 1;
1120 UniqueArray<Int64> who;
1121 debug() <<
"[Node][" << my_proc <<
"] Step 2.2";
1127 for (Int32 i = 0; i < unknown_node.size(); ++i) {
1128 if (unknown_node[i].null())
1131 who.add(unknown_node[i].m_who);
1132 unknown_node[i].m_who = -1;
1133 for (Int32 j = i + 1; j < unknown_node.size(); ++j) {
1134 if (unknown_node[j].null())
1136 if (unknown_node[j] == unknown_node[i]) {
1137 who.add(unknown_node[j].m_who);
1138 unknown_node[j].m_who = -1;
1142 for (
auto proc : who) {
1143 answers_uid[proc].add(unknown_node[i].m_node0_uid);
1144 answers_uid[proc].add(unknown_node[i].m_node1_uid);
1145 answers_uid[proc].add(who.size());
1146 answers_uid[proc].addRange(who);
1152 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain() * 2);
1155 debug() <<
"[Node][" << my_proc <<
"] Step 2.3";
1156 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1157 if (sr == subDomain()->subDomainId()) {
1161 Int32 size = answers_uid[sr].size();
1162 requests[sr * 2] = pm->send(ArrayView{ 1, &size }, sr,
false);
1163 requests[sr * 2 + 1] = pm->send(answers_uid[sr], sr,
false);
1168 pm->waitAllRequests(requests);
1287 UniqueArray<UniqueArray<Int64>> request_uid(subDomain()->nbSubDomain());
1288 UniqueArray<UniqueArray<Ref<NodeOnEdge>>> requested_nodes2(subDomain()->nbSubDomain());
1291 debug() <<
"[Node][" << my_proc <<
"] Step 3";
1294 bool need_more_comm =
false;
1296 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1297 if (sr == subDomain()->subDomainId()) {
1301 Int32 total_size = 0;
1302 pm->recv(ArrayView{ 1, &total_size }, sr);
1304 UniqueArray<Int64> answered_uid(total_size);
1305 pm->recv(answered_uid, sr);
1307 if (total_size == 1) {
1311 Int32 answer_to_request_size =
static_cast<Int32
>(answered_uid[0]);
1313 Span<Int64> answer_to_request = answered_uid.subView(1, answer_to_request_size);
1314 Span<Int64> additionnal_answer = answered_uid.subView(answer_to_request_size+1, answered_uid.size() - (answer_to_request_size+1));
1321 for (Int32 answer = 0; answer < answer_to_request.size(); ++answer) {
1322 Ref<NodeOnEdge> node_on_edge = requested_nodes[sr][answer];
1324 if (answer_to_request[answer] != -1) {
1325 node_on_edge->m_uid_new_node = answer_to_request[answer];
1333 while (pos < additionnal_answer.size()) {
1334 Int64& uid0 = additionnal_answer[pos++];
1335 Int64 uid1 = additionnal_answer[pos++];
1336 Int64 decal = additionnal_answer[pos++];
1337 if (uid0 == node_on_edge->m_uid_node0 && uid1 == node_on_edge->m_uid_node1) {
1343 if (pos >= additionnal_answer.size()) {
1344 ARCANE_FATAL(
"Unknown node -- UID0 : {0} -- UID1 : {1}", node_on_edge->m_uid_node0, node_on_edge->m_uid_node1);
1350 Span<Int64> sub_additionnal_answer;
1352 while (pos < additionnal_answer.size()) {
1353 Int64 pos_node_in_array = additionnal_answer[pos++];
1355 Int64 decal = additionnal_answer[pos++];
1357 Ref<NodeOnEdge> node_on_edge = requested_nodes[sr][pos_node_in_array];
1358 sub_additionnal_answer = additionnal_answer.subSpan(pos, decal);
1365 Node node0 = node_on_edge->m_node0;
1366 Node node1 = node_on_edge->m_node1;
1372 Int64 min_uid = INT64_MAX;
1373 Int32 owner_min = -1;
1374 for (Cell cell0 : node0.cells()) {
1375 for (Cell cell1 : node1.cells()) {
1376 if (cell0 == cell1) {
1377 if (cell0.uniqueId() < min_uid && sub_additionnal_answer.contains(cell0.owner())) {
1378 min_uid = cell0.uniqueId();
1379 owner_min = cell0.owner();
1386 if (owner_min == subDomain()->subDomainId()) {
1387 node_on_edge->m_owner_new_node = subDomain()->subDomainId();
1388 node_on_edge->m_uid_new_node = sd_nb_node++;
1391 if (sub_additionnal_answer.size() > 1) {
1392 need_more_comm =
true;
1400 for (
auto proc : sub_additionnal_answer) {
1401 if (proc == my_proc)
1403 request_uid[proc].add(node_on_edge->m_uid_new_node);
1409 else if (owner_min >= 0) {
1410 need_more_comm =
true;
1411 node_on_edge->m_owner_new_node = owner_min;
1412 node_on_edge->m_uid_new_node = -2;
1414 if (request_uid[my_proc].empty()) {
1415 request_uid[my_proc].resize(subDomain()->nbSubDomain(), 0);
1418 request_uid[my_proc][owner_min]++;
1420 requested_nodes2[owner_min].add(node_on_edge);
1436 if (need_more_comm) {
1438 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain());
1441 debug() <<
"[Node][" << my_proc <<
"] Step 3.2";
1443 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1444 if (sr == subDomain()->subDomainId()) {
1448 if (request_uid[sr].empty())
continue;
1449 requests[sr] = pm->send(request_uid[sr], sr,
false);
1453 pm->waitAllRequests(requests);
1468 if (!request_uid[my_proc].empty()) {
1470 debug() <<
"[Node][" << my_proc <<
"] Step 4";
1472 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1473 if (sr == subDomain()->subDomainId()) {
1477 Int64 size = request_uid[my_proc][sr];
1478 if (size == 0)
continue;
1483 UniqueArray<Int64> requested_uid(size);
1484 pm->recv(requested_uid, sr);
1485 for (Int32 i = 0; i < size; ++i) {
1486 Ref<NodeOnEdge> node_on_edge = requested_nodes2[sr][i];
1487 node_on_edge->m_uid_new_node = requested_uid[i];
1501Int32 MeshCutService::
1502_makeUniqueNodeUID(Int32 sd_nb_node, UniqueArray<NodeIntersection>& new_nodes)
1504 IParallelMng* pm = subDomain()->parallelMng();
1506 UniqueArray<Int32> all_nb_node(pm->commSize());
1507 pm->allGather(ArrayView{ 1, &sd_nb_node }, all_nb_node);
1510 for (
auto& elem : all_nb_node) {
1511 const Int32 old = elem;
1518 for (
auto& elem : new_nodes) {
1519 elem.m_new_node->m_uid_new_node += all_nb_node[elem.m_new_node->m_owner_new_node];
1527void MeshCutService::
1528_fillFaceUID(Int32& sd_nb_face, UniqueArray<FaceLite>& new_faces)
1531 IParallelMng* pm = subDomain()->parallelMng();
1532 Int32 my_proc = pm->commRank();
1533 UniqueArray<UniqueArray<Int32>> requested_faces(subDomain()->nbSubDomain());
1537 UniqueArray<UniqueArray<Int64>> request_uid(subDomain()->nbSubDomain());
1539 debug() <<
"[Face][" << my_proc <<
"] Étape 1";
1541 for (
auto& elem : new_faces) {
1543 if (elem.m_uid_new_face >= 0) {
1546 if (elem.m_owner_new_face < 0) {
1548 Node node00 = elem.m_node0->m_node0;
1549 Node node01 = elem.m_node0->m_node1;
1550 Node node10 = elem.m_node1->m_node0;
1551 Node node11 = elem.m_node1->m_node1;
1553 Int64 min_uid = INT64_MAX;
1554 Int32 owner_min = -1;
1557 for (Cell cell00 : node00.cells()) {
1558 for (Cell cell01 : node01.cells()) {
1559 if (cell00 == cell01) {
1560 for (Cell cell10 : node10.cells()) {
1561 if (cell01 == cell10) {
1562 for (Cell cell11 : node11.cells()) {
1563 if (cell10 == cell11) {
1564 if (cell11.uniqueId() < min_uid) {
1565 min_uid = cell11.uniqueId();
1566 owner_min = cell11.owner();
1576 if (owner_min == subDomain()->subDomainId()) {
1577 elem.m_owner_new_face = subDomain()->subDomainId();
1578 elem.m_uid_new_face = sd_nb_face++;
1586 elem.m_owner_new_face = owner_min;
1587 elem.m_uid_new_face = -2;
1588 request_uid[elem.m_owner_new_face].add(elem.m_node0->m_uid_new_node);
1589 request_uid[elem.m_owner_new_face].add(elem.m_node1->m_uid_new_node);
1591 requested_faces[elem.m_owner_new_face].add(iter);
1599 request_uid[elem.m_owner_new_face].add(elem.m_node0->m_uid_new_node);
1600 request_uid[elem.m_owner_new_face].add(elem.m_node1->m_uid_new_node);
1602 requested_faces[elem.m_owner_new_face].add(iter);
1611 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain() * 2);
1614 debug() <<
"[Face][" << my_proc <<
"] Étape 1.2";
1616 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1617 if (sr == subDomain()->subDomainId()) {
1620 Int32 size = request_uid[sr].size();
1621 requests[sr * 2] = pm->send(ArrayView{ 1, &size }, sr,
false);
1622 requests[sr * 2 + 1] = pm->send(request_uid[sr], sr,
false);
1626 pm->waitAllRequests(requests);
1631 UniqueArray<UniqueArray<Int64>> answers_uid(subDomain()->nbSubDomain());
1633 UniqueArray<UnknownNodeOrFace> unknown_face;
1634 debug() <<
"[Face][" << my_proc <<
"] Étape 2";
1636 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1637 if (sr == subDomain()->subDomainId()) {
1641 pm->recv(ArrayView{ 1, &size }, sr);
1643 UniqueArray<Int64> requested_uid(size);
1644 pm->recv(requested_uid, sr);
1646 answers_uid[sr].add(0);
1648 for (Int32 ipair_uid = 0; ipair_uid < requested_uid.size(); ipair_uid += 2) {
1649 std::optional<Int64> pos = _find(new_faces, requested_uid[ipair_uid], requested_uid[ipair_uid + 1]);
1651 answers_uid[sr].add(new_faces[pos.value()].m_uid_new_face);
1665 answers_uid[sr].add(-1);
1666 unknown_face.add({ requested_uid[ipair_uid], requested_uid[ipair_uid + 1], sr });
1672 answers_uid[sr][0] = answers_uid[sr].size() - 1;
1675 UniqueArray<Int64> who;
1676 debug() <<
"[Face][" << my_proc <<
"] Étape 2.2";
1678 for (Int32 i = 0; i < unknown_face.size(); ++i) {
1679 if (unknown_face[i].null())
1682 who.add(unknown_face[i].m_who);
1683 unknown_face[i].m_who = -1;
1684 for (Int32 j = i + 1; j < unknown_face.size(); ++j) {
1685 if (unknown_face[j].null())
1687 if (unknown_face[j] == unknown_face[i]) {
1688 who.add(unknown_face[j].m_who);
1689 unknown_face[j].m_who = -1;
1693 for (
auto proc : who) {
1694 answers_uid[proc].add(unknown_face[i].m_node0_uid);
1695 answers_uid[proc].add(unknown_face[i].m_node1_uid);
1696 answers_uid[proc].add(who.size());
1697 answers_uid[proc].addRange(who);
1703 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain() * 2);
1706 debug() <<
"[Face][" << my_proc <<
"] Étape 2.3";
1707 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1708 if (sr == subDomain()->subDomainId()) {
1712 Int32 size = answers_uid[sr].size();
1713 requests[sr * 2] = pm->send(ArrayView{ 1, &size }, sr,
false);
1714 requests[sr * 2 + 1] = pm->send(answers_uid[sr], sr,
false);
1717 pm->waitAllRequests(requests);
1721 UniqueArray<UniqueArray<Int64>> request_uid(subDomain()->nbSubDomain());
1722 UniqueArray<UniqueArray<Int32>> requested_faces2(subDomain()->nbSubDomain());
1725 debug() <<
"[Face][" << my_proc <<
"] Étape 3";
1727 bool need_more_comm =
false;
1729 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1730 if (sr == subDomain()->subDomainId()) {
1734 Int32 total_size = 0;
1735 pm->recv(ArrayView{ 1, &total_size }, sr);
1737 UniqueArray<Int64> answered_uid(total_size);
1738 pm->recv(answered_uid, sr);
1740 if (total_size == 1) {
1744 Int32 answer_to_request_size =
static_cast<Int32
>(answered_uid[0]);
1746 Span<Int64> answer_to_request = answered_uid.subView(1, answer_to_request_size);
1747 Span<Int64> additionnal_answer = answered_uid.subView(answer_to_request_size + 1, answered_uid.size() - (answer_to_request_size + 1));
1753 for (Int32 answer = 0; answer < answer_to_request.size(); ++answer) {
1754 FaceLite& face_lite = new_faces[requested_faces[sr][answer]];
1756 if (answer_to_request[answer] != -1) {
1757 face_lite.m_uid_new_face = answer_to_request[answer];
1765 while (pos < additionnal_answer.size()) {
1766 Int64& uid0 = additionnal_answer[pos++];
1767 Int64 uid1 = additionnal_answer[pos++];
1768 Int64 decal = additionnal_answer[pos++];
1769 if (uid0 == face_lite.m_node0->m_uid_new_node && uid1 == face_lite.m_node1->m_uid_new_node) {
1775 if (pos >= additionnal_answer.size()) {
1776 ARCANE_FATAL(
"Unknown face -- UID0 : {0} -- UID1 : {1}", face_lite.m_node0->m_uid_new_node, face_lite.m_node1->m_uid_new_node);
1782 Span<Int64> sub_additionnal_answer;
1784 while (pos < additionnal_answer.size()) {
1785 Int64 pos_node_in_array = additionnal_answer[pos++];
1787 Int64 decal = additionnal_answer[pos++];
1789 FaceLite& face_lite = new_faces[requested_faces[sr][pos_node_in_array]];
1790 sub_additionnal_answer = additionnal_answer.subSpan(pos, decal);
1798 Node node00 = face_lite.m_node0->m_node0;
1799 Node node01 = face_lite.m_node0->m_node1;
1800 Node node10 = face_lite.m_node1->m_node0;
1801 Node node11 = face_lite.m_node1->m_node1;
1803 Int64 min_uid = INT64_MAX;
1804 Int32 owner_min = -1;
1807 for (Cell cell00 : node00.cells()) {
1808 for (Cell cell01 : node01.cells()) {
1809 if (cell00 == cell01) {
1810 for (Cell cell10 : node10.cells()) {
1811 if (cell01 == cell10) {
1812 for (Cell cell11 : node11.cells()) {
1813 if (cell10 == cell11) {
1814 if (cell11.uniqueId() < min_uid && sub_additionnal_answer.contains(cell11.owner())) {
1815 min_uid = cell11.uniqueId();
1816 owner_min = cell11.owner();
1827 if (owner_min == subDomain()->subDomainId()) {
1828 face_lite.m_owner_new_face = subDomain()->subDomainId();
1829 face_lite.m_uid_new_face = sd_nb_face++;
1832 if (sub_additionnal_answer.size() > 1) {
1833 need_more_comm =
true;
1841 for (
auto proc : sub_additionnal_answer) {
1842 if (proc == my_proc)
1844 request_uid[proc].add(face_lite.m_uid_new_face);
1850 else if (owner_min >= 0) {
1851 need_more_comm =
true;
1852 face_lite.m_owner_new_face = owner_min;
1853 face_lite.m_uid_new_face = -2;
1855 if (request_uid[my_proc].empty()) {
1856 request_uid[my_proc].resize(subDomain()->nbSubDomain(), 0);
1859 request_uid[my_proc][owner_min]++;
1861 requested_faces2[owner_min].add(requested_faces[sr][pos_node_in_array]);
1873 if (need_more_comm) {
1875 UniqueArray<Parallel::Request> requests(subDomain()->nbSubDomain());
1878 debug() <<
"[Face][" << my_proc <<
"] Étape 3.2";
1880 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1881 if (sr == subDomain()->subDomainId()) {
1885 if (request_uid[sr].empty())
continue;
1886 requests[sr] = pm->send(request_uid[sr], sr,
false);
1890 pm->waitAllRequests(requests);
1894 debug() <<
"[Face][" << my_proc <<
"] Étape 7";
1896 if (!request_uid[my_proc].empty()) {
1897 for (Int32 sr = 0; sr < subDomain()->nbSubDomain(); ++sr) {
1898 if (sr == subDomain()->subDomainId()) {
1902 Int64 size = request_uid[my_proc][sr];
1903 if (size == 0)
continue;
1908 UniqueArray<Int64> requested_uid(size);
1909 pm->recv(requested_uid, sr);
1911 for (Int32 i = 0; i < size; ++i) {
1912 FaceLite& face_lite = new_faces[requested_faces2[sr][i]];
1913 face_lite.m_uid_new_face = requested_uid[i];
1927Int32 MeshCutService::
1928_makeUniqueFaceUID(Int32 sd_nb_face, UniqueArray<FaceLite>& new_faces)
1930 IParallelMng* pm = subDomain()->parallelMng();
1932 UniqueArray<Int32> all_nb_node(pm->commSize());
1933 pm->allGather(ArrayView{ 1, &sd_nb_face }, all_nb_node);
1936 for (
auto& elem : all_nb_node) {
1937 const Int32 old = elem;
1944 for (
auto& elem : new_faces) {
1945 elem.m_uid_new_face += all_nb_node[elem.m_owner_new_face];
1953void MeshCutService::
1957 Int32 g_nb_node = 0;
1958 Int32 g_nb_face = 0;
1960 UniqueArray<Cell> ori_cells;
1962 UniqueArray<Int64> new_cells;
1964 UniqueArray<NodeIntersection> new_nodes;
1965 UniqueArray<FaceLite> new_faces;
1967 for (Int32 i = 0; i < m_plans.size(); ++i) {
1969 debug() <<
"Plan : " << m_plans[i].first <<
", " << m_plans[i].second;
1971 UniqueArray<NodeIntersection> plan_new_nodes;
1972 UniqueArray<FaceLite> plan_new_faces;
1974 Int32 ajust = new_nodes.size();
1976 Int32 previous_g_nb_node = g_nb_node;
1977 Int32 previous_g_nb_face = g_nb_face;
1979 Int32 nb_node_for_this_plan = g_nb_node;
1980 Int32 nb_face_for_this_plan = g_nb_face;
1982 debug() <<
"[" << subDomain()->parallelMng()->commRank() <<
"] _createNodesAndCells";
1983 _createNodesAndCells(i, g_nb_node, plan_new_nodes, ajust, nb_cell, new_cells, g_nb_face, plan_new_faces, ori_cells);
1996 debug() <<
"[" << subDomain()->parallelMng()->commRank() <<
"] _fillNodeUID";
1997 _fillNodeUID(g_nb_node, plan_new_nodes);
1998 nb_node_for_this_plan = g_nb_node - nb_node_for_this_plan;
2000 nb_node_for_this_plan = _makeUniqueNodeUID(nb_node_for_this_plan, plan_new_nodes);
2001 g_nb_node = previous_g_nb_node + nb_node_for_this_plan;
2026 _fillFaceUID(g_nb_face, plan_new_faces);
2027 nb_face_for_this_plan = g_nb_face - nb_face_for_this_plan;
2029 nb_face_for_this_plan = _makeUniqueFaceUID(nb_face_for_this_plan, plan_new_faces);
2030 g_nb_face = previous_g_nb_face + nb_face_for_this_plan;
2045 new_nodes.addRange(plan_new_nodes);
2046 new_faces.addRange(plan_new_faces);
2049 _makeUniqueCellUID(nb_cell, new_cells, new_nodes);
2071 _addFaces(new_faces);
2072 _addCells(new_cells);
2073 m_cloned_mesh->modifier()->endUpdate();
2074 _setCoordNodesAndOwner(new_nodes);
2075 _setFacesOwner(new_faces);
2077 _updateVariables(ori_cells);
2079 m_cloned_mesh->nodeFamily()->notifyItemsOwnerChanged();
2080 m_cloned_mesh->faceFamily()->notifyItemsOwnerChanged();
2082 info() <<
"Nouveau maillage : " << m_cloned_mesh->name() <<
" -- NbNœuds : " << m_cloned_mesh->nbNode() <<
" -- NbMailles : " << m_cloned_mesh->nbCell();
2088std::optional<Int64> MeshCutService::
2089_find(Span<FaceLite> new_faces, Int64 node_uid0, Int64 node_uid1)
2091 for (Int32 i = 0; i < new_faces.size(); ++i) {
2092 if (new_faces[i].m_node0->m_uid_new_node == node_uid0 && new_faces[i].m_node1->m_uid_new_node == node_uid1) {
2096 return std::nullopt;
2102void MeshCutService::
2103_addFaces(UniqueArray<FaceLite>& new_faces)
const
2105 UniqueArray<Int64> faces_infos;
2106 faces_infos.reserve(new_faces.size() * 4);
2110 for (
auto& elem : new_faces) {
2111 faces_infos.add(ITI_Line2);
2112 faces_infos.add(elem.m_uid_new_face);
2113 faces_infos.add(elem.m_node0->m_uid_new_node);
2114 faces_infos.add(elem.m_node1->m_uid_new_node);
2118 m_cloned_mesh->modifier()->addFaces(nb_faces, faces_infos);
2124void MeshCutService::
2125_addCells(UniqueArray<Int64>& new_cells)
2130 while (pos0 < new_cells.size()) {
2131 const Int64 type = new_cells[pos0];
2134 new_cells[pos0++] = ITI_Triangle3;
2136 new_cells[pos0++] = ITI_Quad4;
2138 new_cells[pos0++] = ITI_Pentagon5;
2140 new_cells[pos0++] = ITI_Hexagon6;
2144 pos0 += 1 +
static_cast<Int32
>(type);
2149 m_cloned_mesh->modifier()->addCells(nb_cells, new_cells);
2155void MeshCutService::
2156_setCoordNodesAndOwner(UniqueArray<NodeIntersection>& new_nodes)
2159 ENUMERATE_ (Node, inode, m_cloned_mesh->allNodes()) {
2160 const Int64 uid = inode->uniqueId();
2161 for (
const auto& elem : new_nodes) {
2162 if (elem.m_new_node->m_uid_new_node == uid) {
2163 node_coords[inode] = elem.m_intersection_pos;
2164 inode->mutableItemBase().setOwner(elem.m_new_node->m_owner_new_node, subDomain()->subDomainId());
2174void MeshCutService::
2175_setFacesOwner(UniqueArray<FaceLite>& new_faces)
2177 ENUMERATE_ (Face, iface, m_cloned_mesh->allFaces()) {
2178 const Int64 uid = iface->uniqueId();
2179 for (
const auto& elem : new_faces) {
2180 if (elem.m_uid_new_face == uid) {
2181 iface->mutableItemBase().setOwner(elem.m_owner_new_face, subDomain()->subDomainId());
2189void MeshCutService::
2190_updateVariables(UniqueArray<Cell>& ori_cells)
2192 for (Int32 type = 0; type < NB_ARCANE_DATA_TYPE; ++type) {
2195 _updateVariablesT(ori_cells, type,
Byte());
2198 _updateVariablesT(ori_cells, type, Real());
2201 _updateVariablesT(ori_cells, type, Real2());
2204 _updateVariablesT(ori_cells, type, Real2x2());
2207 _updateVariablesT(ori_cells, type, Real3());
2210 _updateVariablesT(ori_cells, type, Real3x3());
2213 _updateVariablesT(ori_cells, type,
Int8());
2216 _updateVariablesT(ori_cells, type, Int16());
2219 _updateVariablesT(ori_cells, type, Int32());
2222 _updateVariablesT(ori_cells, type, Int64());
2225 _updateVariablesT(ori_cells, type,
Float32());
2228 _updateVariablesT(ori_cells, type,
Float16());
2231 _updateVariablesT(ori_cells, type,
BFloat16());
2243void MeshCutService::
2244_updateVariablesT(UniqueArray<Cell>& ori_cells, Int32 type, T)
2246 VariableOriClone<T> voc;
2248 if (m_variables_cloned.count() != m_variables_ori.count()) {
2249 ARCANE_FATAL(
"Bad size -- m_variables_cloned : {0} -- m_variables_ori : {1}", m_variables_cloned.count(), m_variables_ori.count());
2252 VariableCollection::Enumerator iclone(m_variables_cloned);
2253 VariableCollection::Enumerator iori(m_variables_ori);
2255 while (++iclone && ++iori) {
2256 IVariable* ori = *iori;
2257 if (ori->dataType() == type) {
2258 IVariable* clone = *iclone;
2259 if (ori->dimension() == 1) {
2262 if (ori->itemKind() == IK_Unknown) {
2263 voc.ori.unknown.dim1.add(ori_data->view());
2264 voc.clone.unknown.dim1.add(clo_data->view());
2266 else if (ori->itemKind() == IK_Cell) {
2267 voc.ori.cells.dim1.add(ori_data->view());
2268 voc.clone.cells.dim1.add(clo_data->view());
2271 ARCANE_FATAL(
"Variable type not supported -- Type : {0}", ori->itemKind());
2274 else if (ori->dimension() == 2) {
2275 if (ori->itemKind() == IK_Cell) {
2276 VariableResizeArgs vra(-1);
2277 vra.setNewSizeDim2(ori->nbElement() / mesh()->nbCell());
2278 clone->_internalApi()->resize(vra);
2281 voc.ori.cells.dim2.add(ori_data->view());
2282 voc.clone.cells.dim2.add(clo_data->view());
2286 ARCANE_FATAL(
"Variable dim not supported -- Dim : {0}", ori->dimension());
2291 _updateArrayVariable(ori_cells, T(), voc);
2298void MeshCutService::
2299_updateArrayVariable(UniqueArray<Cell>& ori_cells, T, VariableOriClone<T>& voc)
2301 if (voc.ori.isUnknownUsed()) {
2302 for (Int32 i = 0; i < voc.ori.unknown.dim1.size(); ++i) {
2303 voc.clone.unknown.dim1[i].copy(voc.ori.unknown.dim1[i]);
2305 for (Int32 i = 0; i < voc.ori.unknown.dim2.size(); ++i) {
2306 for (Int32 j = 0; j < voc.ori.unknown.dim2[i].dim2Size(); ++j) {
2307 voc.clone.unknown.dim2[i][j].copy(voc.ori.unknown.dim2[i][j]);
2312 ENUMERATE_ (Cell, icell, m_cloned_mesh->ownCells()) {
2313 Cell ori_cell = ori_cells[icell.localId()];
2314 if (voc.ori.isCellsUsed()) {
2315 for (Int32 i = 0; i < voc.ori.cells.dim1.size(); ++i) {
2316 voc.clone.cells.dim1[i][icell.localId()] = voc.ori.cells.dim1[i][ori_cell.localId()];
2318 for (Int32 i = 0; i < voc.ori.cells.dim2.size(); ++i) {
2319 voc.clone.cells.dim2[i][icell.localId()].copy(voc.ori.cells.dim2[i][ori_cell.localId()]);
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
CaseOptionsMeshCut * options() const
Options du jeu de données du service.
ArcaneMeshCutObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
virtual void clearItems()=0
Supprime toutes les entitées de toutes les familles de ce maillage.
virtual IMeshModifier * modifier()=0
Interface de modification associée.
CellGroup ownCells() const
Retourne le groupe contenant toutes les mailles propres à ce domaine.
NodeGroup allNodes() const
Retourne le groupe contenant tous les noeuds.
void addPlane(const Real3 &p0, const Real3 &normal) override
Méthode permettant d'ajouter un plan au service de coupe. L'utilisation de ces plans dépend du servic...
void setServiceMeshUniqueId(Int32 unique_id) override
Méthode permettant de définir un identifiant unique pour créer plusieurs services de section pour un ...
void setVariables(VariableCollection variables) override
Méthode permettant d'ajouter un ensemble de variables à copier sur le nouveau maillage.
VariableCollection variables() override
Méthode permettant d'obtenir un ensemble de variables copiées sur le nouveau maillage.
void updateSection() override
Méthode permettant de mettre à jour la section du maillage avec tous les plans.
MeshHandle meshSection() override
Méthode permettant d'obtenir la section du maillage.
Classe gérant un vecteur réel de 3 dimensions.
eServiceType creationType() const
Type du service pouvant être créé par cette instance.
Structure contenant les informations pour créer un service.
Vue d'un tableau d'éléments de type T.
Vecteur 1D de données avec sémantique par valeur (style STL).
__host__ __device__ Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
Real3 normalizedCrossProduct3(Real3 v1, Real3 v2)
Produit vectoriel normalisé.
__host__ __device__ Real3 normalizeReal3(Real3 v)
Normalisation d'un Real3.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Node, Real > VariableNodeReal
Grandeur au noeud de type réel.
constexpr __host__ __device__ bool isNearlyZeroWithEpsilon(const Type &a, const Type &epsilon)
Teste si une valeur est approximativement égale à zéro dans un epsilon.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int8_t Int8
Type entier signé sur 8 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
bool operator<(const Item &item1, const Item &item2)
Compare deux entités.
eServiceType
Type du service.
@ ST_CaseOption
Le service s'utilise au niveau du jeu de données.
double Real
Type représentant un réel.
unsigned char Byte
Type d'un octet.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
float Float32
Type flottant IEEE-753 simple précision.
@ DT_Float32
Donnée de type 'Float32'.
@ DT_Real2x2
Donnée de type tenseur 3x3.
@ DT_Int16
Donnée de type entier 16 bits.
@ DT_Int8
Donnée de type entier sur 8 bits.
@ DT_Real3x3
Donnée de type tenseur 3x3.
@ DT_Int32
Donnée de type entier 32 bits.
@ DT_Real3
Donnée de type vecteur 3.
@ DT_Float16
Donnée de type 'Float16'.
@ DT_Int64
Donnée de type entier 64 bits.
@ DT_BFloat16
Donnée de type 'BFloat16'.
@ DT_Real2
Donnée de type vecteur 2.
@ DT_Real
Donnée de type réel.
@ DT_Byte
Donnée de type octet.
@ Cell
Le maillage est AMR par maille.
std::int32_t Int32
Type entier signé sur 32 bits.
Arcane::BFloat16 BFloat16
Type 'Brain Float16'.
Arcane::Float16 Float16
Type 'Float16' (binary16).