OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
ghost_shells.cpp
Go to the documentation of this file.
1//Copyright> OpenRadioss
2//Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3//Copyright>
4//Copyright> This program is free software: you can redistribute it and/or modify
5//Copyright> it under the terms of the GNU Affero General Public License as published by
6//Copyright> the Free Software Foundation, either version 3 of the License, or
7//Copyright> (at your option) any later version.
8//Copyright>
9//Copyright> This program is distributed in the hope that it will be useful,
10//Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11//Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12//Copyright> GNU Affero General Public License for more details.
13//Copyright>
14//Copyright> You should have received a copy of the GNU Affero General Public License
15//Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16//Copyright>
17//Copyright>
18//Copyright> Commercial Alternative: Altair Radioss Software
19//Copyright>
20//Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21//Copyright> software under a commercial license. Contact Altair to discuss further if the
22//Copyright> commercial version may interest you: https://www.altair.com/radioss/.
23#include <iostream>
24#include <vector>
25#include <algorithm>
26
27// Type alias for ghost shells data structure
28using Ghosts = std::vector<std::vector<int>>;
29
31 int shell_index, // Index of the shell
32 int process_id, // Process ID
33 int *shells, // Shell nodes array
34 int *mask, // Mask array for nodes
35 int nspmd, // Number of processes
36 int max_node_id) // Maximum node ID
37{
38 // A shell should be included if at least one of its nodes has mask == 1
39 constexpr int nodes_per_shell = 4;
40
41 for (int j = 0; j < nodes_per_shell; ++j)
42 {
43 const int node_id = shells[shell_index * nodes_per_shell + j];
44 if (node_id > 0 && node_id <= max_node_id)
45 {
46 // For a Fortran array mask(nspmd,numnodes)
47 // Access mask(p,node_id) as mask[(node_id-1)*nspmd + (p)]
48 const int mask_index = (node_id - 1) * nspmd + process_id;
49 if (mask[mask_index] == 1)
50 {
51 return true; // Found at least one node with mask == 1
52 }
53 }
54 }
55 return false; // No nodes have mask == 1
56}
57
58extern "C"
59{
61 int *shells, // 4 x nb_shells array : node id of the shells
62 int nb_shells,
63 int *mask, // nspmd x numnod array: 1 => node belongs to process
64 int nspmd,
65 int numnod)
66 {
67 if (!shells || !mask || nb_shells < 0 || nspmd <= 0 || numnod <= 0)
68 {
69 return nullptr;
70 }
71
72 auto *ghost_data = new Ghosts(nspmd);
73 const int max_node_id = numnod;
74
75 // Build ghost shell lists for each process
76 for (int shell_idx = 0; shell_idx < nb_shells; ++shell_idx)
77 {
78 for (int process_idx = 0; process_idx < nspmd; ++process_idx)
79 {
80 if (is_shell_ghost_on_proc(shell_idx, process_idx, shells, mask, nspmd, max_node_id))
81 {
82 (*ghost_data)[process_idx].push_back(shell_idx + 1); // Convert to 1-based for Fortran
83 }
84 }
85 }
86
87 // Remove duplicates from each process's shell list
88 if (nb_shells > 0)
89 {
90 for (int process_idx = 0; process_idx < nspmd; ++process_idx)
91 {
92 auto &shell_list = (*ghost_data)[process_idx];
93 std::sort(shell_list.begin(), shell_list.end());
94 auto new_end = std::unique(shell_list.begin(), shell_list.end());
95 shell_list.erase(new_end, shell_list.end());
96 }
97 }
98
99 return ghost_data;
100 }
101
102 int *cpp_get_shells_list(void *c, int pc, int *n)
103 {
104 if (!c || !n)
105 {
106 if (n)
107 *n = 0;
108 return nullptr;
109 }
110
111 auto *ghost_data = static_cast<Ghosts *>(c);
112 const int process_idx = pc - 1; // Fortran to C index conversion
113
114 // Check bounds
115 if (process_idx < 0 || process_idx >= static_cast<int>(ghost_data->size()))
116 {
117 *n = 0;
118 return nullptr;
119 }
120
121 auto &shell_list = (*ghost_data)[process_idx];
122 *n = static_cast<int>(shell_list.size());
123
124 return *n == 0 ? nullptr : shell_list.data();
125 }
126
127 int cpp_get_shells_list_size(void *c, int pc)
128 {
129 if (!c)
130 {
131 return 0;
132 }
133
134 auto *ghost_data = static_cast<Ghosts *>(c);
135 const int process_idx = pc - 1; // Fortran to C index conversion
136
137 // Check bounds
138 if (process_idx < 0 || process_idx >= static_cast<int>(ghost_data->size()))
139 {
140 return 0;
141 }
142
143 return static_cast<int>((*ghost_data)[process_idx].size());
144 }
145
146 void cpp_copy_shells_list(void *c, int pc, int *shells, int n)
147 {
148 if (!c || !shells)
149 {
150 return;
151 }
152
153 auto *ghost_data = static_cast<Ghosts *>(c);
154 const int process_idx = pc - 1; // Fortran to C index conversion
155
156 // Check bounds
157 if (process_idx < 0 || process_idx >= static_cast<int>(ghost_data->size()))
158 {
159 return;
160 }
161
162 // Copy the shells list to the output array
163 const auto &shell_list = (*ghost_data)[process_idx];
164 std::copy(shell_list.begin(), shell_list.end(), shells);
165 }
166
167 void cpp_destroy_ghosts(void *c)
168 {
169 if (!c)
170 {
171 return;
172 }
173
174 auto *ghost_data = static_cast<Ghosts *>(c);
175 delete ghost_data;
176 }
177}
int * cpp_get_shells_list(void *c, int pc, int *n)
int cpp_get_shells_list_size(void *c, int pc)
void cpp_copy_shells_list(void *c, int pc, int *shells, int n)
void cpp_destroy_ghosts(void *c)
Ghosts * cpp_build_ghosts(int *shells, int nb_shells, int *mask, int nspmd, int numnod)
bool is_shell_ghost_on_proc(int shell_index, int process_id, int *shells, int *mask, int nspmd, int max_node_id)
std::vector< std::vector< int > > Ghosts
static int nspmd
Definition rad2rad_c.c:126
n