PeriDEM 0.2.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
vtkReader.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2024 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "vtkReader.h"
12
13#include <vtkAbstractArray.h>
14#include <vtkCellArray.h>
15#include <vtkCellData.h>
16#include <vtkDoubleArray.h>
17#include <vtkFieldData.h>
18#include <vtkIdList.h>
19#include <vtkIntArray.h>
20#include <vtkPointData.h>
21#include <vtkPoints.h>
22#include <vtkUnsignedCharArray.h>
23#include <vtkUnsignedIntArray.h>
24
25#include "util/feElementDefs.h"
26#include "util/io.h"
27
29
30rw::reader::VtkReader::VtkReader(const std::string &filename) {
31 d_count++;
32
33 auto f = util::io::checkAndCreateNewFilename(filename, "vtu");
34
35 // Append the extension vtu to file_name
36 d_reader_p = vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();
37 d_reader_p->SetFileName(const_cast<char *>(f.c_str()));
38 d_reader_p->Update();
39}
40
42 std::vector<util::Point> *nodes,
43 size_t &element_type, size_t &num_elem,
44 std::vector<size_t> *enc,
45 std::vector<std::vector<size_t>> *nec,
46 std::vector<double> *volumes, bool is_fd) {
47 //
48 // For nodes, we read following data
49 // 1. nodes initial configuration
50 // 2. nodes volume (if provided)
51 // 3. nodes element connectivity (if provided)
52 //
53 // For elements, we read following data
54 // 1. element node connectivity
55 // 2. element type
56 //
57 d_grid_p = d_reader_p->GetOutput();
58 vtkIdType num_nodes = d_grid_p->GetNumberOfPoints();
59 vtkIdType num_elems = d_grid_p->GetNumberOfCells();
60
61 // read point field data
62 vtkPointData *p_field = d_grid_p->GetPointData();
63
64 // check if file contains nodal volumes
65 bool has_volume = true;
66 if (p_field->HasArray("Node_Volume") == 0 and
67 p_field->HasArray("Volume") == 0)
68 has_volume = false;
69 vtkDataArray *vol_array;
70 if (has_volume) {
71 if (p_field->HasArray("Node_Volume"))
72 vol_array = p_field->GetArray("Node_Volume");
73 else if (p_field->HasArray("Volume"))
74 vol_array = p_field->GetArray("Volume");
75 }
76
77 // resize data
78 nodes->resize(num_nodes);
79 if (has_volume) volumes->resize(num_nodes);
80
81 // Below is not efficient and need improvement
82 // declare another array data to hold the ux,uy,uz
83 auto u_a = vtkSmartPointer<vtkDoubleArray>::New();
84 u_a->SetNumberOfComponents(3);
85 u_a->Allocate(3, 1); // allocate memory
86
87 auto fix_a = vtkSmartPointer<vtkUnsignedIntArray>::New();
88 fix_a->SetNumberOfComponents(1);
89 fix_a->Allocate(1, 1); // allocate memory
90
91 auto vol_a = vtkSmartPointer<vtkDoubleArray>::New();
92 vol_a->SetNumberOfComponents(1);
93 vol_a->Allocate(1, 1); // allocate memory
94
95 auto con_a = vtkSmartPointer<vtkIntArray>::New();
96 con_a->SetNumberOfComponents(11);
97 con_a->Allocate(11, 1); // allocate memory
98
99 for (size_t i = 0; i < num_nodes; i++) {
100 vtkIdType id = i;
101
102 double x[3];
103 d_grid_p->GetPoint(id, x);
104
105 util::Point i_node = util::Point(x[0], x[1], x[2]);
106 (*nodes)[i] = i_node;
107
108 // read node volume
109 if (has_volume) {
110 vol_array->GetTuples(i, i, vol_a);
111 (*volumes)[i] = vol_a->GetValue(0);
112 }
113 }
114
115 // if mesh is for finite difference simulation and if we have read the
116 // volume data then we do not need to go further
117 if (is_fd and has_volume) return;
118
119 // read elements
120 // to resize element-node connectivity, we need to know the number of
121 // vertex in the given element type
122 num_elem = num_elems;
123
124 // resize node-element connectivity
125 nec->resize(num_nodes);
126
127 // get cell types array
128 vtkUnsignedCharArray *elem_types = d_grid_p->GetCellTypesArray();
129
130 // read cell field data
131 vtkCellData *c_field = d_grid_p->GetCellData();
132
133 int nds_per_el = 0;
134 for (size_t i = 0; i < num_elems; i++) {
135 vtkIdType id = i;
136 vtkIdType num_ids;
137 vtkIdType const *nodes_ids;
138
139 d_grid_p->GetCellPoints(id, num_ids, nodes_ids);
140
141 // resize element-node connectivity data in the beginning of the loop
142 if (i == 0) {
143 elem_types->GetTuples(i, i, fix_a);
144 element_type = fix_a->GetValue(0);
145
146 nds_per_el = util::vtk_map_element_to_num_nodes[element_type];
147
148 // std::cout << "nodes per element = " << nds_per_el << "\n";
149 // std::cout << "Num elements = " << num_elems << "\n";
150
151 // resize the element-node connectivity
152 enc->resize(nds_per_el * num_elems);
153 }
154
155 for (size_t j = 0; j < num_ids; j++) {
156 // read element-node connectivity data
157 (*enc)[nds_per_el * i + j] = nodes_ids[j];
158
159 // update node-element connectivity data
160 (*nec)[nodes_ids[j]].push_back(i);
161 }
162 }
163}
164
165void rw::reader::VtkReader::readNodes(std::vector<util::Point> *nodes) {
166 d_grid_p = d_reader_p->GetOutput();
167 vtkIdType num_nodes = d_grid_p->GetNumberOfPoints();
168
169 // resize data
170 nodes->clear();
171 nodes->resize(num_nodes);
172 for (size_t i = 0; i < num_nodes; i++) {
173 vtkIdType id = i;
174
175 double x[3];
176 d_grid_p->GetPoint(id, x);
177
178 util::Point i_node = util::Point(x[0], x[1], x[2]);
179 (*nodes)[i] = i_node;
180 }
181}
182
183void rw::reader::VtkReader::readCells(size_t dim, size_t &element_type,
184 size_t &num_elem,
185 std::vector<size_t> *enc,
186 std::vector<std::vector<size_t>> *nec) {
187 d_grid_p = d_reader_p->GetOutput();
188 vtkIdType num_nodes = d_grid_p->GetNumberOfPoints();
189 vtkIdType num_elems = d_grid_p->GetNumberOfCells();
190
191 // set number of elements
192 num_elem = num_elems;
193
194 // resize data (we resize enc data inside loop, see below)
195 nec->clear();
196 nec->resize(num_nodes);
197
198 // get cell types array
199 vtkUnsignedCharArray *elem_types = d_grid_p->GetCellTypesArray();
200
201 // read cell field data
202 vtkCellData *c_field = d_grid_p->GetCellData();
203
204 // to hold integer
205 auto val = vtkSmartPointer<vtkUnsignedIntArray>::New();
206 val->SetNumberOfComponents(1);
207 val->Allocate(1, 1); // allocate memory
208
209 int nds_per_el = 0;
210 for (size_t i = 0; i < num_elems; i++) {
211 vtkIdType id = i;
212 vtkIdType num_ids;
213 vtkIdType const *nodes_ids;
214
215 d_grid_p->GetCellPoints(id, num_ids, nodes_ids);
216
217 // resize element-node connectivity data in the beginning of the loop
218 if (i == 0) {
219 elem_types->GetTuples(i, i, val);
220 element_type = val->GetValue(0);
221
222 nds_per_el = util::vtk_map_element_to_num_nodes[element_type];
223
224 // std::cout << "nodes per element = " << nds_per_el << "\n";
225 // std::cout << "Num elements = " << num_elems << "\n";
226
227 // resize the element-node connectivity
228 enc->clear();
229 enc->resize(nds_per_el * num_elems);
230 }
231
232 for (size_t j = 0; j < num_ids; j++) {
233 // read element-node connectivity data
234 (*enc)[nds_per_el * i + j] = nodes_ids[j];
235
236 // update node-element connectivity data
237 (*nec)[nodes_ids[j]].push_back(i);
238 }
239 }
240}
241
242bool rw::reader::VtkReader::readPointData(const std::string &name,
243 std::vector<uint8_t> *data) {
244 // read point field data
245 d_grid_p = d_reader_p->GetOutput();
246 vtkPointData *p_field = d_grid_p->GetPointData();
247
248 // handle for displacement, fixity and node element connectivity
249 if (p_field->HasArray(name.c_str()) == 0) return false;
250
251 vtkDataArray *array = p_field->GetArray(name.c_str());
252
253 // Below is not efficient. Later this can be improved.
254 // declare another array data to hold the ux,uy,uz
255 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
256 data_a->SetNumberOfComponents(1);
257 data_a->Allocate(1, 1); // allocate memory
258
259 (*data).resize(array->GetNumberOfTuples());
260 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
261 array->GetTuples(i, i, data_a);
262 (*data)[i] = data_a->GetValue(0);
263 }
264
265 return true;
266}
267
268bool rw::reader::VtkReader::readPointData(const std::string &name,
269 std::vector<size_t> *data) {
270 // read point field data
271 d_grid_p = d_reader_p->GetOutput();
272 vtkPointData *p_field = d_grid_p->GetPointData();
273
274 // handle for displacement, fixity and node element connectivity
275 if (p_field->HasArray(name.c_str()) == 0) return false;
276
277 vtkDataArray *array = p_field->GetArray(name.c_str());
278
279 // Below is not efficient. Later this can be improved.
280 // declare another array data to hold the ux,uy,uz
281 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
282 data_a->SetNumberOfComponents(1);
283 data_a->Allocate(1, 1); // allocate memory
284
285 (*data).resize(array->GetNumberOfTuples());
286 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
287 array->GetTuples(i, i, data_a);
288 (*data)[i] = data_a->GetValue(0);
289 }
290
291 return true;
292}
293
294bool rw::reader::VtkReader::readPointData(const std::string &name,
295 std::vector<int> *data) {
296 // read point field data
297 d_grid_p = d_reader_p->GetOutput();
298 vtkPointData *p_field = d_grid_p->GetPointData();
299
300 // handle for displacement, fixity and node element connectivity
301 if (p_field->HasArray(name.c_str()) == 0) return false;
302
303 vtkDataArray *array = p_field->GetArray(name.c_str());
304
305 // Below is not efficient. Later this can be improved.
306 // declare another array data to hold the ux,uy,uz
307 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
308 data_a->SetNumberOfComponents(1);
309 data_a->Allocate(1, 1); // allocate memory
310
311 (*data).resize(array->GetNumberOfTuples());
312 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
313 array->GetTuples(i, i, data_a);
314 (*data)[i] = data_a->GetValue(0);
315 }
316
317 return true;
318}
319
320bool rw::reader::VtkReader::readPointData(const std::string &name,
321 std::vector<float> *data) {
322 // read point field data
323 d_grid_p = d_reader_p->GetOutput();
324 vtkPointData *p_field = d_grid_p->GetPointData();
325
326 // handle for displacement, fixity and node element connectivity
327 if (p_field->HasArray(name.c_str()) == 0) return false;
328
329 vtkDataArray *array = p_field->GetArray(name.c_str());
330
331 // Below is not efficient. Later this can be improved.
332 // declare another array data to hold the ux,uy,uz
333 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
334 data_a->SetNumberOfComponents(1);
335 data_a->Allocate(1, 1); // allocate memory
336
337 (*data).resize(array->GetNumberOfTuples());
338 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
339 array->GetTuples(i, i, data_a);
340 (*data)[i] = data_a->GetValue(0);
341 }
342
343 return true;
344}
345
346bool rw::reader::VtkReader::readPointData(const std::string &name,
347 std::vector<double> *data) {
348 // read point field data
349 d_grid_p = d_reader_p->GetOutput();
350 vtkPointData *p_field = d_grid_p->GetPointData();
351
352 // handle for displacement, fixity and node element connectivity
353 if (p_field->HasArray(name.c_str()) == 0) return false;
354
355 vtkDataArray *array = p_field->GetArray(name.c_str());
356
357 // Below is not efficient. Later this can be improved.
358 // declare another array data to hold the ux,uy,uz
359 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
360 data_a->SetNumberOfComponents(1);
361 data_a->Allocate(1, 1); // allocate memory
362
363 (*data).resize(array->GetNumberOfTuples());
364 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
365 array->GetTuples(i, i, data_a);
366 (*data)[i] = data_a->GetValue(0);
367 }
368
369 return true;
370}
371
372bool rw::reader::VtkReader::readPointData(const std::string &name,
373 std::vector<util::Point> *data) {
374 // read point field data
375 d_grid_p = d_reader_p->GetOutput();
376 vtkPointData *p_field = d_grid_p->GetPointData();
377
378 // handle for displacement, fixity and node element connectivity
379 if (p_field->HasArray(name.c_str()) == 0) return false;
380
381 vtkDataArray *array = p_field->GetArray(name.c_str());
382
383 // Below is not efficient. Later this can be improved.
384 // declare another array data to hold the ux,uy,uz
385 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
386 data_a->SetNumberOfComponents(3);
387 data_a->Allocate(3, 1); // allocate memory
388
389 (*data).resize(array->GetNumberOfTuples());
390 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
391 array->GetTuples(i, i, data_a);
392 (*data)[i] = util::Point(data_a->GetValue(0), data_a->GetValue(1),
393 data_a->GetValue(2));
394 }
395
396 return true;
397}
398
399bool rw::reader::VtkReader::readPointData(const std::string &name,
400 std::vector<util::SymMatrix3> *data) {
401 // read point field data
402 d_grid_p = d_reader_p->GetOutput();
403 vtkPointData *p_field = d_grid_p->GetPointData();
404
405 // handle for displacement, fixity and node element connectivity
406 if (p_field->HasArray(name.c_str()) == 0) return false;
407
408 vtkDataArray *array = p_field->GetArray(name.c_str());
409
410 // Below is not efficient. Later this can be improved.
411 // declare another array data to hold the ux,uy,uz
412 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
413 data_a->SetNumberOfComponents(6);
414 data_a->Allocate(6, 1); // allocate memory
415
416 (*data).resize(array->GetNumberOfTuples());
417 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
418 array->GetTuples(i, i, data_a);
419 (*data)[i] = util::SymMatrix3({data_a->GetValue(0), data_a->GetValue(1),
420 data_a->GetValue(2), data_a->GetValue(3),
421 data_a->GetValue(4), data_a->GetValue(5)});
422 }
423
424 return true;
425}
426
427bool rw::reader::VtkReader::readPointData(const std::string &name,
428 std::vector<util::Matrix3> *data) {
429 // read point field data
430 d_grid_p = d_reader_p->GetOutput();
431 vtkPointData *p_field = d_grid_p->GetPointData();
432
433 // handle for displacement, fixity and node element connectivity
434 if (p_field->HasArray(name.c_str()) == 0) return false;
435
436 vtkDataArray *array = p_field->GetArray(name.c_str());
437
438 // Below is not efficient. Later this can be improved.
439 // declare another array data to hold the ux,uy,uz
440 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
441 data_a->SetNumberOfComponents(6);
442 data_a->Allocate(6, 1); // allocate memory
443
444 (*data).resize(array->GetNumberOfTuples());
445 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
446 array->GetTuples(i, i, data_a);
447
449 m(0,0) = data_a->GetValue(0);
450 m(1,1) = data_a->GetValue(1);
451 m(2,2) = data_a->GetValue(2);
452 m(1,2) = data_a->GetValue(3);
453 m(0,2) = data_a->GetValue(4);
454 m(0,1) = data_a->GetValue(5);
455
456 // symmetrize
457 m(2,1) = m(1,2);
458 m(2,0) = m(0,2);
459 m(1,0) = m(0,1);
460
461 // add to the data
462 (*data)[i] = m;
463 }
464
465 return true;
466}
467
468bool rw::reader::VtkReader::readCellData(const std::string &name,
469 std::vector<float> *data) {
470 // read point field data
471 d_grid_p = d_reader_p->GetOutput();
472 vtkCellData *c_field = d_grid_p->GetCellData();
473
474 // handle for displacement, fixity and node element connectivity
475 if (c_field->HasArray(name.c_str()) == 0) return false;
476
477 vtkDataArray *array = c_field->GetArray(name.c_str());
478
479 // Below is not efficient. Later this can be improved.
480 // declare another array data to hold the ux,uy,uz
481 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
482 data_a->SetNumberOfComponents(1);
483 data_a->Allocate(1, 1); // allocate memory
484
485 (*data).resize(array->GetNumberOfTuples());
486 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
487 array->GetTuples(i, i, data_a);
488 (*data)[i] = data_a->GetValue(0);
489 }
490
491 return true;
492}
493
494bool rw::reader::VtkReader::readCellData(const std::string &name,
495 std::vector<double> *data) {
496 // read point field data
497 d_grid_p = d_reader_p->GetOutput();
498 vtkCellData *c_field = d_grid_p->GetCellData();
499
500 // handle for displacement, fixity and node element connectivity
501 if (c_field->HasArray(name.c_str()) == 0) return false;
502
503 vtkDataArray *array = c_field->GetArray(name.c_str());
504
505 // Below is not efficient. Later this can be improved.
506 // declare another array data to hold the ux,uy,uz
507 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
508 data_a->SetNumberOfComponents(1);
509 data_a->Allocate(1, 1); // allocate memory
510
511 (*data).resize(array->GetNumberOfTuples());
512 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
513 array->GetTuples(i, i, data_a);
514 (*data)[i] = data_a->GetValue(0);
515 }
516
517 return true;
518}
519
520bool rw::reader::VtkReader::readCellData(const std::string &name,
521 std::vector<util::Point> *data) {
522 // read point field data
523 d_grid_p = d_reader_p->GetOutput();
524 vtkCellData *c_field = d_grid_p->GetCellData();
525
526 // handle for displacement, fixity and node element connectivity
527 if (c_field->HasArray(name.c_str()) == 0) return false;
528
529 vtkDataArray *array = c_field->GetArray(name.c_str());
530
531 // Below is not efficient. Later this can be improved.
532 // declare another array data to hold the ux,uy,uz
533 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
534 data_a->SetNumberOfComponents(3);
535 data_a->Allocate(3, 1); // allocate memory
536
537 (*data).resize(array->GetNumberOfTuples());
538 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
539 array->GetTuples(i, i, data_a);
540 (*data)[i] = util::Point(data_a->GetValue(0), data_a->GetValue(1),
541 data_a->GetValue(2));
542 }
543
544 return true;
545}
546
547bool rw::reader::VtkReader::readCellData(const std::string &name,
548 std::vector<util::SymMatrix3> *data) {
549 // read point field data
550 d_grid_p = d_reader_p->GetOutput();
551 vtkCellData *c_field = d_grid_p->GetCellData();
552
553 // handle for displacement, fixity and node element connectivity
554 if (c_field->HasArray(name.c_str()) == 0) return false;
555
556 vtkDataArray *array = c_field->GetArray(name.c_str());
557
558 // Below is not efficient. Later this can be improved.
559 // declare another array data to hold the ux,uy,uz
560 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
561 data_a->SetNumberOfComponents(6);
562 data_a->Allocate(6, 1); // allocate memory
563
564 (*data).resize(array->GetNumberOfTuples());
565 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
566 array->GetTuples(i, i, data_a);
567 (*data)[i] = util::SymMatrix3({data_a->GetValue(0), data_a->GetValue(1),
568 data_a->GetValue(2), data_a->GetValue(3),
569 data_a->GetValue(4), data_a->GetValue(5)});
570 }
571
572 return true;
573}
574
575bool rw::reader::VtkReader::readCellData(const std::string &name,
576 std::vector<util::Matrix3> *data) {
577 // read point field data
578 d_grid_p = d_reader_p->GetOutput();
579 vtkCellData *c_field = d_grid_p->GetCellData();
580
581 // handle for displacement, fixity and node element connectivity
582 if (c_field->HasArray(name.c_str()) == 0) return false;
583
584 vtkDataArray *array = c_field->GetArray(name.c_str());
585
586 // Below is not efficient. Later this can be improved.
587 // declare another array data to hold the ux,uy,uz
588 auto data_a = vtkSmartPointer<vtkDoubleArray>::New();
589 data_a->SetNumberOfComponents(6);
590 data_a->Allocate(6, 1); // allocate memory
591
592 (*data).resize(array->GetNumberOfTuples());
593 for (size_t i = 0; i < array->GetNumberOfTuples(); i++) {
594 array->GetTuples(i, i, data_a);
595
597 m(0,0) = data_a->GetValue(0);
598 m(1,1) = data_a->GetValue(1);
599 m(2,2) = data_a->GetValue(2);
600 m(1,2) = data_a->GetValue(3);
601 m(0,2) = data_a->GetValue(4);
602 m(0,1) = data_a->GetValue(5);
603
604 // symmetrize
605 m(2,1) = m(1,2);
606 m(2,0) = m(0,2);
607 m(1,0) = m(0,1);
608
609 // add to the data
610 (*data)[i] = m;
611 }
612
613 return true;
614}
615
617 // delete d_reader_p;
618 // delete d_grid_p;
619}
void close()
Close the file.
static size_t d_count
Counter.
Definition vtkReader.h:133
bool readPointData(const std::string &name, std::vector< uint8_t > *data)
reads point data from .vtu file
void readNodes(std::vector< util::Point > *nodes)
Reads nodal position.
VtkReader(const std::string &filename)
Constructor.
Definition vtkReader.cpp:30
bool readCellData(const std::string &name, std::vector< float > *data)
reads cell data from .vtu file
void readMesh(size_t dim, std::vector< util::Point > *nodes, size_t &element_type, size_t &num_elems, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec, std::vector< double > *volumes, bool is_fd=false)
Reads mesh data into node file and element file.
Definition vtkReader.cpp:41
void readCells(size_t dim, size_t &element_type, size_t &num_elems, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec)
Reads cell data, i.e. element-node connectivity and node-element connectivity.
vtkSmartPointer< vtkXMLUnstructuredGridReader > d_reader_p
XML unstructured grid writer.
Definition vtkReader.h:136
static int vtk_map_element_to_num_nodes[16]
Map from element type to number of nodes (for vtk)
std::string checkAndCreateNewFilename(std::string const &filename, std::string filename_ext)
Check for extension and if possible create new filename from a given filename and a given extension.
Definition io.h:443
A structure to represent 3d matrices.
Definition matrix.h:19
A structure to represent 3d vectors.
Definition point.h:30
A structure to represent 3d matrices.
Definition matrix.h:258