8 #include <deal.II/arborx/bvh.h>
9 #include <deal.II/grid/filtered_iterator.h>
11 #include <boost/algorithm/string.hpp>
20 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
21 std::vector<double>, std::vector<double>>
23 boost::property_tree::ptree
const &geometry_database,
27 bool material_deposition =
28 geometry_database.get(
"material_deposition",
false);
30 if (!material_deposition)
31 return {{}, {}, {}, {}};
34 geometry_database.get<std::string>(
"material_deposition_method");
38 return read_material_deposition<dim>(geometry_database);
43 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
44 std::vector<double>, std::vector<double>>>
46 for (
auto const &source : heat_sources)
48 deposition_paths.emplace_back(deposition_along_scan_path<dim>(
49 geometry_database, source->get_scan_path()));
52 return merge_deposition_paths<dim>(deposition_paths);
57 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
58 std::vector<double>, std::vector<double>>
62 std::string material_deposition_filename =
63 geometry_database.get<std::string>(
"material_deposition_file");
65 std::vector<dealii::BoundingBox<dim>> material_deposition_boxes;
66 std::vector<double> material_deposition_times;
67 std::vector<double> material_deposition_cos;
68 std::vector<double> material_deposition_sin;
72 "Waiting for material deposition file: " +
73 material_deposition_filename);
75 file.open(material_deposition_filename);
78 int dim_ = std::stoi(
line);
79 ASSERT_THROW(dim_ == dim,
"Dimension in " + material_deposition_filename +
80 " does not match " + std::to_string(dim) +
82 while (getline(file,
line))
84 std::vector<std::string> split_line;
85 boost::split(split_line,
line, boost::is_any_of(
" "),
86 boost::token_compress_on);
88 std::vector<double> center(dim);
89 for (
int d = 0; d < dim; ++d)
91 center[d] = std::stod(split_line[d]);
94 std::vector<double> box_size(dim);
95 for (
int d = 0; d < dim; ++d)
97 box_size[d] = std::stod(split_line[dim + d]);
100 material_deposition_times.push_back(std::stod(split_line[2 * dim]));
102 unsigned int times_size = material_deposition_times.size();
104 ASSERT_THROW(material_deposition_times[times_size - 2] <=
105 material_deposition_times[times_size - 1],
106 "Time stamp not increasing.");
108 double deposition_angle = std::stod(split_line[2 * dim + 1]);
109 material_deposition_cos.push_back(std::cos(deposition_angle));
110 material_deposition_sin.push_back(std::sin(deposition_angle));
113 dealii::Point<dim> bounding_pt_a;
114 dealii::Point<dim> bounding_pt_b;
115 for (
int d = 0; d < dim; ++d)
117 bounding_pt_a[d] = center[d] - 0.5 * box_size[d];
118 bounding_pt_b[d] = center[d] + 0.5 * box_size[d];
120 material_deposition_boxes.emplace_back(
121 std::make_pair(bounding_pt_a, bounding_pt_b));
125 return std::make_tuple(material_deposition_boxes, material_deposition_times,
126 material_deposition_cos, material_deposition_sin);
130 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
131 std::vector<double>, std::vector<double>>
135 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
136 std::vector<double>, std::vector<double>>
138 int constexpr tuple_box = 0;
139 int constexpr tuple_time = 1;
140 int constexpr tuple_cos = 2;
141 int constexpr tuple_sin = 3;
146 double deposition_length = geometry_database.get<
double>(
"deposition_length");
148 double deposition_height = geometry_database.get<
double>(
"deposition_height");
150 double deposition_width =
151 geometry_database.get<
double>(
"deposition_width", 0.0);
154 double lead_time = geometry_database.get<
double>(
"deposition_lead_time");
158 double segment_start_time = 0.0;
159 dealii::Point<3> segment_start_point = segment_list.at(0).end_point;
163 double const eps = 1.0e-12;
164 double const eps_time = 1.0e-12;
165 if (segment.power_modifier > eps)
167 dealii::Point<3> segment_end_point = segment.end_point;
168 double const segment_length =
169 segment_end_point.distance(segment_start_point);
170 bool in_segment =
true;
171 dealii::Point<3> center = segment_start_point;
172 double const segment_velocity =
173 segment_length / (segment.end_time - segment_start_time);
179 ? (segment_end_point[0] - segment_start_point[0]) / segment_length
183 ? (segment_end_point[1] - segment_start_point[1]) / segment_length
185 bool const segment_along_x = std::abs(cos) > std::abs(sin) ? true :
false;
186 double next_box_length = deposition_length;
190 double distance_to_box_center = center.distance(segment_start_point);
191 double time_to_box_center =
192 segment_velocity != 0. ? distance_to_box_center / segment_velocity
195 std::vector<double> box_size(dim);
206 box_size.at(
axis<dim>::x) = std::abs(cos) * next_box_length;
208 deposition_width + std::abs(sin) * next_box_length;
213 deposition_width + std::abs(cos) * next_box_length;
214 box_size.at(
axis<dim>::y) = std::abs(sin) * next_box_length;
218 dealii::Point<dim> bounding_pt_a;
219 dealii::Point<dim> bounding_pt_b;
220 for (
int d = 0; d < dim - 1; ++d)
222 bounding_pt_a[d] = center[d] - 0.5 * box_size[d];
223 bounding_pt_b[d] = center[d] + 0.5 * box_size[d];
225 bounding_pt_a[dim - 1] = center[dim - 1] - box_size[dim - 1];
226 bounding_pt_b[dim - 1] = center[dim - 1];
228 std::get<tuple_box>(deposition_path)
229 .push_back(std::make_pair(bounding_pt_a, bounding_pt_b));
230 std::get<tuple_time>(deposition_path)
232 segment_start_time + time_to_box_center - lead_time, eps_time));
233 std::get<tuple_cos>(deposition_path).push_back(cos);
234 std::get<tuple_sin>(deposition_path).push_back(sin);
237 if (distance_to_box_center + eps > segment_length)
245 double center_increment = deposition_length;
246 if (distance_to_box_center + deposition_length > segment_length)
248 center_increment = deposition_length / 2.0 +
249 (segment_length - distance_to_box_center) / 2.0;
250 next_box_length = segment_length - distance_to_box_center;
253 center[0] += cos * center_increment;
254 center[1] += sin * center_increment;
258 segment_start_point = segment.end_point;
259 segment_start_time = segment.end_time;
261 return deposition_path;
265 std::tuple<std::vector<dealii::BoundingBox<dim>>, std::vector<double>,
266 std::vector<double>, std::vector<double>>
268 std::vector<std::tuple<std::vector<dealii::BoundingBox<dim>>,
269 std::vector<double>, std::vector<double>,
270 std::vector<double>>>
const &deposition_paths)
273 std::vector<dealii::BoundingBox<dim>> bounding_boxes;
274 std::vector<double> time;
275 std::vector<double> cos;
276 std::vector<double> sin;
277 for (
auto const &path : deposition_paths)
279 bounding_boxes.insert(bounding_boxes.end(), std::get<0>(path).begin(),
280 std::get<0>(path).end());
281 time.insert(time.end(), std::get<1>(path).begin(), std::get<1>(path).end());
282 cos.insert(cos.end(), std::get<2>(path).begin(), std::get<2>(path).end());
283 sin.insert(sin.end(), std::get<3>(path).begin(), std::get<3>(path).end());
287 unsigned int const n_boxes = bounding_boxes.size();
288 std::vector<int> permutation(n_boxes);
289 std::iota(permutation.begin(), permutation.end(), 0);
290 std::sort(permutation.begin(), permutation.end(),
291 [&](
int const &i,
int const &j) { return time[i] < time[j]; });
296 std::vector<dealii::BoundingBox<dim>> permutated_bounding_boxes(n_boxes);
297 std::vector<double> permutated_time(n_boxes);
298 std::vector<double> permutated_cos(n_boxes);
299 std::vector<double> permutated_sin(n_boxes);
300 for (
unsigned int i = 0; i < n_boxes; ++i)
302 permutated_bounding_boxes[i] = bounding_boxes[permutation[i]];
303 permutated_time[i] = time[permutation[i]];
304 permutated_cos[i] = cos[permutation[i]];
305 permutated_sin[i] = sin[permutation[i]];
308 return std::make_tuple(permutated_bounding_boxes, permutated_time,
309 permutated_cos, permutated_sin);
313 std::vector<std::vector<typename dealii::DoFHandler<dim>::active_cell_iterator>>
315 dealii::DoFHandler<dim>
const &dof_handler,
316 std::vector<dealii::BoundingBox<dim>>
const &material_deposition_boxes)
319 if (material_deposition_boxes.size() == 0)
321 std::vector<typename dealii::DoFHandler<dim>::active_cell_iterator>>();
325 std::vector<dealii::BoundingBox<dim>> bounding_boxes;
326 std::vector<typename dealii::DoFHandler<dim>::active_cell_iterator>
328 for (
auto const &cell : dealii::filter_iterators(
329 dof_handler.active_cell_iterators(),
330 dealii::IteratorFilters::LocallyOwnedCell(),
331 dealii::IteratorFilters::ActiveFEIndexEqualTo(1)))
333 bounding_boxes.push_back(cell->bounding_box());
334 cell_iterators.push_back(cell);
338 dealii::ArborXWrappers::BVH bvh(bounding_boxes);
339 dealii::ArborXWrappers::BoundingBoxIntersectPredicate bb_intersect(
340 material_deposition_boxes);
341 auto [indices, offset] = bvh.query(bb_intersect);
343 unsigned int const n_queries = material_deposition_boxes.size();
345 std::vector<typename dealii::DoFHandler<dim>::active_cell_iterator>>
346 elements_to_activate(n_queries);
347 for (
unsigned int i = 0; i < n_queries; ++i)
349 for (
int j = offset[i]; j < offset[i + 1]; ++j)
351 elements_to_activate[i].push_back(cell_iterators[indices[j]]);
355 return elements_to_activate;
362 template std::tuple<std::vector<dealii::BoundingBox<2>>, std::vector<double>,
363 std::vector<double>, std::vector<double>>
365 boost::property_tree::ptree
const &geometry_database,
367 template std::tuple<std::vector<dealii::BoundingBox<3>>, std::vector<double>,
368 std::vector<double>, std::vector<double>>
370 boost::property_tree::ptree
const &geometry_database,
373 template std::tuple<std::vector<dealii::BoundingBox<2>>, std::vector<double>,
374 std::vector<double>, std::vector<double>>
376 template std::tuple<std::vector<dealii::BoundingBox<3>>, std::vector<double>,
377 std::vector<double>, std::vector<double>>
380 template std::vector<
381 std::vector<typename dealii::DoFHandler<2>::active_cell_iterator>>
383 dealii::DoFHandler<2>
const &dof_handler,
384 std::vector<dealii::BoundingBox<2>>
const &material_deposition_boxes);
385 template std::vector<
386 std::vector<typename dealii::DoFHandler<3>::active_cell_iterator>>
388 dealii::DoFHandler<3>
const &dof_handler,
389 std::vector<dealii::BoundingBox<3>>
const &material_deposition_boxes);
391 template std::tuple<std::vector<dealii::BoundingBox<2, double>>,
392 std::vector<double>, std::vector<double>,
395 std::vector<std::tuple<std::vector<dealii::BoundingBox<2, double>>,
396 std::vector<double>, std::vector<double>,
397 std::vector<double>>>
const &deposition_paths);
398 template std::tuple<std::vector<dealii::BoundingBox<3, double>>,
399 std::vector<double>, std::vector<double>,
402 std::vector<std::tuple<std::vector<dealii::BoundingBox<3, double>>,
403 std::vector<double>, std::vector<double>,
404 std::vector<double>>>
const &deposition_paths);
406 template std::tuple<std::vector<dealii::BoundingBox<2>>, std::vector<double>,
407 std::vector<double>, std::vector<double>>
410 template std::tuple<std::vector<dealii::BoundingBox<3>>, std::vector<double>,
411 std::vector<double>, std::vector<double>>
std::vector< ScanPathSegment > get_segment_list() const
std::tuple< std::vector< dealii::BoundingBox< dim > >, std::vector< double >, std::vector< double >, std::vector< double > > deposition_along_scan_path(boost::property_tree::ptree const &geometry_database, ScanPath const &scan_path)
void wait_for_file(std::string const &filename, std::string const &message)
std::tuple< std::vector< dealii::BoundingBox< dim > >, std::vector< double >, std::vector< double >, std::vector< double > > create_material_deposition_boxes(boost::property_tree::ptree const &geometry_database, std::vector< std::shared_ptr< HeatSource< dim >>> &heat_sources)
std::tuple< std::vector< dealii::BoundingBox< dim > >, std::vector< double >, std::vector< double >, std::vector< double > > merge_deposition_paths(std::vector< std::tuple< std::vector< dealii::BoundingBox< dim >>, std::vector< double >, std::vector< double >, std::vector< double >>> const &deposition_paths)
std::tuple< std::vector< dealii::BoundingBox< dim > >, std::vector< double >, std::vector< double >, std::vector< double > > read_material_deposition(boost::property_tree::ptree const &geometry_database)
void ASSERT_THROW(bool cond, std::string const &message)
std::vector< std::vector< typename dealii::DoFHandler< dim >::active_cell_iterator > > get_elements_to_activate(dealii::DoFHandler< dim > const &dof_handler, std::vector< dealii::BoundingBox< dim >> const &material_deposition_boxes)