17 #include <vtkCPDataDescription.h>
18 #include <vtkCPInputDataDescription.h>
19 #include <vtkDoubleArray.h>
20 #include <vtkExtentTranslator.h>
21 #include <vtkFloatArray.h>
23 #include <vtkPointData.h>
24 #include <vtkPoints.h>
35 typename type_ternary_operator<std::is_same<real_t, double>::value,
36 vtkDoubleArray, vtkFloatArray>::type;
40 vtkCPDataDescription* data_description) {
42 if (param->export_visualization) {
44 data_.resize(tinfo->GetMaxThreads());
49 #pragma omp parallel for schedule(static, 1)
50 for (uint64_t i = 0; i <
data_.size(); ++i) {
51 data_[i] = vtkImageData::New();
57 for (
auto& entry : param->visualize_diffusion) {
58 if (entry.name == name) {
66 for (uint64_t i = 0; i <
data_.size(); ++i) {
69 vtkNew<vtkRealArray> concentration;
70 concentration->SetName(
"Substance Concentration");
72 data_[i]->GetPointData()->AddArray(concentration.GetPointer());
75 vtkNew<vtkRealArray> gradient;
76 gradient->SetName(
"Diffusion Gradient");
77 gradient->SetNumberOfComponents(3);
79 data_[i]->GetPointData()->AddArray(gradient.GetPointer());
83 if (!param->export_visualization) {
84 data_description->AddInput(name.c_str());
85 data_description->GetInputDescriptionByName(name.c_str())
89 Log::Warning(
"VtkDiffusionGrid::VtkDiffusionGrid",
"Variable `name` (",
90 name,
") not found in `param->visualize_diffusion`.");
97 for (
auto& el :
data_) {
116 whole_extent_ = {{0, std::max(
static_cast<int>(num_boxes[0]) - 1, 0), 0,
117 std::max(
static_cast<int>(num_boxes[1]) - 1, 0), 0,
118 std::max(
static_cast<int>(num_boxes[2]) - 1, 0)}};
119 Dissect(num_boxes[2], tinfo->GetMaxThreads());
121 uint64_t xy_num_boxes = num_boxes[0] * num_boxes[1];
122 real_t origin_x = grid_dimensions[0] + box_length / 2.;
123 real_t origin_y = grid_dimensions[2] + box_length / 2.;
124 real_t origin_z = grid_dimensions[4] + box_length / 2.;
127 if (
data_.size() == 1) {
128 data_[0]->SetOrigin(origin_x, origin_y, origin_z);
129 data_[0]->SetDimensions(num_boxes[0], num_boxes[1], num_boxes[2]);
130 data_[0]->SetSpacing(box_length, box_length, box_length);
134 auto elements =
static_cast<vtkIdType
>(total_boxes);
137 array->SetArray(co_ptr, elements, 1);
141 auto elements =
static_cast<vtkIdType
>(total_boxes * 3);
144 array->SetArray(gr_ptr, elements, 1);
149 #pragma omp parallel for schedule(static, 1)
151 uint64_t piece_elements;
156 data_[i]->SetExtent(e[0], e[1], e[2], e[3], e[4],
161 data_[i]->SetExtent(e[0], e[1], e[2], e[3], e[4],
165 data_[i]->SetOrigin(origin_x, origin_y, piece_origin_z);
166 data_[i]->SetSpacing(box_length, box_length, box_length);
170 auto elements =
static_cast<vtkIdType
>(piece_elements);
174 array->SetArray(co_ptr + (elements * i), elements, 1);
176 array->SetArray(co_ptr + total_boxes - elements, elements, 1);
181 auto elements =
static_cast<vtkIdType
>(piece_elements * 3);
185 array->SetArray(gr_ptr + (elements * i), elements, 1);
187 array->SetArray(gr_ptr + total_boxes - elements, elements, 1);
205 if (num_pieces_target == 1) {
209 }
else if (boxes_z <= num_pieces_target) {
212 num_pieces_ = std::max<unsigned long long>(1ULL, boxes_z - 1);
214 auto boxes_per_piece =
static_cast<real_t>(boxes_z) / num_pieces_target;
215 piece_boxes_z_ =
static_cast<uint64_t
>(std::ceil(boxes_per_piece));
226 const std::array<size_t, 3>& num_boxes) {
234 static_cast<int>(num_boxes[1]) - 1, 0, c}};
237 static_cast<int>(num_boxes[1]) - 1, c,
241 piece_extents_.back() = {{0,
static_cast<int>(num_boxes[0]) - 1, 0,
242 static_cast<int>(num_boxes[1]) - 1, c,
243 static_cast<int>(num_boxes[2]) - 1}};