171 std::vector<Real> ring_radii,
172 const std::vector<unsigned int> ring_layers,
173 const std::vector<Real> ring_radial_biases,
176 std::vector<Real> ducts_center_dist,
177 const std::vector<unsigned int> ducts_layers,
178 const std::vector<Real> duct_radial_biases,
182 const unsigned int num_sectors_per_side,
183 const unsigned int background_intervals,
184 const Real background_radial_bias,
188 const Real virtual_side_number,
189 const unsigned int side_index,
190 const std::vector<Real> azimuthal_tangent,
192 const bool quad_center_elements,
193 const Real center_quad_factor,
194 const bool create_inward_interface_boundaries,
195 const bool create_outward_interface_boundaries,
197 const Real pitch_scale_factor,
198 const bool generate_side_specific_boundaries,
206 ", an incompatible elements type combination is used when calling "
207 "PolygonMeshGeneratorBase::buildSlice().");
213 std::vector<unsigned int> mod_ring_layers(ring_layers);
215 mod_ring_layers.begin(), mod_ring_layers.end(), [&order](
unsigned int & n) { n *= order; });
218 std::vector<Real> mod_ring_radial_biases(ring_radial_biases);
219 std::for_each(mod_ring_radial_biases.begin(),
220 mod_ring_radial_biases.end(),
221 [&order](
Real & n) { n = std::pow(n, 1.0 / order); });
223 std::vector<unsigned int> mod_ducts_layers(ducts_layers);
225 mod_ducts_layers.begin(), mod_ducts_layers.end(), [&order](
unsigned int & n) { n *= order; });
227 std::vector<Real> mod_duct_radial_biases(duct_radial_biases);
228 std::for_each(mod_duct_radial_biases.begin(),
229 mod_duct_radial_biases.end(),
230 [&order](
Real & n) { n = std::pow(n, 1.0 / order); });
232 const unsigned int mod_num_sectors_per_side = num_sectors_per_side * order;
233 const unsigned int mod_background_intervals = background_intervals * order;
235 const Real mod_background_radial_bias = std::pow(background_radial_bias, 1.0 / order);
237 const auto mod_ring_inner_boundary_layer_params =
239 const auto mod_ring_outer_boundary_layer_params =
241 const auto mod_duct_inner_boundary_layer_params =
243 const auto mod_duct_outer_boundary_layer_params =
246 const auto mod_background_inner_boundary_layer_params =
248 const auto mod_background_outer_boundary_layer_params =
253 std::vector<Real> mod_ducts_center_dist(ducts_center_dist);
254 std::vector<Real> mod_ring_radii(ring_radii);
255 bool has_rings(ring_radii.size());
256 bool has_ducts(ducts_center_dist.size());
257 bool has_background(background_intervals);
262 const auto main_background_bias_terms =
264 const auto inner_background_bias_terms =
266 background_inner_boundary_layer_params.
intervals);
267 const auto outer_background_bias_terms =
269 background_outer_boundary_layer_params.
intervals);
272 ring_inner_boundary_layer_params,
273 ring_outer_boundary_layer_params);
276 duct_inner_boundary_layer_params,
277 duct_outer_boundary_layer_params);
279 const auto mod_main_background_bias_terms =
281 const auto mod_inner_background_bias_terms =
283 mod_background_inner_boundary_layer_params.intervals);
284 const auto mod_outer_background_bias_terms =
286 mod_background_outer_boundary_layer_params.intervals);
289 mod_ring_inner_boundary_layer_params,
290 mod_ring_outer_boundary_layer_params);
293 mod_duct_inner_boundary_layer_params,
294 mod_duct_outer_boundary_layer_params);
296 std::vector<unsigned int> total_ring_layers;
297 for (
unsigned int i = 0; i < ring_layers.size(); i++)
298 total_ring_layers.push_back(ring_layers[i] + ring_inner_boundary_layer_params.
intervals[i] +
299 ring_outer_boundary_layer_params.
intervals[i]);
301 if (background_inner_boundary_layer_params.
intervals)
303 total_ring_layers.push_back(background_inner_boundary_layer_params.
intervals);
304 rings_bias_terms.push_back(inner_background_bias_terms);
305 ring_radii.push_back((ring_radii.empty() ? 0.0 : ring_radii.back()) +
306 background_inner_boundary_layer_params.
width);
309 std::vector<unsigned int> mod_total_ring_layers;
310 for (
unsigned int i = 0; i < mod_ring_layers.size(); i++)
311 mod_total_ring_layers.push_back(mod_ring_layers[i] +
312 mod_ring_inner_boundary_layer_params.intervals[i] +
313 mod_ring_outer_boundary_layer_params.intervals[i]);
315 if (mod_background_inner_boundary_layer_params.intervals)
317 mod_total_ring_layers.push_back(mod_background_inner_boundary_layer_params.intervals);
318 mod_rings_bias_terms.push_back(mod_inner_background_bias_terms);
319 mod_ring_radii.push_back((mod_ring_radii.empty() ? 0.0 : mod_ring_radii.back()) +
320 mod_background_inner_boundary_layer_params.width);
324 std::vector<unsigned int> total_ducts_layers;
325 if (background_outer_boundary_layer_params.
intervals)
327 total_ducts_layers.push_back(background_outer_boundary_layer_params.
intervals);
328 duct_bias_terms.insert(duct_bias_terms.begin(), outer_background_bias_terms);
329 ducts_center_dist.insert(ducts_center_dist.begin(),
330 (ducts_center_dist.empty()
331 ? pitch / 2.0 / std::cos(M_PI / virtual_side_number)
332 : ducts_center_dist.front()) -
333 background_outer_boundary_layer_params.
width);
336 for (
unsigned int i = 0; i < ducts_layers.size(); i++)
337 total_ducts_layers.push_back(ducts_layers[i] + duct_inner_boundary_layer_params.
intervals[i] +
338 duct_outer_boundary_layer_params.
intervals[i]);
340 std::vector<unsigned int> mod_total_ducts_layers;
341 if (mod_background_outer_boundary_layer_params.intervals)
343 mod_total_ducts_layers.push_back(mod_background_outer_boundary_layer_params.intervals);
344 mod_duct_bias_terms.insert(mod_duct_bias_terms.begin(), mod_outer_background_bias_terms);
345 mod_ducts_center_dist.insert(mod_ducts_center_dist.begin(),
346 (mod_ducts_center_dist.empty()
347 ? pitch / 2.0 / std::cos(M_PI / virtual_side_number)
348 : mod_ducts_center_dist.front()) -
349 mod_background_outer_boundary_layer_params.width);
352 for (
unsigned int i = 0; i < mod_ducts_layers.size(); i++)
353 mod_total_ducts_layers.push_back(mod_ducts_layers[i] +
354 mod_duct_inner_boundary_layer_params.intervals[i] +
355 mod_duct_outer_boundary_layer_params.intervals[i]);
357 unsigned int angle_number = azimuthal_tangent.size() == 0
358 ? num_sectors_per_side
359 : ((azimuthal_tangent.size() - 1) / order);
360 unsigned int mod_angle_number =
361 azimuthal_tangent.size() == 0 ? mod_num_sectors_per_side : (azimuthal_tangent.size() - 1);
364 const Real corner_to_corner =
365 pitch / std::cos(M_PI / virtual_side_number);
366 const Real corner_p[2][2] = {
367 {0.0, 0.5 * corner_to_corner},
368 {0.5 * corner_to_corner * pitch_scale_factor * std::sin(2.0 * M_PI / virtual_side_number),
369 0.5 * corner_to_corner * pitch_scale_factor * std::cos(2.0 * M_PI / virtual_side_number)}};
370 const unsigned int div_num = angle_number / 2 + 1;
371 const unsigned int mod_div_num = mod_angle_number / 2 + 1;
374 std::vector<std::vector<Node *>> nodes(mod_div_num, std::vector<Node *>(mod_div_num));
375 if (quad_center_elements)
380 ring_radii_0 = ring_radii.front() * mod_rings_bias_terms.front()[order - 1];
382 ring_radii_0 = mod_ducts_center_dist.front() * std::cos(M_PI / virtual_side_number) *
383 mod_main_background_bias_terms[order - 1];
385 ring_radii_0 = pitch / 2.0 * mod_main_background_bias_terms[order - 1];
390 center_quad_factor == 0.0 ? (((
Real)div_num - 1.0) / (
Real)div_num) : center_quad_factor;
392 centerNodes(*
mesh, virtual_side_number, mod_div_num, ring_radii_0, nodes);
401 mod_total_ring_layers,
402 mod_rings_bias_terms,
403 mod_num_sectors_per_side,
413 Real background_corner_radial_interval_length;
414 Real background_corner_distance;
418 background_in = ring_radii.back();
424 background_out = mod_ducts_center_dist.front();
425 background_corner_distance =
426 mod_ducts_center_dist
431 background_out = 0.5 * corner_to_corner;
432 background_corner_distance =
433 0.5 * corner_to_corner;
436 background_corner_radial_interval_length =
437 (background_out - background_in) / mod_background_intervals;
443 mod_num_sectors_per_side,
444 mod_background_intervals,
445 mod_main_background_bias_terms,
446 background_corner_distance,
447 background_corner_radial_interval_length,
457 &mod_ducts_center_dist,
458 mod_total_ducts_layers,
460 mod_num_sectors_per_side,
476 bool is_central_region_independent;
477 if (ring_layers.empty())
478 is_central_region_independent = mod_background_inner_boundary_layer_params.intervals +
479 mod_background_intervals +
480 mod_background_outer_boundary_layer_params.intervals ==
483 is_central_region_independent = mod_ring_layers[0] +
484 mod_ring_inner_boundary_layer_params.intervals[0] +
485 mod_ring_outer_boundary_layer_params.intervals[0] ==
491 if (quad_center_elements)
495 create_outward_interface_boundaries && is_central_region_independent,
498 (!has_rings) && (!has_ducts) && (background_intervals == 1),
503 generate_side_specific_boundaries,
508 num_sectors_per_side,
511 create_outward_interface_boundaries && is_central_region_independent,
513 ((!has_rings) && (!has_ducts) && (background_intervals == 1)) ||
514 ((!has_background) &&
515 (std::accumulate(total_ring_layers.begin(), total_ring_layers.end(), 0) == 1)),
519 generate_side_specific_boundaries,
527 std::vector<unsigned int> subdomain_rings;
530 subdomain_rings = total_ring_layers;
531 subdomain_rings.front() -= 1;
532 if (background_inner_boundary_layer_params.
intervals)
534 subdomain_rings.back() =
535 background_inner_boundary_layer_params.
intervals + background_intervals +
536 background_outer_boundary_layer_params.
intervals;
537 if (ring_radii.size() == 1)
538 subdomain_rings.back() -= 1;
540 else if (has_background)
541 subdomain_rings.push_back(background_inner_boundary_layer_params.
intervals +
542 background_intervals +
543 background_outer_boundary_layer_params.
intervals);
547 subdomain_rings.push_back(
548 background_inner_boundary_layer_params.
intervals + background_intervals +
549 background_outer_boundary_layer_params.
intervals);
550 subdomain_rings[0] -= 1;
554 for (
unsigned int i = (background_outer_boundary_layer_params.
intervals > 0);
555 i < total_ducts_layers.size();
557 subdomain_rings.push_back(total_ducts_layers[i]);
560 num_sectors_per_side,
565 quad_center_elements ? (mod_div_num * mod_div_num - 1) : 0,
566 create_inward_interface_boundaries,
567 create_outward_interface_boundaries,
569 generate_side_specific_boundaries,
721 const unsigned int num_sectors_per_side,
722 const unsigned int background_intervals,
723 const std::vector<Real> biased_terms,
724 const Real background_corner_distance,
725 const Real background_corner_radial_interval_length,
726 const Real corner_p[2][2],
727 const Real corner_to_corner,
728 const Real background_in,
729 const std::vector<Real> azimuthal_tangent)
const
731 unsigned int angle_number =
732 azimuthal_tangent.size() == 0 ? num_sectors_per_side : (azimuthal_tangent.size() - 1);
733 for (
unsigned int k = 0; k < (background_intervals); k++)
735 const Real background_corner_p_x =
736 background_corner_distance / (0.5 * corner_to_corner) * corner_p[0][0] *
738 biased_terms[k] * background_intervals * background_corner_radial_interval_length) /
739 background_corner_distance;
740 const Real background_corner_p_y =
741 background_corner_distance / (0.5 * corner_to_corner) * corner_p[0][1] *
743 biased_terms[k] * background_intervals * background_corner_radial_interval_length) /
744 background_corner_distance;
750 for (
unsigned int j = 1; j <= angle_number; j++)
752 const Real cell_boundary_p_x =
753 background_corner_distance / (0.5 * corner_to_corner) *
754 (corner_p[0][0] + (corner_p[1][0] - corner_p[0][0]) *
755 (azimuthal_tangent.size() == 0 ? ((
Real)j / (
Real)angle_number)
756 : (azimuthal_tangent[j] / 2.0)));
757 const Real cell_boundary_p_y =
758 background_corner_distance / (0.5 * corner_to_corner) *
759 (corner_p[0][1] + (corner_p[1][1] - corner_p[0][1]) *
760 (azimuthal_tangent.size() == 0 ? ((
Real)j / (
Real)angle_number)
761 : (azimuthal_tangent[j] / 2.0)));
764 const Real pin_boundary_p_x =
765 cell_boundary_p_x * background_in /
766 std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
767 const Real pin_boundary_p_y =
768 cell_boundary_p_y * background_in /
769 std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
772 const Real background_radial_interval =
773 std::sqrt(Utility::pow<2>(cell_boundary_p_x - pin_boundary_p_x) +
774 Utility::pow<2>(cell_boundary_p_y - pin_boundary_p_y)) /
775 background_intervals;
776 const Real background_azimuthal_p_x =
778 (background_in + biased_terms[k] * background_intervals * background_radial_interval) /
779 std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
780 const Real background_azimuthal_p_y =
782 (background_in + biased_terms[k] * background_intervals * background_radial_interval) /
783 std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
854 const unsigned int div_num,
856 const bool create_outward_interface_boundaries,
858 std::vector<std::vector<Node *>> & nodes,
859 const bool assign_external_boundary,
860 const unsigned int side_index,
861 const bool generate_side_specific_boundaries,
868 for (
unsigned int i = 0; i < div_num - 1; i++)
870 unsigned int id_x = 0;
871 unsigned int id_y = i;
872 for (
unsigned int j = 0; j < 2 * i + 1; j++)
874 std::unique_ptr<Elem> new_elem;
877 new_elem = std::make_unique<Quad4>();
878 new_elem->set_node(0, nodes[id_x][id_y]);
879 new_elem->set_node(3, nodes[id_x][id_y + 1]);
880 new_elem->set_node(2, nodes[id_x + 1][id_y + 1]);
881 new_elem->set_node(1, nodes[id_x + 1][id_y]);
882 new_elem->subdomain_id() = 1 + block_id_shift;
886 new_elem = std::make_unique<Quad8>();
889 new_elem = std::make_unique<Quad9>();
890 new_elem->set_node(8, nodes[id_x * 2 + 1][id_y * 2 + 1]);
892 new_elem->set_node(0, nodes[id_x * 2][id_y * 2]);
893 new_elem->set_node(3, nodes[id_x * 2][id_y * 2 + 2]);
894 new_elem->set_node(2, nodes[id_x * 2 + 2][id_y * 2 + 2]);
895 new_elem->set_node(1, nodes[id_x * 2 + 2][id_y * 2]);
896 new_elem->set_node(4, nodes[id_x * 2 + 1][id_y * 2]);
897 new_elem->set_node(5, nodes[id_x * 2 + 2][id_y * 2 + 1]);
898 new_elem->set_node(6, nodes[id_x * 2 + 1][id_y * 2 + 2]);
899 new_elem->set_node(7, nodes[id_x * 2][id_y * 2 + 1]);
900 new_elem->subdomain_id() = 1 + block_id_shift;
915 for (
unsigned int i = (div_num - 1) * (div_num - 1); i < div_num * div_num - 1; i++)
917 std::unique_ptr<Elem> new_elem;
920 new_elem = std::make_unique<Quad4>();
922 new_elem->set_node(3,
mesh.
node_ptr(i + 2 * div_num - 1));
928 new_elem = std::make_unique<Quad8>();
931 new_elem = std::make_unique<Quad9>();
932 new_elem->set_node(8,
934 (i - (div_num - 1) * (div_num - 1)) * 2 + 1 +
935 ((div_num - 1) * 4 + 1)));
937 new_elem->set_node(0,
939 (i - (div_num - 1) * (div_num - 1)) * 2));
940 new_elem->set_node(3,
942 (i - (div_num - 1) * (div_num - 1)) * 2 +
943 ((div_num - 1) * 4 + 1) * 2));
944 new_elem->set_node(2,
946 (i - (div_num - 1) * (div_num - 1)) * 2 + 2 +
947 ((div_num - 1) * 4 + 1) * 2));
948 new_elem->set_node(1,
950 (i - (div_num - 1) * (div_num - 1)) * 2 + 2));
951 new_elem->set_node(4,
953 (i - (div_num - 1) * (div_num - 1)) * 2 + 1));
954 new_elem->set_node(5,
956 (i - (div_num - 1) * (div_num - 1)) * 2 + 2 +
957 ((div_num - 1) * 4 + 1)));
958 new_elem->set_node(6,
960 (i - (div_num - 1) * (div_num - 1)) * 2 + 1 +
961 ((div_num - 1) * 4 + 1) * 2));
962 new_elem->set_node(7,
964 (i - (div_num - 1) * (div_num - 1)) * 2 +
965 ((div_num - 1) * 4 + 1)));
970 if (create_outward_interface_boundaries)
971 boundary_info.
add_side(elem_Quad, 2, 1 + boundary_id_shift);
972 if (i == (div_num - 1) * (div_num - 1))
974 if (i == div_num * div_num - 2)
976 if (assign_external_boundary)
979 if (generate_side_specific_boundaries)
1154 const unsigned int num_sectors_per_side,
1155 const unsigned int peripheral_invervals,
1156 const std::vector<std::pair<Real, Real>> & positions_inner,
1157 const std::vector<std::pair<Real, Real>> & d_positions_outer,
1160 const bool create_inward_interface_boundaries,
1161 const bool create_outward_interface_boundaries)
1164 std::pair<Real, Real> positions_p;
1167 for (
unsigned int i = 0; i <= peripheral_invervals; i++)
1169 for (
unsigned int j = 0; j <= num_sectors_per_side / 2; j++)
1172 positions_inner[0].second,
1173 d_positions_outer[0].first,
1174 d_positions_outer[0].second,
1175 positions_inner[1].first,
1176 positions_inner[1].second,
1177 d_positions_outer[1].first,
1178 d_positions_outer[1].second,
1181 num_sectors_per_side,
1182 peripheral_invervals);
1185 for (
unsigned int j = 1; j <= num_sectors_per_side / 2; j++)
1188 positions_inner[1].second,
1189 d_positions_outer[1].first,
1190 d_positions_outer[1].second,
1191 positions_inner[2].first,
1192 positions_inner[2].second,
1193 d_positions_outer[2].first,
1194 d_positions_outer[2].second,
1197 num_sectors_per_side,
1198 peripheral_invervals);
1206 for (
unsigned int i = 0; i < peripheral_invervals; i++)
1208 for (
unsigned int j = 0; j < num_sectors_per_side; j++)
1210 std::unique_ptr<Elem> new_elem;
1212 new_elem = std::make_unique<Quad4>();
1213 new_elem->set_node(0,
mesh->
node_ptr(j + (num_sectors_per_side + 1) * (i)));
1214 new_elem->set_node(1,
mesh->
node_ptr(j + 1 + (num_sectors_per_side + 1) * (i)));
1215 new_elem->set_node(2,
mesh->
node_ptr(j + 1 + (num_sectors_per_side + 1) * (i + 1)));
1216 new_elem->set_node(3,
mesh->
node_ptr(j + (num_sectors_per_side + 1) * (i + 1)));
1225 if (create_inward_interface_boundaries)
1228 if (i == peripheral_invervals - 1)
1231 if (create_outward_interface_boundaries)
1236 if (j == num_sectors_per_side - 1)