Chi-Tech
chi_volumemesher_01a_get_PIDs.cc
Go to the documentation of this file.
2
6
7#include "chi_runtime.h"
8#include "chi_log.h"
9#include "chi_mpi.h"
10
11
12//###################################################################
13/**Obtains the xy partition IDs of a cell.
14 * Cell xy_partition ids are obtained from
15 * the surface mesher.*/
16std::pair<int,int> chi_mesh::VolumeMesher::
18{
19 std::pair<int,int> ij_id(0,0);
20
21 if (Chi::mpi.process_count == 1){return ij_id;}
22
23 //================================================== Get the current handler
24 auto& mesh_handler = chi_mesh::GetCurrentHandler();
25 auto& vol_mesher = mesh_handler.GetVolumeMesher();
26
27//====================================== Sanity check on partitioning
28 size_t num_x_subsets = vol_mesher.options.xcuts.size()+1;
29 size_t num_y_subsets = vol_mesher.options.ycuts.size()+1;
30
31 size_t x_remainder = num_x_subsets%vol_mesher.options.partition_x;
32 size_t y_remainder = num_y_subsets%vol_mesher.options.partition_y;
33
34 if (x_remainder != 0)
35 {
37 << "When specifying x-partitioning, the number of grp_subsets in x "
38 "needs to be divisible by the number of partitions in x.";
39 Chi::Exit(EXIT_FAILURE);
40 }
41
42 if (y_remainder != 0)
43 {
45 << "When specifying y-partitioning, the number of grp_subsets in y "
46 "needs to be divisible by the number of partitions in y.";
47 Chi::Exit(EXIT_FAILURE);
48 }
49
50 size_t subsets_per_partitionx = num_x_subsets/vol_mesher.options.partition_x;
51 size_t subsets_per_partitiony = num_y_subsets/vol_mesher.options.partition_y;
52
53 //====================================== Determine x-partition
54 int x=-1;
55 int xcount=-1;
56 for (size_t i = subsets_per_partitionx-1;
57 i < vol_mesher.options.xcuts.size();
58 i += subsets_per_partitionx)
59 {
60 xcount++;
61 if (cell->centroid_.x <= vol_mesher.options.xcuts[i])
62 {
63 x = xcount;
64 break;
65 }
66 }
67 if (x<0)
68 {
69 x = vol_mesher.options.partition_x-1;
70 }
71
72 //====================================== Determine y-partition
73 int y=-1;
74 int ycount=-1;
75 for (size_t i = subsets_per_partitiony-1;
76 i < vol_mesher.options.ycuts.size();
77 i += subsets_per_partitiony)
78 {
79 ycount++;
80 if (cell->centroid_.y <= vol_mesher.options.ycuts[i])
81 {
82 y = ycount;
83 break;
84 }
85 }
86 if (y<0)
87 {
88 y = vol_mesher.options.partition_y - 1;
89 }
90
91 //====================================== Set partitioning
92 ij_id.first = x;
93 ij_id.second= y;
94
95 return ij_id;
96}
97
98//###################################################################
99/**Obtains the xyz partition IDs of a cell.
100 * Cell xy_partition ids are obtained from
101 * the surface mesher. z id is obtained from the volume mesher.*/
102std::tuple<int,int,int> chi_mesh::VolumeMesher::
104{
105 std::tuple<int,int,int> ijk_id(0,0,0);
106 bool found_partition = false;
107
108 if (Chi::mpi.process_count == 1){return ijk_id;}
109
110 //================================================== Get ij indices
111 std::pair<int,int> ij_id = GetCellXYPartitionID(cell);
112
113 //================================================== Get the current handler
114 auto& mesh_handler = chi_mesh::GetCurrentHandler();
115 auto& vol_mesher = mesh_handler.GetVolumeMesher();
116
117 if (vol_mesher.options.partition_z == 1)
118 {
119 found_partition = true;
120 std::get<0>(ijk_id) = ij_id.first;
121 std::get<1>(ijk_id) = ij_id.second;
122 std::get<2>(ijk_id) = 0;
123 }
124 else if (vol_mesher.Type() == VolumeMesherType::EXTRUDER)
125 {
126 auto extruder = dynamic_cast<chi_mesh::VolumeMesherExtruder&>(vol_mesher);
127 const auto& vertex_layers = extruder.GetVertexLayers();
128 //====================================== Create virtual cuts
129 if (vol_mesher.options.zcuts.empty())
130 {
131 size_t num_sub_layers = vertex_layers.size()-1;
132
133 if ((num_sub_layers%vol_mesher.options.partition_z) != 0)
134 {
136 << "Number of sub-layers in extruded mesh is not divisible "
137 << "by the requested number of z-partitions.";
138 Chi::Exit(EXIT_FAILURE);
139 }
140
141 int delta_zk = num_sub_layers/
142 vol_mesher.options.partition_z;
143 for (int k=0; k<(vol_mesher.options.partition_z); k++)
144 {
145 int layer_index = k*delta_zk + delta_zk;
146 if (layer_index > (vertex_layers.size()-1))
147 {
148 layer_index = (int)vertex_layers.size()-1;
149 vol_mesher.options.zcuts.push_back(vertex_layers[layer_index]);
150 }
151 else
152 {
153 vol_mesher.options.zcuts.push_back(vertex_layers[layer_index]);
154
155 if (Chi::log.GetVerbosity() == chi::ChiLog::LOG_LVL::LOG_0VERBOSE_2)
156 {
157 printf("Z-Cut %lu, %g\n",vol_mesher.options.zcuts.size(),
158 vertex_layers[layer_index]);
159 }
160 }
161 }
162 }
163
164
165 //====================================== Scan cuts for location
166 double zmin = -1.0e-16;
167 for (int k=0; k<(vol_mesher.options.zcuts.size()); k++)
168 {
169 double zmax = vol_mesher.options.zcuts[k];
170
171 double z = cell->centroid_.z;
172
173 if (Chi::log.GetVerbosity() == chi::ChiLog::LOG_0VERBOSE_2)
174 {
175 printf("zmax = %g, zmin = %g, cell_z = %g\n",zmax,zmin,z);
176 }
177
178
179 if ((z > zmin) && (z < zmax))
180 {
181 std::get<0>(ijk_id) = ij_id.first;
182 std::get<1>(ijk_id) = ij_id.second;
183 std::get<2>(ijk_id) = k;
184
185 found_partition = true;
186 break;
187 }
188 zmin = zmax;
189 }
190 }//if typeid
191 else if (vol_mesher.Type() == VolumeMesherType::UNPARTITIONED)
192 {
193 if (vol_mesher.options.zcuts.empty())
194 {
195 throw std::invalid_argument("Cell z-partitioning cannot be determined "
196 "because no z-cuts are supplied to volume "
197 "mesher.");
198 }
199
200 //====================================== Scan cuts for location
201 std::vector<double> temp_zcuts = vol_mesher.options.zcuts;
202 double zmin = -1.0e16;
203 double zmax = 1.0e16;
204 temp_zcuts.push_back(zmax);
205 for (int k=0; k<(temp_zcuts.size()); k++)
206 {
207 zmax = temp_zcuts[k];
208
209 double z = cell->centroid_.z;
210
211 if (Chi::log.GetVerbosity() == chi::ChiLog::LOG_0VERBOSE_2)
212 {
213 printf("zmax = %g, zmin = %g, cell_z = %g\n",zmax,zmin,z);
214 }
215
216
217 if ((z > zmin) && (z < zmax))
218 {
219 std::get<0>(ijk_id) = ij_id.first;
220 std::get<1>(ijk_id) = ij_id.second;
221 std::get<2>(ijk_id) = k;
222
223 found_partition = true;
224 break;
225 }
226 zmin = zmax;
227 }//for k
228 }//if typeid
229
230 //================================================== Report unallocated item_id
231 if (!found_partition)
232 {
234 << "A cell was encountered for which "
235 "no zpartition id was found";
236 Chi::Exit(EXIT_FAILURE);
237 }
238
239 return ijk_id;
240}
static void Exit(int error_code)
Definition: chi_runtime.cc:342
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream LogAllError()
Definition: chi_log.h:239
@ LOG_0VERBOSE_2
Used only if verbosity level equals 2.
Definition: chi_log.h:204
Vertex centroid_
Definition: cell.h:78
const std::vector< double > & GetVertexLayers() const
static std::tuple< int, int, int > GetCellXYZPartitionID(chi_mesh::Cell *cell)
static std::pair< int, int > GetCellXYPartitionID(chi_mesh::Cell *cell)
MeshHandler & GetCurrentHandler()
double x
Element-0.
double y
Element-1.
double z
Element-2.