OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
cpp_split_tool.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#define _FCALL
24#include <list>
25#include <vector>
26#include <unordered_map>
27#include <algorithm>
28#include <cmath>
29#include <deque>
30#include <fstream>
31#include <iostream>
32#include <limits>
33#include <cfloat>
34#include <set>
35#include <map>
36
37
38#ifndef NDEBUG
39#define NDEBUG
40#endif
41#include <assert.h>
42
43
44//Type definition
45//
46// Partition[domain][global Id] = local Id
47typedef std::vector<std::unordered_map<int,int>> Partition;
48
49//vector of candidates
50typedef std::vector<std::pair<int,int>> Candidates;
51
52//vector of pointers to pairs
53typedef std::vector<std::pair<int,int>*> VectOfCandPtr;
54
55typedef std::vector<std::vector<int>> Remotes;
56
57void build_partition(int *cep, int *size, const int nspmd, Partition & partition)
58{ // partition element according to the CEP
59
60// create a vector of size nspmd initialized at 0
61 std::vector<int> count(nspmd,0);
62 partition.reserve(nspmd);
63 for(int i = 0 ; i < *size ; i++)
64 {
65 assert( cep[i] >= 0);
66 assert( cep[i] < nspmd);
67 partition[cep[i]][i]=count[cep[i]];
68 count[cep[i]]++;
69 }
70}
71
72extern "C" {
73
74
75//Restriction : secondary objects must belong to one and only one processor
76//
77void cpp_count_candidates(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS, int *localIdS, int *candS, int * nspmd, int * secondaryRemoteCount, int * localIdx)
78{
79 // nbCand:
80 // IN: number of candidates
81 // sizeM:
82 // IN: number of Main objects
83 // cepM:
84 // IN: domain of main objects, starts at 0
85 // LocalIdM
86 // IN: local ID of the main object on its owner domain
87 // candM
88 // IN: global id of main object
89 // OUT: id of main object local to domain
90 // sizeS: number of Main objects
91 // cepS:
92 // IN: secondary of main objects, starts at 0
93 // LocalIdM
94 // IN: local ID of the main object on its owner domain
95 // candS
96 // IN: global id of secondary object, starts at 1
97 // OUT: id of secondary object:
98 // if CandS[i] > 0 => CandS[i] is the local ID on domain CepM[i]
99 // if CandS[i] < 0 => -CandS[i] is the ID in the remote (FI) structure
100 // indexes starts at 1
101 // nspmd:
102 // IN: number of domains
103 // secondaryRemoteCount:
104 // OUT: array of size nspmd*nspmd that contains the number of remotes per pairs of processors
105 // localIdx:
106 // OUT: array of size nbCand, localIdx[i] = local index of the CandS[i] in the domain CepS[i]
107 //
108 // Description:
109 // split based on the domains of the main and the secondary element
110
111
112 const int nspmd2 = (*nspmd)*(*nspmd);
113 std::vector<Candidates> candidates(nspmd2, std::vector<std::pair<int,int>>());
114 Remotes secondaryRemotes(nspmd2, std::vector<int>());
115
116 for(int i = 0 ; i < *nbCand ; i++)
117 {
118 // Fortran indexes start at 1
119 const int currentM = candM[i] - 1;
120 const int currentS = candS[i] - 1;
121 assert(currentM < *sizeM);
122 assert(currentM >= 0 );
123 assert(currentS < *sizeS);
124 assert(currentS >= 0 );
125 const int domainM = cepM[currentM];
126 const int domainS = cepS[currentS];
127 const int oneD = domainM * (*nspmd) + domainS;
128
129// const auto itrS = partitionS[domainS].find(currentS);
130// const auto itrM = partitionM[domainM].find(currentM);
131// const int localIdS = itrS->second;
132// const int localIdM = itrM->second;
133// const int localIdS = std::distance(partitionM[domainM].begin(),itrM) + 1; //idx starts at 1 (back to Fortran)
134// const int localIdM = std::distance(partitionS[domainS].begin(),itrS) + 1;
135
136 //DEBUG
137 assert(domainM >= 0);
138 assert(domainM < *nspmd);
139 assert(domainS >=0);
140 assert(domainS < *nspmd);
141 if(domainS != domainM)
142 {
143 // candidates[oneD].push_back(std::make_pair(localIdM[currentM],localIdS[currentS]));
144 candidates[oneD].push_back(std::make_pair(i,localIdS[currentS]));
145
146 }
147 //replace candidates global id by local ids
148 candM[i] = localIdM[currentM];
149 candS[i] = localIdS[currentS]; // if remote, will be replace by id in FI
150 localIdx[i] = localIdS[currentS]; // keep local ID on owner domain
151
152 }
153
154 for(int domainM = 0 ; domainM < *nspmd ; domainM++)
155 {
156 int offset = 0 ;
157 for(int domainS = 0 ; domainS < *nspmd ; domainS++)
158 {
159 // 2D to 1D index
160 const int oneD = domainM * (*nspmd) + domainS;
161 secondaryRemoteCount[oneD] = 0;
162 secondaryRemotes[oneD] = {} ;
163 if(domainS != domainM)
164 {
165 // SecondaryToCand[ global secondary id] => vector of pointers to candidates that
166 // have that secondary object
167 std::map<int,VectOfCandPtr> secondaryToCand;
168
169 // Sets automatically exclude duplicates
170 std::set<int> secondarySet;
171
172 // Find all remote secondary objects
173 // They may be duplicated,multiple candidate pairs having the same secondary objects
174 // SecondaryToCand keep tracks of those candidates pairs
175 for(auto & c : candidates[oneD])
176 {
177 auto it = secondarySet.insert(c.second);
178 secondaryToCand[c.second].push_back(&(c));
179 }
180 // convert set into vector
181 secondaryRemotes[oneD].assign(secondarySet.begin(),secondarySet.end());
182 // sort the vector - not needed since set is automatically sorted
183 // would be needed if set was replaced by unordered_set
184 // std::sort(secondaryRemotes[oneD].begin(),secondaryRemotes[oneD].end();
185 secondaryRemoteCount[oneD] = secondaryRemotes[oneD].size();
186 int idxInFi = offset; // index in Fi structure
187
188 // For remote candidate, convert:
189 // id of the secondary object (local to the owner domain) => index in the FI structure
190 for(auto & sc : secondaryToCand)
191 {
192 idxInFi++;
193 for(auto & ptr : sc.second)
194 {
195 // ptr = ptr to the pair of candidates
196 (*ptr).second = -( idxInFi); // index starts at 1
197 // std::cout<<"candS["<<(*ptr).first<<"]="<< -(idxInFi) << std::endl;
198 candS[(*ptr).first] = -(idxInFi);
199 }
200 }
201
202 } else
203 {
204 secondaryRemoteCount[oneD] = 0;
205 }
206 offset+= secondaryRemoteCount[oneD];
207 }
208 }
209
210// for(int domainM = 0 ; domainM < *nspmd ; domainM++)
211// {
212// for(int domainS = 0 ; domainS < *nspmd ; domainS++)
213// {
214// const int oneD = domainM * (*nspmd) + domainS;
215// std::cout<<secondaryRemoteCount[oneD]<<" ";
216// }
217// std::cout<<std::endl;
218// }
219}
220
221
222void _FCALL CPP_COUNT_CANDIDATES(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS,int *localIdS, int *candS, int * nspmd, int * secondaryRemoteCount, int * localIdx)
223{
224 cpp_count_candidates(nbCand, sizeM, cepM, localIdM, candM, sizeS, cepS, localIdS, candS, nspmd, secondaryRemoteCount, localIdx);
225}
226void cpp_count_candidates__(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS,int *localIdS, int *candS, int * nspmd, int * secondaryRemoteCount, int * localIdx)
227{
228 cpp_count_candidates(nbCand, sizeM, cepM, localIdM, candM, sizeS, cepS, localIdS, candS, nspmd, secondaryRemoteCount, localIdx);
229}
230void cpp_count_candidates_(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS,int *localIdS, int *candS, int * nspmd, int * secondaryRemoteCount, int * localIdx)
231{
232 cpp_count_candidates(nbCand, sizeM, cepM, localIdM, candM, sizeS, cepS, localIdS, candS, nspmd, secondaryRemoteCount, localIdx);
233}
234
235} //extern C
236
std::vector< std::unordered_map< int, int > > Partition
void cpp_count_candidates_(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS, int *localIdS, int *candS, int *nspmd, int *secondaryRemoteCount, int *localIdx)
std::vector< std::vector< int > > Remotes
std::vector< std::pair< int, int > * > VectOfCandPtr
void build_partition(int *cep, int *size, const int nspmd, Partition &partition)
void cpp_count_candidates(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS, int *localIdS, int *candS, int *nspmd, int *secondaryRemoteCount, int *localIdx)
std::vector< std::pair< int, int > > Candidates
void _FCALL CPP_COUNT_CANDIDATES(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS, int *localIdS, int *candS, int *nspmd, int *secondaryRemoteCount, int *localIdx)
void cpp_count_candidates__(int *nbCand, int *sizeM, int *cepM, int *localIdM, int *candM, int *sizeS, int *cepS, int *localIdS, int *candS, int *nspmd, int *secondaryRemoteCount, int *localIdx)
#define _FCALL
static int nspmd
Definition rad2rad_c.c:126