41 #include <vtkCellType.h>
42 #include <vtkXMLUnstructuredGridReader.h>
43 #include <vtkXMLPUnstructuredGridReader.h>
44 #include <vtkXMLUnstructuredGridWriter.h>
45 #include <vtkXMLPUnstructuredGridWriter.h>
46 #include <vtkUnstructuredGrid.h>
47 #include <vtkIntArray.h>
48 #include <vtkIdTypeArray.h>
49 #include <vtkUnsignedCharArray.h>
50 #include <vtkUnsignedIntArray.h>
51 #include <vtkDoubleArray.h>
53 #include <vtkPoints.h>
54 #include <vtkPointData.h>
55 #include <vtkDataArray.h>
56 #include <vtkCellData.h>
57 #include <vtkSmartPointer.h>
59 #include <vtkJPEGReader.h>
60 #include <vtkImageData.h>
61 #include <vtkDataSetTriangleFilter.h>
62 #include <vtkImageGaussianSmooth.h>
63 #include <vtkImageAnisotropicDiffusion2D.h>
65 #ifndef vtkFloatingPointType
66 #define vtkFloatingPointType vtkFloatingPointType
87 #ifdef HAVE_BOOST_UNORDERED_MAP_HPP
88 #include <boost/unordered_map.hpp>
98 vtkSmartPointer<vtkUnstructuredGrid> ug = vtkSmartPointer<vtkUnstructuredGrid>::New();
100 if(filename.substr(filename.find_last_of(
'.'))==
".pvtu"){
101 vtkSmartPointer<vtkXMLPUnstructuredGridReader> reader = vtkSmartPointer<vtkXMLPUnstructuredGridReader>::New();
102 reader->SetFileName(filename.c_str());
105 ug->DeepCopy(reader->GetOutput());
107 vtkSmartPointer<vtkXMLUnstructuredGridReader> reader = vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();
108 reader->SetFileName(filename.c_str());
111 ug->DeepCopy(reader->GetOutput());
114 size_t NNodes = ug->GetNumberOfPoints();
115 size_t NElements = ug->GetNumberOfCells();
117 std::map<int, int> renumber;
118 std::map<int, int> gnns;
120 std::vector<real_t> x,y,z;
122 bool have_global_ids = ug->GetPointData()->GetArray(
"GlobalId")!=NULL;
124 for(
size_t i=0;i<NNodes;i++){
125 int gnn = ug->GetPointData()->GetArray(
"GlobalId")->GetTuple1(i);
126 if(gnns.find(gnn)==gnns.end()){
132 ug->GetPoints()->GetPoint(i, r);
137 renumber[i] = gnns[gnn];
141 for(
size_t i=0;i<NNodes;i++){
143 ug->GetPoints()->GetPoint(i, r);
152 int cell_type = ug->GetCell(0)->GetCellType();
156 if(cell_type==VTK_TRIANGLE){
159 }
else if(cell_type==VTK_TETRA){
163 std::cerr<<
"ERROR("<<__FILE__<<
"): unsupported element type\n";
167 std::vector<int> ENList;
168 for(
size_t i=0;i<NElements;i++){
170 if(ug->GetCellData()->GetArray(
"vtkGhostLevels")!=NULL)
171 ghost = ug->GetCellData()->GetArray(
"vtkGhostLevels")->GetTuple1(i);
176 vtkCell *cell = ug->GetCell(i);
177 assert(cell->GetCellType()==cell_type);
178 for(
int j=0;j<nloc;j++){
180 ENList.push_back(renumber[cell->GetPointId(j)]);
182 ENList.push_back(cell->GetPointId(j));
185 NElements = ENList.size()/nloc;
191 MPI_Comm_size(MPI_COMM_WORLD, &nparts);
194 std::vector<index_t> owner_range;
195 std::vector<index_t> lnn2gnn;
196 std::vector<int> node_owner;
198 std::vector<int> epart(NElements, 0), npart(NNodes, 0);
200 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
205 std::vector<int> eind(NElements*nloc);
207 for(
size_t i=0;i<NElements*nloc;i++)
210 int intNElements = NElements;
211 int intNNodes = NNodes;
213 #ifdef METIS_VER_MAJOR
214 int vsize = nloc - 1;
215 std::vector<int> eptr(NElements+1);
216 for(
size_t i=0;i<NElements;i++)
217 eptr[i+1] = eptr[i]+nloc;
218 METIS_PartMeshNodal(&intNElements,
231 std::vector<int> etype(NElements);
232 for(
size_t i=0;i<NElements;i++)
235 METIS_PartMeshNodal(&intNElements,
248 MPI_Datatype MPI_INDEX_T = mpi_index_t_wrapper.
mpi_type;
250 MPI_Bcast(&(epart[0]), NElements, MPI_INDEX_T, 0, MPI_COMM_WORLD);
251 MPI_Bcast(&(npart[0]), NNodes, MPI_INDEX_T, 0, MPI_COMM_WORLD);
254 std::vector< std::vector<index_t> > node_partition(nparts);
255 for(
size_t i=0;i<NNodes;i++)
256 node_partition[npart[i]].push_back(i);
258 #ifdef HAVE_BOOST_UNORDERED_MAP_HPP
259 boost::unordered_map<index_t, index_t> renumber;
261 std::map<index_t, index_t> renumber;
265 owner_range.push_back(0);
266 for(
int i=0;i<nparts;i++){
267 int pNNodes = node_partition[i].size();
268 owner_range.push_back(owner_range[i]+pNNodes);
269 for(
int j=0;j<pNNodes;j++)
270 renumber[node_partition[i][j]] = pos++;
273 std::vector<index_t> element_partition;
274 std::set<index_t> halo_nodes;
275 for(
size_t i=0;i<NElements;i++){
276 std::set<index_t> residency;
277 for(
int j=0;j<nloc;j++)
278 residency.insert(npart[ENList[i*nloc+j]]);
280 if(residency.count(rank)){
281 element_partition.push_back(i);
283 for(
int j=0;j<nloc;j++){
284 index_t nid = ENList[i*nloc+j];
286 halo_nodes.insert(nid);
292 for(
typename std::set<index_t>::const_iterator it=halo_nodes.begin();it!=halo_nodes.end();++it){
293 node_partition[rank].push_back(*it);
297 NNodes = node_partition[rank].size();
298 lnn2gnn.resize(NNodes);
299 node_owner.resize(NNodes);
300 for(
size_t i=0;i<NNodes;i++){
301 index_t nid = node_partition[rank][i];
304 node_owner[i] = npart[nid];
308 std::vector<real_t> lx(NNodes), ly(NNodes), lz(NNodes);
310 for(
size_t i=0;i<NNodes;i++){
311 lx[i] = x[node_partition[rank][i]];
312 ly[i] = y[node_partition[rank][i]];
315 for(
size_t i=0;i<NNodes;i++){
316 lx[i] = x[node_partition[rank][i]];
317 ly[i] = y[node_partition[rank][i]];
318 lz[i] = z[node_partition[rank][i]];
322 NElements = element_partition.size();
323 std::vector<index_t> lENList(NElements*nloc);
324 for(
size_t i=0;i<NElements;i++){
325 for(
int j=0;j<nloc;j++){
326 index_t nid = renumber[ENList[element_partition[i]*nloc+j]];
327 lENList[i*nloc+j] = nid;
336 ENList.swap(lENList);
338 MPI_Comm comm = MPI_COMM_WORLD;
341 mesh =
new Mesh<real_t>(NNodes, NElements, &(ENList[0]), &(x[0]), &(y[0]), &(lnn2gnn[0]), &(owner_range[0]), comm);
343 mesh =
new Mesh<real_t>(NNodes, NElements, &(ENList[0]), &(x[0]), &(y[0]), &(z[0]), &(lnn2gnn[0]), &(owner_range[0]), comm);
348 mesh =
new Mesh<real_t>(NNodes, NElements, &(ENList[0]), &(x[0]), &(y[0]));
350 mesh =
new Mesh<real_t>(NNodes, NElements, &(ENList[0]), &(x[0]), &(y[0]), &(z[0]));
362 for(
size_t i=0;i<NElements;i++){
379 vtkSmartPointer<vtkUnstructuredGrid> ug = vtkSmartPointer<vtkUnstructuredGrid>::New();
381 vtkSmartPointer<vtkPoints> vtk_points = vtkSmartPointer<vtkPoints>::New();
383 vtk_points->SetNumberOfPoints(NNodes);
385 vtkSmartPointer<vtkDoubleArray> vtk_psi = NULL;
388 vtk_psi = vtkSmartPointer<vtkDoubleArray>::New();
389 vtk_psi->SetNumberOfComponents(1);
390 vtk_psi->SetNumberOfTuples(NNodes);
391 vtk_psi->SetName(
"psi");
394 vtkSmartPointer<vtkIntArray> vtk_node_numbering = vtkSmartPointer<vtkIntArray>::New();
395 vtk_node_numbering->SetNumberOfComponents(1);
396 vtk_node_numbering->SetNumberOfTuples(NNodes);
397 vtk_node_numbering->SetName(
"nid");
399 vtkSmartPointer<vtkDoubleArray> vtk_metric = vtkSmartPointer<vtkDoubleArray>::New();
400 vtk_metric->SetNumberOfComponents(ndims*ndims);
401 vtk_metric->SetNumberOfTuples(NNodes);
402 vtk_metric->SetName(
"Metric");
404 vtkSmartPointer<vtkDoubleArray> vtk_edge_length = vtkSmartPointer<vtkDoubleArray>::New();
405 vtk_edge_length->SetNumberOfComponents(1);
406 vtk_edge_length->SetNumberOfTuples(NNodes);
407 vtk_edge_length->SetName(
"mean_edge_length");
409 vtkSmartPointer<vtkDoubleArray> vtk_max_desired_length = vtkSmartPointer<vtkDoubleArray>::New();
410 vtk_max_desired_length->SetNumberOfComponents(1);
411 vtk_max_desired_length->SetNumberOfTuples(NNodes);
412 vtk_max_desired_length->SetName(
"max_desired_edge_length");
414 vtkSmartPointer<vtkDoubleArray> vtk_min_desired_length = vtkSmartPointer<vtkDoubleArray>::New();
415 vtk_min_desired_length->SetNumberOfComponents(1);
416 vtk_min_desired_length->SetNumberOfTuples(NNodes);
417 vtk_min_desired_length->SetName(
"min_desired_edge_length");
419 #pragma omp parallel for
420 for(
size_t i=0;i<NNodes;i++){
425 vtk_psi->SetTuple1(i, psi[i]);
426 vtk_node_numbering->SetTuple1(i, i);
428 vtk_points->SetPoint(i, r[0], r[1], 0.0);
429 vtk_metric->SetTuple4(i,
433 vtk_points->SetPoint(i, r[0], r[1], r[2]);
434 vtk_metric->SetTuple9(i,
439 int nedges=mesh->NNList[i].size();
440 real_t mean_edge_length=0;
441 real_t max_desired_edge_length=0;
442 real_t min_desired_edge_length=DBL_MAX;
445 for(
typename std::vector<index_t>::const_iterator it=mesh->NNList[i].begin();it!=mesh->NNList[i].end();++it){
447 mean_edge_length += length;
451 max_desired_edge_length = std::max(max_desired_edge_length, M.
max_length());
452 min_desired_edge_length = std::min(min_desired_edge_length, M.
min_length());
455 for(
typename std::vector<index_t>::const_iterator it=mesh->NNList[i].begin();it!=mesh->NNList[i].end();++it){
457 mean_edge_length += length;
461 max_desired_edge_length = std::max(max_desired_edge_length, M.
max_length());
462 min_desired_edge_length = std::min(min_desired_edge_length, M.
min_length());
466 mean_edge_length/=nedges;
467 vtk_edge_length->SetTuple1(i, mean_edge_length);
468 vtk_max_desired_length->SetTuple1(i, max_desired_edge_length);
469 vtk_min_desired_length->SetTuple1(i, min_desired_edge_length);
472 ug->SetPoints(vtk_points);
474 ug->GetPointData()->AddArray(vtk_psi);
476 ug->GetPointData()->AddArray(vtk_node_numbering);
477 ug->GetPointData()->AddArray(vtk_metric);
478 ug->GetPointData()->AddArray(vtk_edge_length);
479 ug->GetPointData()->AddArray(vtk_max_desired_length);
480 ug->GetPointData()->AddArray(vtk_min_desired_length);
483 vtkSmartPointer<vtkIntArray> vtk_boundary_nodes = vtkSmartPointer<vtkIntArray>::New();
484 vtk_boundary_nodes->SetNumberOfComponents(1);
485 vtk_boundary_nodes->SetNumberOfTuples(NNodes);
486 vtk_boundary_nodes->SetName(
"BoundaryNodes");
487 for(
size_t i=0;i<NNodes;i++)
488 vtk_boundary_nodes->SetTuple1(i, -1);
490 for(
size_t i=0;i<NElements;i++){
496 for(
int j=0;j<3;j++){
497 if(mesh->boundary[i*3+j]>0){
498 vtk_boundary_nodes->SetTuple1(n[(j+1)%3], mesh->boundary[i*3+j]);
499 vtk_boundary_nodes->SetTuple1(n[(j+2)%3], mesh->boundary[i*3+j]);
503 for(
int j=0;j<4;j++){
504 if(mesh->boundary[i*4+j]>0){
505 vtk_boundary_nodes->SetTuple1(n[(j+1)%4], mesh->boundary[i*4+j]);
506 vtk_boundary_nodes->SetTuple1(n[(j+2)%4], mesh->boundary[i*4+j]);
507 vtk_boundary_nodes->SetTuple1(n[(j+3)%4], mesh->boundary[i*4+j]);
512 ug->GetPointData()->AddArray(vtk_boundary_nodes);
514 vtkSmartPointer<vtkIntArray> vtk_cell_numbering = vtkSmartPointer<vtkIntArray>::New();
515 vtk_cell_numbering->SetNumberOfComponents(1);
516 vtk_cell_numbering->SetNumberOfTuples(NElements);
517 vtk_cell_numbering->SetName(
"eid");
519 vtkSmartPointer<vtkIntArray> vtk_boundary = vtkSmartPointer<vtkIntArray>::New();
521 vtk_boundary->SetNumberOfComponents(3);
523 vtk_boundary->SetNumberOfComponents(4);
524 vtk_boundary->SetNumberOfTuples(NElements);
525 vtk_boundary->SetName(
"Boundary");
527 vtkSmartPointer<vtkDoubleArray> vtk_quality = vtkSmartPointer<vtkDoubleArray>::New();
528 vtk_quality->SetNumberOfComponents(1);
529 vtk_quality->SetNumberOfTuples(NElements);
530 vtk_quality->SetName(
"quality");
532 for(
size_t i=0, k=0;i<NElements;i++){
537 vtkIdType pts[] = {n[0], n[1], n[2]};
538 ug->InsertNextCell(VTK_TRIANGLE, 3, pts);
539 vtk_boundary->SetTuple3(i, mesh->boundary[i*3], mesh->boundary[i*3+1], mesh->boundary[i*3+2]);
544 vtkIdType pts[] = {n[0], n[1], n[2], n[3]};
545 ug->InsertNextCell(VTK_TETRA, 4, pts);
546 vtk_boundary->SetTuple4(i, mesh->boundary[i*4], mesh->boundary[i*4+1], mesh->boundary[i*4+2], mesh->boundary[i*4+3]);
552 vtk_cell_numbering->SetTuple1(k, i);
557 ug->GetCellData()->AddArray(vtk_cell_numbering);
558 ug->GetCellData()->AddArray(vtk_quality);
559 ug->GetCellData()->AddArray(vtk_boundary);
561 int rank=0, nparts=1;
563 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
564 MPI_Comm_size(MPI_COMM_WORLD, &nparts);
568 vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
569 std::string filename = std::string(basename)+std::string(
".vtu");
570 writer->SetFileName(filename.c_str());
571 #if VTK_MAJOR_VERSION < 6
572 writer->SetInput(ug);
574 writer->SetInputData(ug);
581 vtkSmartPointer<vtkUnsignedCharArray> vtk_ghost = vtkSmartPointer<vtkUnsignedCharArray>::New();
582 vtk_ghost->SetNumberOfComponents(1);
583 vtk_ghost->SetNumberOfTuples(NElements);
584 vtk_ghost->SetName(
"vtkGhostLevels");
586 for(
size_t i=0;i<NElements;i++){
590 owner=std::min(mesh->node_owner[n[0]], std::min(mesh->node_owner[n[1]], mesh->node_owner[n[2]]));
592 owner=std::min(std::min(mesh->node_owner[n[0]], mesh->node_owner[n[1]]), std::min(mesh->node_owner[n[2]], mesh->node_owner[n[3]]));
595 vtk_ghost->SetTuple1(i, 0);
597 vtk_ghost->SetTuple1(i, 1);
600 ug->GetCellData()->AddArray(vtk_ghost);
603 vtkSmartPointer<vtkIdTypeArray> vtk_gnn = vtkSmartPointer<vtkIdTypeArray>::New();
604 vtk_gnn->SetNumberOfComponents(1);
605 vtk_gnn->SetNumberOfTuples(NNodes);
606 vtk_gnn->SetName(
"GlobalId");
608 for(
size_t i=0;i<NNodes;i++){
609 vtk_gnn->SetTuple1(i, mesh->lnn2gnn[i]);
613 ug->GetPointData()->SetGlobalIds(vtk_gnn);
615 vtkSmartPointer<vtkXMLPUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New();
616 std::string filename = std::string(basename)+std::string(
".pvtu");
617 writer->SetFileName(filename.c_str());
618 writer->SetNumberOfPieces(nparts);
619 writer->SetGhostLevel(1);
620 writer->SetStartPiece(rank);
621 writer->SetEndPiece(rank);
622 #if VTK_MAJOR_VERSION < 6
623 writer->SetInput(ug);
625 writer->SetInputData(ug);
symmetric metric tensor class.
treal_t max_length() const
const real_t * get_coords(index_t nid) const
Return positions vector.
Calculates a number of element properties.
real_t calc_edge_length(index_t nid0, index_t nid1) const
Calculates the edge lengths in metric space.
size_t get_number_elements() const
Return the number of elements in the mesh.
const MPI_Datatype mpi_type
double min_length() const
const double * get_metric(index_t nid) const
Return metric at that vertex.
size_t get_number_dimensions() const
Return the number of spatial dimensions.
size_t get_number_nodes() const
Return the number of nodes in the mesh.
const index_t * get_element(size_t eid) const
Return a pointer to the element-node list.