Reference documentation for deal.II version 9.0.0
grid_in.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/path_search.h>
18 #include <deal.II/base/utilities.h>
19 #include <deal.II/base/exceptions.h>
20 
21 #include <deal.II/grid/grid_in.h>
22 #include <deal.II/grid/tria.h>
23 #include <deal.II/grid/grid_reordering.h>
24 #include <deal.II/grid/grid_tools.h>
25 
26 #include <boost/io/ios_state.hpp>
27 
28 #include <map>
29 #include <algorithm>
30 #include <fstream>
31 #include <functional>
32 #include <cctype>
33 
34 
35 #ifdef DEAL_II_WITH_NETCDF
36 #include <netcdfcpp.h>
37 #endif
38 
39 #ifdef DEAL_II_WITH_ASSIMP
40 #include <assimp/Importer.hpp> // C++ importer interface
41 #include <assimp/scene.h> // Output data structure
42 #include <assimp/postprocess.h> // Post processing flags
43 #endif
44 
45 
46 DEAL_II_NAMESPACE_OPEN
47 
48 
49 namespace
50 {
59  template <int spacedim>
60  void
61  assign_1d_boundary_ids (const std::map<unsigned int, types::boundary_id> &boundary_ids,
62  Triangulation<1,spacedim> &triangulation)
63  {
64  if (boundary_ids.size() > 0)
66  cell = triangulation.begin_active();
67  cell != triangulation.end(); ++cell)
68  for (unsigned int f=0; f<GeometryInfo<1>::faces_per_cell; ++f)
69  if (boundary_ids.find(cell->vertex_index(f)) != boundary_ids.end())
70  {
71  AssertThrow (cell->at_boundary(f),
72  ExcMessage ("You are trying to prescribe boundary ids on the face "
73  "of a 1d cell (i.e., on a vertex), but this face is not actually at "
74  "the boundary of the mesh. This is not allowed."));
75  cell->face(f)->set_boundary_id (boundary_ids.find(cell->vertex_index(f))->second);
76  }
77  }
78 
79 
80  template <int dim, int spacedim>
81  void
82  assign_1d_boundary_ids (const std::map<unsigned int, types::boundary_id> &,
84  {
85  // we shouldn't get here since boundary ids are not assigned to
86  // vertices except in 1d
87  Assert (dim != 1, ExcInternalError());
88  }
89 }
90 
91 template <int dim, int spacedim>
93  tria(nullptr, typeid(*this).name()), default_format(ucd)
94 {}
95 
96 
97 template <int dim, int spacedim>
99 {
100  tria = &t;
101 }
102 
103 
104 
105 template <int dim, int spacedim>
106 void GridIn<dim, spacedim>::read_vtk(std::istream &in)
107 {
108  Assert((dim == 2)||(dim == 3), ExcNotImplemented());
109  std::string line;
110 
111  // verify that the first, third and fourth lines match
112  // expectations. the second line of the file may essentially be
113  // anything the author of the file chose to identify what's in
114  // there, so we just ensure that we can read it
115  {
116  std::string text[4];
117  text[0] = "# vtk DataFile Version 3.0";
118  text[1] = "****";
119  text[2] = "ASCII";
120  text[3] = "DATASET UNSTRUCTURED_GRID";
121 
122  for (unsigned int i = 0; i < 4; ++i)
123  {
124  getline(in,line);
125  if (i != 1)
126  AssertThrow (line.compare(text[i]) == 0,
127  ExcMessage(std::string("While reading VTK file, failed to find a header line with text <") +
128  text[i] + ">"));
129  }
130  }
131 
133 
134  std::vector< Point<spacedim> > vertices;
135  std::vector< CellData<dim> > cells;
136  SubCellData subcelldata;
137 
138  std::string keyword;
139 
140  in >> keyword;
141 
143 
144  if (keyword == "POINTS")
145  {
146  unsigned int n_vertices;
147  in >> n_vertices;
148 
149  in.ignore(256, '\n');//ignoring the number beside the total no. of points.
150 
151  for (unsigned int vertex = 0; vertex < n_vertices; ++vertex)
152  {
153  // VTK format always specifies vertex coordinates with 3 components
154  Point<3> x;
155  in >> x(0) >> x(1) >> x(2);
156 
157  vertices.emplace_back();
158  for (unsigned int d=0; d<spacedim; ++d)
159  vertices.back()(d) = x(d);
160  }
161  }
162 
163  else
164  AssertThrow (false,
165  ExcMessage ("While reading VTK file, failed to find POINTS section"));
166 
167 
169  std::string checkline;
170  int no;
171  in.ignore(256, '\n');//this move pointer to the next line ignoring unwanted no.
172  no = in.tellg();
173  getline(in,checkline);
174  if (checkline.compare("") != 0)
175  {
176  in.seekg(no);
177  }
178 
179  in >> keyword;
180 
182 
183  if (keyword == "CELLS")
184  {
185  unsigned int n_geometric_objects;
186  in >> n_geometric_objects;
187  in.ignore(256,'\n');
188 
189  if (dim == 3)
190  {
191  for (unsigned int count = 0; count < n_geometric_objects; count++)
192  {
193  unsigned int type;
194  in >> type;
195 
196  if (type == 8)
197  {
198  // we assume that the file contains first all cells,
199  // and only then any faces or lines
200  AssertThrow (subcelldata.boundary_quads.size() == 0
201  &&
202  subcelldata.boundary_lines.size() == 0,
204 
205  cells.emplace_back();
206 
207  for (unsigned int j = 0; j < type; j++) //loop to feed data
208  in >> cells.back().vertices[j];
209 
210  cells.back().material_id = 0;
211  }
212 
213  else if ( type == 4)
214  {
215  subcelldata.boundary_quads.emplace_back();
216 
217  for (unsigned int j = 0; j < type; j++) //loop to feed the data to the boundary
218  in >> subcelldata.boundary_quads.back().vertices[j];
219 
220  subcelldata.boundary_quads.back().material_id = 0;
221  }
222 
223  else
224  AssertThrow (false,
225  ExcMessage ("While reading VTK file, unknown file type encountered"));
226  }
227  }
228 
229  else if (dim == 2)
230  {
231  for (unsigned int count = 0; count < n_geometric_objects; count++)
232  {
233  unsigned int type;
234  in >> type;
235 
236  if (type == 4)
237  {
238  // we assume that the file contains first all cells,
239  // and only then any faces
240  AssertThrow (subcelldata.boundary_lines.size() == 0,
242 
243  cells.emplace_back();
244 
245  for (unsigned int j = 0; j < type; j++) //loop to feed data
246  in >> cells.back().vertices[j];
247 
248  cells.back().material_id = 0;
249  }
250 
251  else if (type == 2)
252  {
253  //If this is encountered, the pointer comes out of the loop
254  //and starts processing boundaries.
255  subcelldata.boundary_lines.emplace_back();
256 
257  for (unsigned int j = 0; j < type; j++) //loop to feed the data to the boundary
258  {
259  in >> subcelldata.boundary_lines.back().vertices[j];
260  }
261 
262  subcelldata.boundary_lines.back().material_id = 0;
263  }
264 
265  else
266  AssertThrow (false,
267  ExcMessage ("While reading VTK file, unknown file type encountered"));
268  }
269  }
270  else
271  AssertThrow (false,
272  ExcMessage ("While reading VTK file, failed to find CELLS section"));
273 
275 
276  in >> keyword;
277 
278  if (keyword == "CELL_TYPES")//Entering the cell_types section and ignoring data.
279  {
280  in.ignore(256, '\n');
281 
282  while (!in.fail() && !in.eof())
283  {
284  in>>keyword;
285  if (keyword != "12" && keyword != "9")
286  {
287  break;
288  }
289  }
290  }
291 
293 
294  if (keyword == "CELL_DATA")
295  {
296  unsigned int n_ids;
297  in >> n_ids;
298 
299  AssertThrow (n_ids == cells.size() + (dim == 3 ?
300  subcelldata.boundary_quads.size() :
301  (dim == 2 ?
302  subcelldata.boundary_lines.size()
303  :
304  0)),
305  ExcMessage ("The VTK reader found a CELL_DATA statement "
306  "that lists a total of "
307  + Utilities::int_to_string (n_ids) +
308  " cell data objects, but this needs to "
309  "equal the number of cells (which is "
310  + Utilities::int_to_string (cells.size()) +
311  ") plus the number of quads ("
312  + Utilities::int_to_string (subcelldata.boundary_quads.size()) +
313  " in 3d or the number of lines ("
314  + Utilities::int_to_string (subcelldata.boundary_lines.size()) +
315  ") in 2d."));
316 
317 
318  std::string linenew;
319  std::string textnew[2];
320  textnew[0] = "SCALARS MaterialID double";
321  textnew[1] = "LOOKUP_TABLE default";
322 
323  in.ignore(256, '\n');
324 
325  for (unsigned int i = 0; i < 2; i++)
326  {
327  getline(in, linenew);
328  if (i == 0)
329  if (linenew.size() > textnew[0].size())
330  linenew.resize(textnew[0].size());
331 
332  AssertThrow (linenew.compare(textnew[i]) == 0,
333  ExcMessage (std::string("While reading VTK file, failed to find <") +
334  textnew[i] + "> section"));
335  }
336 
337  // read material ids first for all cells, then for all
338  // faces. the assumption that cells come before all faces
339  // has been verified above via an assertion, so the order
340  // used in the following blocks makes sense
341  for (unsigned int i = 0; i < cells.size(); i++)
342  {
343  double id;
344  in >> id;
345  cells[i].material_id = id;
346  }
347 
348  if (dim == 3)
349  {
350  for (unsigned int i = 0; i < subcelldata.boundary_quads.size(); i++)
351  {
352  double id;
353  in >> id;
354  subcelldata.boundary_quads[i].material_id = id;
355  }
356  }
357  else if (dim == 2)
358  {
359  for (unsigned int i = 0; i < subcelldata.boundary_lines.size(); i++)
360  {
361  double id;
362  in >> id;
363  subcelldata.boundary_lines[i].material_id = id;
364  }
365  }
366  }
367 
368  Assert(subcelldata.check_consistency(dim), ExcInternalError());
369 
371  cells,
372  subcelldata);
373 
374  if (dim == spacedim)
376  cells);
377 
379  tria->create_triangulation_compatibility(vertices,
380  cells,
381  subcelldata);
382 
383  return;
384  }
385  else
386  AssertThrow (false,
387  ExcMessage ("While reading VTK file, failed to find CELLS section"));
388 }
389 
390 
391 
392 template <int dim, int spacedim>
393 void GridIn<dim, spacedim>::read_unv(std::istream &in)
394 {
395  Assert(tria != nullptr, ExcNoTriangulationSelected());
396  Assert((dim == 2)||(dim == 3), ExcNotImplemented());
397 
398  AssertThrow(in, ExcIO());
399  skip_comment_lines(in, '#'); // skip comments (if any) at beginning of file
400 
401  int tmp;
402 
403  AssertThrow(in, ExcIO());
404  in >> tmp;
405  AssertThrow(in, ExcIO());
406  in >> tmp;
407 
408  // section 2411 describes vertices: see
409  // http://www.sdrl.uc.edu/sdrl/referenceinfo/universalfileformats/file-format-storehouse/universal-dataset-number-2411
410  AssertThrow(tmp == 2411, ExcUnknownSectionType(tmp));
411 
412  std::vector< Point<spacedim> > vertices; // vector of vertex coordinates
413  std::map<int, int> vertex_indices; // # vert in unv (key) ---> # vert in deal.II (value)
414 
415  int no_vertex = 0; // deal.II
416 
417  while (tmp != -1) // we do until reach end of 2411
418  {
419  int no; // unv
420  int dummy;
421  double x[3];
422 
423  AssertThrow(in, ExcIO());
424  in >> no;
425 
426  tmp = no;
427  if (tmp == -1)
428  break;
429 
430  in >> dummy >> dummy >> dummy;
431 
432  AssertThrow(in, ExcIO());
433  in >> x[0] >> x[1] >> x[2];
434 
435  vertices.emplace_back();
436 
437  for (unsigned int d = 0; d < spacedim; d++)
438  vertices.back()(d) = x[d];
439 
440  vertex_indices[no] = no_vertex;
441 
442  no_vertex++;
443  }
444 
445  AssertThrow(in, ExcIO());
446  in >> tmp;
447  AssertThrow(in, ExcIO());
448  in >> tmp;
449 
450  // section 2412 describes elements: see
451  // http://www.sdrl.uc.edu/sdrl/referenceinfo/universalfileformats/file-format-storehouse/universal-dataset-number-2412
452  AssertThrow(tmp == 2412, ExcUnknownSectionType(tmp));
453 
454  std::vector< CellData<dim> > cells; // vector of cells
455  SubCellData subcelldata;
456 
457  std::map<int, int> cell_indices; // # cell in unv (key) ---> # cell in deal.II (value)
458  std::map<int, int> line_indices; // # line in unv (key) ---> # line in deal.II (value)
459  std::map<int, int> quad_indices; // # quad in unv (key) ---> # quad in deal.II (value)
460 
461  int no_cell = 0; // deal.II
462  int no_line = 0; // deal.II
463  int no_quad = 0; // deal.II
464 
465  while (tmp != -1) // we do until reach end of 2412
466  {
467  int no; // unv
468  int type;
469  int dummy;
470 
471  AssertThrow(in, ExcIO());
472  in >> no;
473 
474  tmp = no;
475  if (tmp == -1)
476  break;
477 
478  in >> type >> dummy >> dummy >> dummy >> dummy;
479 
480  AssertThrow((type == 11)||(type == 44)||(type == 94)||(type == 115), ExcUnknownElementType(type));
481 
482  if ( (((type == 44)||(type == 94))&&(dim == 2)) || ((type == 115)&&(dim == 3)) ) // cell
483  {
484  cells.emplace_back();
485 
486  AssertThrow(in, ExcIO());
487  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
488  in >> cells.back().vertices[v];
489 
490  cells.back().material_id = 0;
491 
492  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
493  cells.back().vertices[v] = vertex_indices[cells.back().vertices[v]];
494 
495  cell_indices[no] = no_cell;
496 
497  no_cell++;
498  }
499  else if ( ((type == 11)&&(dim == 2)) || ((type == 11)&&(dim == 3)) ) // boundary line
500  {
501  AssertThrow(in, ExcIO());
502  in >> dummy >> dummy >> dummy;
503 
504  subcelldata.boundary_lines.emplace_back();
505 
506  AssertThrow(in, ExcIO());
507  for (unsigned int v = 0; v < 2; v++)
508  in >> subcelldata.boundary_lines.back().vertices[v];
509 
510  subcelldata.boundary_lines.back().material_id = 0;
511 
512  for (unsigned int v = 0; v < 2; v++)
513  subcelldata.boundary_lines.back().vertices[v] = vertex_indices[subcelldata.boundary_lines.back().vertices[v]];
514 
515  line_indices[no] = no_line;
516 
517  no_line++;
518  }
519  else if ( ((type == 44)||(type == 94)) && (dim == 3) ) // boundary quad
520  {
521  subcelldata.boundary_quads.emplace_back();
522 
523  AssertThrow(in, ExcIO());
524  for (unsigned int v = 0; v < 4; v++)
525  in >> subcelldata.boundary_quads.back().vertices[v];
526 
527  subcelldata.boundary_quads.back().material_id = 0;
528 
529  for (unsigned int v = 0; v < 4; v++)
530  subcelldata.boundary_quads.back().vertices[v] = vertex_indices[subcelldata.boundary_quads.back().vertices[v]];
531 
532  quad_indices[no] = no_quad;
533 
534  no_quad++;
535  }
536  else
537  AssertThrow (false,
538  ExcMessage ("Unknown element label <"
540  + "> when running in dim="
541  + Utilities::int_to_string(dim)));
542  }
543 
544 // note that so far all materials and bcs are explicitly set to 0
545 // if we do not need more info on materials and bcs - this is end of file
546 // if we do - section 2467 or 2477 comes
547 
548  in >> tmp; // tmp can be either -1 or end-of-file
549 
550  if ( !in.eof() )
551  {
552  AssertThrow(in, ExcIO());
553  in >> tmp;
554 
555  // section 2467 (2477) describes (materials - first and bcs - second) or
556  // (bcs - first and materials - second) - sequence depends on which
557  // group is created first: see
558  // http://www.sdrl.uc.edu/sdrl/referenceinfo/universalfileformats/file-format-storehouse/universal-dataset-number-2467
559  AssertThrow((tmp == 2467)||(tmp == 2477), ExcUnknownSectionType(tmp));
560 
561  while (tmp != -1) // we do until reach end of 2467 or 2477
562  {
563  int n_entities; // number of entities in group
564  int id; // id is either material or bc
565  int no; // unv
566  int dummy;
567 
568  AssertThrow(in, ExcIO());
569  in >> dummy;
570 
571  tmp = dummy;
572  if (tmp == -1)
573  break;
574 
575  in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> n_entities;
576 
577  AssertThrow(in, ExcIO());
578  in >> id;
579 
580  const unsigned int n_lines = (n_entities%2 == 0)?(n_entities/2):((n_entities+1)/2);
581 
582  for (unsigned int line = 0; line < n_lines; line++)
583  {
584  unsigned int n_fragments;
585 
586  if (line == n_lines-1)
587  n_fragments = (n_entities%2 == 0)?(2):(1);
588  else
589  n_fragments = 2;
590 
591  for (unsigned int no_fragment = 0; no_fragment < n_fragments; no_fragment++)
592  {
593  AssertThrow(in, ExcIO());
594  in >> dummy >> no >> dummy >> dummy;
595 
596  if ( cell_indices.count(no) > 0 ) // cell - material
597  cells[cell_indices[no]].material_id = id;
598 
599  if ( line_indices.count(no) > 0 ) // boundary line - bc
600  subcelldata.boundary_lines[line_indices[no]].material_id = id;
601 
602  if ( quad_indices.count(no) > 0 ) // boundary quad - bc
603  subcelldata.boundary_quads[quad_indices[no]].material_id = id;
604  }
605  }
606  }
607  }
608 
609  Assert(subcelldata.check_consistency(dim), ExcInternalError());
610 
612  cells,
613  subcelldata);
614 
615  if (dim == spacedim)
617  cells);
618 
620 
621  tria->create_triangulation_compatibility(vertices,
622  cells,
623  subcelldata);
624 }
625 
626 
627 
628 template <int dim, int spacedim>
629 void GridIn<dim, spacedim>::read_ucd (std::istream &in,
630  const bool apply_all_indicators_to_manifolds)
631 {
632  Assert (tria != nullptr, ExcNoTriangulationSelected());
633  AssertThrow (in, ExcIO());
634 
635  // skip comments at start of file
636  skip_comment_lines (in, '#');
637 
638 
639  unsigned int n_vertices;
640  unsigned int n_cells;
641  int dummy;
642 
643  in >> n_vertices
644  >> n_cells
645  >> dummy // number of data vectors
646  >> dummy // cell data
647  >> dummy; // model data
648  AssertThrow (in, ExcIO());
649 
650  // set up array of vertices
651  std::vector<Point<spacedim> > vertices (n_vertices);
652  // set up mapping between numbering
653  // in ucd-file (key) and in the
654  // vertices vector
655  std::map<int,int> vertex_indices;
656 
657  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
658  {
659  int vertex_number;
660  double x[3];
661 
662  // read vertex
663  AssertThrow (in, ExcIO());
664  in >> vertex_number
665  >> x[0] >> x[1] >> x[2];
666 
667  // store vertex
668  for (unsigned int d=0; d<spacedim; ++d)
669  vertices[vertex](d) = x[d];
670  // store mapping; note that
671  // vertices_indices[i] is automatically
672  // created upon first usage
673  vertex_indices[vertex_number] = vertex;
674  };
675 
676  // set up array of cells
677  std::vector<CellData<dim> > cells;
678  SubCellData subcelldata;
679 
680  for (unsigned int cell=0; cell<n_cells; ++cell)
681  {
682  // note that since in the input
683  // file we found the number of
684  // cells at the top, there
685  // should still be input here,
686  // so check this:
687  AssertThrow (in, ExcIO());
688 
689  std::string cell_type;
690 
691  // we use an unsigned int because we
692  // fill this variable through an read-in process
693  unsigned int material_id;
694 
695  in >> dummy // cell number
696  >> material_id;
697  in >> cell_type;
698 
699  if (((cell_type == "line") && (dim == 1)) ||
700  ((cell_type == "quad") && (dim == 2)) ||
701  ((cell_type == "hex" ) && (dim == 3)))
702  // found a cell
703  {
704  // allocate and read indices
705  cells.emplace_back ();
706  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
707  in >> cells.back().vertices[i];
708 
709  // to make sure that the cast won't fail
710  Assert(material_id<= std::numeric_limits<types::material_id>::max(),
711  ExcIndexRange(material_id,0,std::numeric_limits<types::material_id>::max()));
712  // we use only material_ids in the range from 0 to numbers::invalid_material_id-1
713  Assert(material_id < numbers::invalid_material_id,
715 
716  cells.back().material_id = static_cast<types::material_id>(material_id);
717 
718  // transform from ucd to
719  // consecutive numbering
720  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
721  if (vertex_indices.find (cells.back().vertices[i]) != vertex_indices.end())
722  // vertex with this index exists
723  cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
724  else
725  {
726  // no such vertex index
727  AssertThrow (false,
728  ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
729 
730  cells.back().vertices[i] = numbers::invalid_unsigned_int;
731  }
732  }
733  else if ((cell_type == "line") && ((dim == 2) || (dim == 3)))
734  // boundary info
735  {
736  subcelldata.boundary_lines.emplace_back ();
737  in >> subcelldata.boundary_lines.back().vertices[0]
738  >> subcelldata.boundary_lines.back().vertices[1];
739 
740  // to make sure that the cast won't fail
741  Assert(material_id<= std::numeric_limits<types::boundary_id>::max(),
742  ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id>::max()));
743  // we use only boundary_ids in the range from 0 to numbers::internal_face_boundary_id-1
746 
747  if (apply_all_indicators_to_manifolds)
748  subcelldata.boundary_lines.back().manifold_id
749  = static_cast<types::manifold_id>(material_id);
750  else
751  subcelldata.boundary_lines.back().boundary_id
752  = static_cast<types::boundary_id>(material_id);
753 
754  // transform from ucd to
755  // consecutive numbering
756  for (unsigned int i=0; i<2; ++i)
757  if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
758  vertex_indices.end())
759  // vertex with this index exists
760  subcelldata.boundary_lines.back().vertices[i]
761  = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
762  else
763  {
764  // no such vertex index
765  AssertThrow (false,
767  subcelldata.boundary_lines.back().vertices[i]));
768  subcelldata.boundary_lines.back().vertices[i]
770  };
771  }
772  else if ((cell_type == "quad") && (dim == 3))
773  // boundary info
774  {
775  subcelldata.boundary_quads.emplace_back ();
776  in >> subcelldata.boundary_quads.back().vertices[0]
777  >> subcelldata.boundary_quads.back().vertices[1]
778  >> subcelldata.boundary_quads.back().vertices[2]
779  >> subcelldata.boundary_quads.back().vertices[3];
780 
781  // to make sure that the cast won't fail
782  Assert(material_id<= std::numeric_limits<types::boundary_id>::max(),
783  ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id>::max()));
784  // we use only boundary_ids in the range from 0 to numbers::internal_face_boundary_id-1
787 
788  if (apply_all_indicators_to_manifolds)
789  subcelldata.boundary_quads.back().manifold_id
790  = static_cast<types::manifold_id>(material_id);
791  else
792  subcelldata.boundary_quads.back().boundary_id
793  = static_cast<types::boundary_id>(material_id);
794 
795  // transform from ucd to
796  // consecutive numbering
797  for (unsigned int i=0; i<4; ++i)
798  if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
799  vertex_indices.end())
800  // vertex with this index exists
801  subcelldata.boundary_quads.back().vertices[i]
802  = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
803  else
804  {
805  // no such vertex index
806  Assert (false,
808  subcelldata.boundary_quads.back().vertices[i]));
809  subcelldata.boundary_quads.back().vertices[i] =
811  };
812 
813  }
814  else
815  // cannot read this
816  AssertThrow (false, ExcUnknownIdentifier(cell_type));
817  };
818 
819 
820  // check that no forbidden arrays are used
821  Assert (subcelldata.check_consistency(dim), ExcInternalError());
822 
823  AssertThrow (in, ExcIO());
824 
825  // do some clean-up on vertices...
826  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
827  // ... and cells
828  if (dim==spacedim)
831  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
832 }
833 
834 namespace
835 {
836  template <int dim>
837  class Abaqus_to_UCD
838  {
839  public:
840  Abaqus_to_UCD ();
841 
842  void read_in_abaqus (std::istream &in);
843  void write_out_avs_ucd (std::ostream &out) const;
844 
845  private:
846  const double tolerance;
847 
848  std::vector<double> get_global_node_numbers (const int face_cell_no,
849  const int face_cell_face_no) const;
850 
851  // NL: Stored as [ global node-id (int), x-coord, y-coord, z-coord ]
852  std::vector< std::vector<double> > node_list;
853  // CL: Stored as [ material-id (int), node1, node2, node3, node4, node5, node6, node7, node8 ]
854  std::vector< std::vector<double> > cell_list;
855  // FL: Stored as [ sideset-id (int), node1, node2, node3, node4 ]
856  std::vector< std::vector<double> > face_list;
857  // ELSET: Stored as [ (std::string) elset_name = (std::vector) of cells numbers]
858  std::map< std::string, std::vector<int> > elsets_list;
859  };
860 }
861 
862 template <int dim, int spacedim>
863 void GridIn<dim, spacedim>::read_abaqus (std::istream &in,
864  const bool apply_all_indicators_to_manifolds)
865 {
866  Assert (tria != nullptr, ExcNoTriangulationSelected());
867  Assert (dim==2 || dim==3, ExcNotImplemented());
868  AssertThrow (in, ExcIO());
869 
870  // Read in the Abaqus file into an intermediate object
871  // that is to be passed along to the UCD reader
872  Abaqus_to_UCD<dim> abaqus_to_ucd;
873  abaqus_to_ucd.read_in_abaqus(in);
874 
875  std::stringstream in_ucd;
876  abaqus_to_ucd.write_out_avs_ucd(in_ucd);
877 
878  // This next call is wrapped in a try-catch for the following reason:
879  // It ensures that if the Abaqus mesh is read in correctly but produces
880  // an erroneous result then the user is alerted to the source of the problem
881  // and doesn't think that they've somehow called the wrong function.
882  try
883  {
884  read_ucd(in_ucd, apply_all_indicators_to_manifolds);
885  }
886  catch (std::exception &exc)
887  {
888  std::cerr
889  << "Exception on processing internal UCD data: " << std::endl
890  << exc.what()
891  << std::endl;
892 
893  AssertThrow(false, ExcMessage("Internal conversion from ABAQUS file to UCD format was unsuccessful. "
894  "More information is provided in an error message printed above. "
895  "Are you sure that your ABAQUS mesh file conforms with the requirements "
896  "listed in the documentation?"));
897  }
898  catch (...)
899  {
900  AssertThrow(false, ExcMessage("Internal conversion from ABAQUS file to UCD format was unsuccessful. "
901  "Are you sure that your ABAQUS mesh file conforms with the requirements "
902  "listed in the documentation?"));
903  }
904 }
905 
906 
907 template <int dim, int spacedim>
908 void GridIn<dim, spacedim>::read_dbmesh (std::istream &in)
909 {
910  Assert (tria != nullptr, ExcNoTriangulationSelected());
911  Assert (dim==2, ExcNotImplemented());
912 
913  AssertThrow (in, ExcIO());
914 
915  // skip comments at start of file
916  skip_comment_lines (in, '#');
917 
918  // first read in identifier string
919  std::string line;
920  getline (in, line);
921 
922  AssertThrow (line=="MeshVersionFormatted 0",
923  ExcInvalidDBMESHInput(line));
924 
925  skip_empty_lines (in);
926 
927  // next read dimension
928  getline (in, line);
929  AssertThrow (line=="Dimension", ExcInvalidDBMESHInput(line));
930  unsigned int dimension;
931  in >> dimension;
932  AssertThrow (dimension == dim, ExcDBMESHWrongDimension(dimension));
933  skip_empty_lines (in);
934 
935  // now there are a lot of fields of
936  // which we don't know the exact
937  // meaning and which are far from
938  // being properly documented in the
939  // manual. we skip everything until
940  // we find a comment line with the
941  // string "# END". at some point in
942  // the future, someone may have the
943  // knowledge to parse and interpret
944  // the other fields in between as
945  // well...
946  while (getline(in,line), line.find("# END")==std::string::npos)
947  ;
948  skip_empty_lines (in);
949 
950 
951  // now read vertices
952  getline (in, line);
953  AssertThrow (line=="Vertices", ExcInvalidDBMESHInput(line));
954 
955  unsigned int n_vertices;
956  double dummy;
957 
958  in >> n_vertices;
959  std::vector<Point<spacedim> > vertices (n_vertices);
960  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
961  {
962  // read vertex coordinates
963  for (unsigned int d=0; d<dim; ++d)
964  in >> vertices[vertex][d];
965  // read Ref phi_i, whatever that may be
966  in >> dummy;
967  };
968  AssertThrow (in, ExcInvalidDBMeshFormat());
969 
970  skip_empty_lines(in);
971 
972  // read edges. we ignore them at
973  // present, so just read them and
974  // discard the input
975  getline (in, line);
976  AssertThrow (line=="Edges", ExcInvalidDBMESHInput(line));
977 
978  unsigned int n_edges;
979  in >> n_edges;
980  for (unsigned int edge=0; edge<n_edges; ++edge)
981  {
982  // read vertex indices
983  in >> dummy >> dummy;
984  // read Ref phi_i, whatever that may be
985  in >> dummy;
986  };
987  AssertThrow (in, ExcInvalidDBMeshFormat());
988 
989  skip_empty_lines(in);
990 
991 
992 
993  // read cracked edges (whatever
994  // that may be). we ignore them at
995  // present, so just read them and
996  // discard the input
997  getline (in, line);
998  AssertThrow (line=="CrackedEdges", ExcInvalidDBMESHInput(line));
999 
1000  in >> n_edges;
1001  for (unsigned int edge=0; edge<n_edges; ++edge)
1002  {
1003  // read vertex indices
1004  in >> dummy >> dummy;
1005  // read Ref phi_i, whatever that may be
1006  in >> dummy;
1007  };
1008  AssertThrow (in, ExcInvalidDBMeshFormat());
1009 
1010  skip_empty_lines(in);
1011 
1012 
1013  // now read cells.
1014  // set up array of cells
1015  getline (in, line);
1016  AssertThrow (line=="Quadrilaterals", ExcInvalidDBMESHInput(line));
1017 
1018  std::vector<CellData<dim> > cells;
1019  SubCellData subcelldata;
1020  unsigned int n_cells;
1021  in >> n_cells;
1022  for (unsigned int cell=0; cell<n_cells; ++cell)
1023  {
1024  // read in vertex numbers. they
1025  // are 1-based, so subtract one
1026  cells.emplace_back ();
1027  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
1028  {
1029  in >> cells.back().vertices[i];
1030 
1031  AssertThrow ((cells.back().vertices[i] >= 1)
1032  &&
1033  (static_cast<unsigned int>(cells.back().vertices[i]) <= vertices.size()),
1034  ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
1035 
1036  --cells.back().vertices[i];
1037  };
1038 
1039  // read and discard Ref phi_i
1040  in >> dummy;
1041  };
1042  AssertThrow (in, ExcInvalidDBMeshFormat());
1043 
1044  skip_empty_lines(in);
1045 
1046 
1047  // then there are again a whole lot
1048  // of fields of which I have no
1049  // clue what they mean. skip them
1050  // all and leave the interpretation
1051  // to other implementors...
1052  while (getline(in,line), ((line.find("End")==std::string::npos) && (in)))
1053  ;
1054  // ok, so we are not at the end of
1055  // the file, that's it, mostly
1056 
1057 
1058  // check that no forbidden arrays are used
1059  Assert (subcelldata.check_consistency(dim), ExcInternalError());
1060 
1061  AssertThrow (in, ExcIO());
1062 
1063  // do some clean-up on vertices...
1064  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
1065  // ...and cells
1068  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
1069 }
1070 
1071 
1072 
1073 template <int dim, int spacedim>
1074 void GridIn<dim, spacedim>::read_xda (std::istream &)
1075 {
1076  Assert (false, ExcNotImplemented());
1077 }
1078 
1079 
1080 
1081 template <>
1082 void GridIn<2>::read_xda (std::istream &in)
1083 {
1084  Assert (tria != nullptr, ExcNoTriangulationSelected());
1085  AssertThrow (in, ExcIO());
1086 
1087  std::string line;
1088  // skip comments at start of file
1089  getline (in, line);
1090 
1091 
1092  unsigned int n_vertices;
1093  unsigned int n_cells;
1094 
1095  // read cells, throw away rest of line
1096  in >> n_cells;
1097  getline (in, line);
1098 
1099  in >> n_vertices;
1100  getline (in, line);
1101 
1102  // ignore following 8 lines
1103  for (unsigned int i=0; i<8; ++i)
1104  getline (in, line);
1105 
1106  // set up array of cells
1107  std::vector<CellData<2> > cells (n_cells);
1108  SubCellData subcelldata;
1109 
1110  for (unsigned int cell=0; cell<n_cells; ++cell)
1111  {
1112  // note that since in the input
1113  // file we found the number of
1114  // cells at the top, there
1115  // should still be input here,
1116  // so check this:
1117  AssertThrow (in, ExcIO());
1119  ExcInternalError());
1120 
1121  for (unsigned int i=0; i<4; ++i)
1122  in >> cells[cell].vertices[i];
1123  };
1124 
1125 
1126 
1127  // set up array of vertices
1128  std::vector<Point<2> > vertices (n_vertices);
1129  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
1130  {
1131  double x[3];
1132 
1133  // read vertex
1134  in >> x[0] >> x[1] >> x[2];
1135 
1136  // store vertex
1137  for (unsigned int d=0; d<2; ++d)
1138  vertices[vertex](d) = x[d];
1139  };
1140  AssertThrow (in, ExcIO());
1141 
1142  // do some clean-up on vertices...
1143  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
1144  // ... and cells
1147  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
1148 }
1149 
1150 
1151 
1152 template <>
1153 void GridIn<3>::read_xda (std::istream &in)
1154 {
1155  Assert (tria != nullptr, ExcNoTriangulationSelected());
1156  AssertThrow (in, ExcIO());
1157 
1158  static const unsigned int xda_to_dealII_map[] = {0,1,5,4,3,2,6,7};
1159 
1160  std::string line;
1161  // skip comments at start of file
1162  getline (in, line);
1163 
1164 
1165  unsigned int n_vertices;
1166  unsigned int n_cells;
1167 
1168  // read cells, throw away rest of line
1169  in >> n_cells;
1170  getline (in, line);
1171 
1172  in >> n_vertices;
1173  getline (in, line);
1174 
1175  // ignore following 8 lines
1176  for (unsigned int i=0; i<8; ++i)
1177  getline (in, line);
1178 
1179  // set up array of cells
1180  std::vector<CellData<3> > cells (n_cells);
1181  SubCellData subcelldata;
1182 
1183  for (unsigned int cell=0; cell<n_cells; ++cell)
1184  {
1185  // note that since in the input
1186  // file we found the number of
1187  // cells at the top, there
1188  // should still be input here,
1189  // so check this:
1190  AssertThrow (in, ExcIO());
1192  ExcInternalError());
1193 
1194  unsigned int xda_ordered_nodes[8];
1195 
1196  for (unsigned int i=0; i<8; ++i)
1197  in >> xda_ordered_nodes[i];
1198 
1199  for (unsigned int i=0; i<8; i++)
1200  cells[cell].vertices[i] = xda_ordered_nodes[xda_to_dealII_map[i]];
1201  };
1202 
1203 
1204 
1205  // set up array of vertices
1206  std::vector<Point<3> > vertices (n_vertices);
1207  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
1208  {
1209  double x[3];
1210 
1211  // read vertex
1212  in >> x[0] >> x[1] >> x[2];
1213 
1214  // store vertex
1215  for (unsigned int d=0; d<3; ++d)
1216  vertices[vertex](d) = x[d];
1217  };
1218  AssertThrow (in, ExcIO());
1219 
1220  // do some clean-up on vertices...
1221  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
1222  // ... and cells
1225  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
1226 }
1227 
1228 
1229 
1230 
1231 template <int dim, int spacedim>
1232 void GridIn<dim, spacedim>::read_msh (std::istream &in)
1233 {
1234  Assert (tria != nullptr, ExcNoTriangulationSelected());
1235  AssertThrow (in, ExcIO());
1236 
1237  unsigned int n_vertices;
1238  unsigned int n_cells;
1239  unsigned int dummy;
1240  std::string line;
1241 
1242  in >> line;
1243 
1244  // first determine file format
1245  unsigned int gmsh_file_format = 0;
1246  if (line == "@f$NOD")
1247  gmsh_file_format = 1;
1248  else if (line == "@f$MeshFormat")
1249  gmsh_file_format = 2;
1250  else
1251  AssertThrow (false, ExcInvalidGMSHInput(line));
1252 
1253  // if file format is 2 or greater
1254  // then we also have to read the
1255  // rest of the header
1256  if (gmsh_file_format == 2)
1257  {
1258  double version;
1259  unsigned int file_type, data_size;
1260 
1261  in >> version >> file_type >> data_size;
1262 
1263  Assert ( (version >= 2.0) &&
1264  (version <= 2.2), ExcNotImplemented());
1265  Assert (file_type == 0, ExcNotImplemented());
1266  Assert (data_size == sizeof(double), ExcNotImplemented());
1267 
1268  // read the end of the header
1269  // and the first line of the
1270  // nodes description to synch
1271  // ourselves with the format 1
1272  // handling above
1273  in >> line;
1274  AssertThrow (line == "@f$EndMeshFormat",
1275  ExcInvalidGMSHInput(line));
1276 
1277  in >> line;
1278  // if the next block is of kind
1279  // @f$PhysicalNames, ignore it
1280  if (line == "@f$PhysicalNames")
1281  {
1282  do
1283  {
1284  in >> line;
1285  }
1286  while (line != "@f$EndPhysicalNames");
1287  in >> line;
1288  }
1289 
1290  // but the next thing should,
1291  // in any case, be the list of
1292  // nodes:
1293  AssertThrow (line == "@f$Nodes",
1294  ExcInvalidGMSHInput(line));
1295  }
1296 
1297  // now read the nodes list
1298  in >> n_vertices;
1299  std::vector<Point<spacedim> > vertices (n_vertices);
1300  // set up mapping between numbering
1301  // in msh-file (nod) and in the
1302  // vertices vector
1303  std::map<int,int> vertex_indices;
1304 
1305  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
1306  {
1307  int vertex_number;
1308  double x[3];
1309 
1310  // read vertex
1311  in >> vertex_number
1312  >> x[0] >> x[1] >> x[2];
1313 
1314  for (unsigned int d=0; d<spacedim; ++d)
1315  vertices[vertex](d) = x[d];
1316  // store mapping
1317  vertex_indices[vertex_number] = vertex;
1318  }
1319 
1320  // Assert we reached the end of the block
1321  in >> line;
1322  static const std::string end_nodes_marker[] = {"@f$ENDNOD", "@f$EndNodes" };
1323  AssertThrow (line==end_nodes_marker[gmsh_file_format-1],
1324  ExcInvalidGMSHInput(line));
1325 
1326  // Now read in next bit
1327  in >> line;
1328  static const std::string begin_elements_marker[] = {"@f$ELM", "@f$Elements" };
1329  AssertThrow (line==begin_elements_marker[gmsh_file_format-1],
1330  ExcInvalidGMSHInput(line));
1331 
1332  in >> n_cells;
1333 
1334  // set up array of cells and subcells (faces). In 1d, there is currently no
1335  // standard way in deal.II to pass boundary indicators attached to individual
1336  // vertices, so do this by hand via the boundary_ids_1d array
1337  std::vector<CellData<dim> > cells;
1338  SubCellData subcelldata;
1339  std::map<unsigned int, types::boundary_id> boundary_ids_1d;
1340 
1341  for (unsigned int cell=0; cell<n_cells; ++cell)
1342  {
1343  // note that since in the input
1344  // file we found the number of
1345  // cells at the top, there
1346  // should still be input here,
1347  // so check this:
1348  AssertThrow (in, ExcIO());
1349 
1350  unsigned int cell_type;
1351  unsigned int material_id;
1352  unsigned int nod_num;
1353 
1354  /*
1355  For file format version 1, the format of each cell is as follows:
1356  elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
1357 
1358  However, for version 2, the format reads like this:
1359  elm-number elm-type number-of-tags < tag > ... node-number-list
1360 
1361  In the following, we will ignore the element number (we simply enumerate
1362  them in the order in which we read them, and we will take reg-phys
1363  (version 1) or the first tag (version 2, if any tag is given at all) as
1364  material id.
1365  */
1366 
1367  unsigned int elm_number;
1368  in >> elm_number // ELM-NUMBER
1369  >> cell_type; // ELM-TYPE
1370 
1371  switch (gmsh_file_format)
1372  {
1373  case 1:
1374  {
1375  in >> material_id // REG-PHYS
1376  >> dummy // reg_elm
1377  >> nod_num;
1378  break;
1379  }
1380 
1381  case 2:
1382  {
1383  // read the tags; ignore all but the first one which we will
1384  // interpret as the material_id (for cells) or boundary_id
1385  // (for faces)
1386  unsigned int n_tags;
1387  in >> n_tags;
1388  if (n_tags > 0)
1389  in >> material_id;
1390  else
1391  material_id = 0;
1392 
1393  for (unsigned int i=1; i<n_tags; ++i)
1394  in >> dummy;
1395 
1397 
1398  break;
1399  }
1400 
1401  default:
1402  AssertThrow (false, ExcNotImplemented());
1403  }
1404 
1405 
1406  /* `ELM-TYPE'
1407  defines the geometrical type of the N-th element:
1408  `1'
1409  Line (2 nodes, 1 edge).
1410 
1411  `3'
1412  Quadrangle (4 nodes, 4 edges).
1413 
1414  `5'
1415  Hexahedron (8 nodes, 12 edges, 6 faces).
1416 
1417  `15'
1418  Point (1 node).
1419  */
1420 
1421  if (((cell_type == 1) && (dim == 1)) ||
1422  ((cell_type == 3) && (dim == 2)) ||
1423  ((cell_type == 5) && (dim == 3)))
1424  // found a cell
1425  {
1427  ExcMessage ("Number of nodes does not coincide with the "
1428  "number required for this object"));
1429 
1430  // allocate and read indices
1431  cells.emplace_back ();
1432  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
1433  in >> cells.back().vertices[i];
1434 
1435  // to make sure that the cast won't fail
1436  Assert(material_id<= std::numeric_limits<types::material_id>::max(),
1437  ExcIndexRange(material_id,0,std::numeric_limits<types::material_id>::max()));
1438  // we use only material_ids in the range from 0 to numbers::invalid_material_id-1
1439  Assert(material_id < numbers::invalid_material_id,
1441 
1442  cells.back().material_id = static_cast<types::material_id>(material_id);
1443 
1444  // transform from ucd to
1445  // consecutive numbering
1446  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
1447  {
1448  AssertThrow (vertex_indices.find (cells.back().vertices[i]) !=
1449  vertex_indices.end(),
1450  ExcInvalidVertexIndexGmsh(cell, elm_number,
1451  cells.back().vertices[i]));
1452 
1453  // vertex with this index exists
1454  cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
1455  }
1456  }
1457  else if ((cell_type == 1) && ((dim == 2) || (dim == 3)))
1458  // boundary info
1459  {
1460  subcelldata.boundary_lines.emplace_back ();
1461  in >> subcelldata.boundary_lines.back().vertices[0]
1462  >> subcelldata.boundary_lines.back().vertices[1];
1463 
1464  // to make sure that the cast won't fail
1465  Assert(material_id<= std::numeric_limits<types::boundary_id>::max(),
1466  ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id>::max()));
1467  // we use only boundary_ids in the range from 0 to numbers::internal_face_boundary_id-1
1470 
1471  subcelldata.boundary_lines.back().boundary_id
1472  = static_cast<types::boundary_id>(material_id);
1473 
1474  // transform from ucd to
1475  // consecutive numbering
1476  for (unsigned int i=0; i<2; ++i)
1477  if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
1478  vertex_indices.end())
1479  // vertex with this index exists
1480  subcelldata.boundary_lines.back().vertices[i]
1481  = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
1482  else
1483  {
1484  // no such vertex index
1485  AssertThrow (false,
1486  ExcInvalidVertexIndex(cell,
1487  subcelldata.boundary_lines.back().vertices[i]));
1488  subcelldata.boundary_lines.back().vertices[i] =
1490  };
1491  }
1492  else if ((cell_type == 3) && (dim == 3))
1493  // boundary info
1494  {
1495  subcelldata.boundary_quads.emplace_back ();
1496  in >> subcelldata.boundary_quads.back().vertices[0]
1497  >> subcelldata.boundary_quads.back().vertices[1]
1498  >> subcelldata.boundary_quads.back().vertices[2]
1499  >> subcelldata.boundary_quads.back().vertices[3];
1500 
1501  // to make sure that the cast won't fail
1502  Assert(material_id<= std::numeric_limits<types::boundary_id>::max(),
1503  ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id>::max()));
1504  // we use only boundary_ids in the range from 0 to numbers::internal_face_boundary_id-1
1507 
1508  subcelldata.boundary_quads.back().boundary_id
1509  = static_cast<types::boundary_id>(material_id);
1510 
1511  // transform from gmsh to
1512  // consecutive numbering
1513  for (unsigned int i=0; i<4; ++i)
1514  if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
1515  vertex_indices.end())
1516  // vertex with this index exists
1517  subcelldata.boundary_quads.back().vertices[i]
1518  = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
1519  else
1520  {
1521  // no such vertex index
1522  Assert (false,
1523  ExcInvalidVertexIndex(cell,
1524  subcelldata.boundary_quads.back().vertices[i]));
1525  subcelldata.boundary_quads.back().vertices[i] =
1527  }
1528 
1529  }
1530  else if (cell_type == 15)
1531  {
1532  // read the indices of nodes given
1533  unsigned int node_index = 0;
1534  switch (gmsh_file_format)
1535  {
1536  case 1:
1537  {
1538  for (unsigned int i=0; i<nod_num; ++i)
1539  in >> node_index;
1540  break;
1541  }
1542  case 2:
1543  {
1544  in >> node_index;
1545  break;
1546  }
1547  default:
1548  Assert(false, ExcInternalError());
1549  }
1550 
1551  // we only care about boundary indicators assigned to individual
1552  // vertices in 1d (because otherwise the vertices are not faces)
1553  if (dim == 1)
1554  boundary_ids_1d[vertex_indices[node_index]] = material_id;
1555  }
1556  else
1557  // cannot read this, so throw
1558  // an exception. treat
1559  // triangles and tetrahedra
1560  // specially since this
1561  // deserves a more explicit
1562  // error message
1563  {
1564  AssertThrow (cell_type != 2,
1565  ExcMessage("Found triangles while reading a file "
1566  "in gmsh format. deal.II does not "
1567  "support triangles"));
1568  AssertThrow (cell_type != 11,
1569  ExcMessage("Found tetrahedra while reading a file "
1570  "in gmsh format. deal.II does not "
1571  "support tetrahedra"));
1572 
1573  AssertThrow (false, ExcGmshUnsupportedGeometry(cell_type));
1574  }
1575  }
1576 
1577  // Assert we reached the end of the block
1578  in >> line;
1579  static const std::string end_elements_marker[] = {"@f$ENDELM", "@f$EndElements" };
1580  AssertThrow (line==end_elements_marker[gmsh_file_format-1],
1581  ExcInvalidGMSHInput(line));
1582 
1583  // check that no forbidden arrays are used
1584  Assert (subcelldata.check_consistency(dim), ExcInternalError());
1585 
1586  AssertThrow (in, ExcIO());
1587 
1588  // check that we actually read some
1589  // cells.
1590  AssertThrow(cells.size() > 0, ExcGmshNoCellInformation());
1591 
1592  // do some clean-up on
1593  // vertices...
1594  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
1595  // ... and cells
1596  if (dim==spacedim)
1599  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
1600 
1601  // in 1d, we also have to attach boundary ids to vertices, which does not
1602  // currently work through the call above
1603  if (dim == 1)
1604  assign_1d_boundary_ids (boundary_ids_1d, *tria);
1605 }
1606 
1607 
1608 template <>
1609 void GridIn<1>::read_netcdf (const std::string &)
1610 {
1611  AssertThrow(false, ExcImpossibleInDim(1));
1612 }
1613 
1614 template <>
1615 void GridIn<1,2>::read_netcdf (const std::string &)
1616 {
1617  AssertThrow(false, ExcImpossibleInDim(1));
1618 }
1619 
1620 
1621 template <>
1622 void GridIn<1,3>::read_netcdf (const std::string &)
1623 {
1624  AssertThrow(false, ExcImpossibleInDim(1));
1625 }
1626 
1627 
1628 template <>
1629 void GridIn<2, 3>::read_netcdf (const std::string &)
1630 {
1631  Assert(false, ExcNotImplemented());
1632 }
1633 
1634 template <>
1635 void GridIn<2>::read_netcdf (const std::string &filename)
1636 {
1637 #ifndef DEAL_II_WITH_NETCDF
1638  (void)filename;
1639  AssertThrow(false, ExcNeedsNetCDF());
1640 #else
1641  const unsigned int dim=2;
1642  const unsigned int spacedim=2;
1643  Assert (tria != nullptr, ExcNoTriangulationSelected());
1644  // this function assumes the TAU
1645  // grid format.
1646  //
1647  // This format stores 2d grids as
1648  // 3d grids. In particular, a 2d
1649  // grid of n_cells quadrilaterals
1650  // in the y=0 plane is duplicated
1651  // to y=1 to build n_cells
1652  // hexaeders. The surface
1653  // quadrilaterals of this 3d grid
1654  // are marked with boundary
1655  // marker. In the following we read
1656  // in all data required, find the
1657  // boundary marker associated with
1658  // the plane y=0, and extract the
1659  // corresponding 2d data to build a
1660  // Triangulation<2>.
1661 
1662  // In the following, we assume that
1663  // the 2d grid lies in the x-z
1664  // plane (y=0). I.e. we choose:
1665  // point[coord]=0, with coord=1
1666  const unsigned int coord=1;
1667  // Also x-y-z (0-1-2) point
1668  // coordinates will be transformed
1669  // to x-y (x2d-y2d) coordinates.
1670  // With coord=1 as above, we have
1671  // x-z (0-2) -> (x2d-y2d)
1672  const unsigned int x2d=0;
1673  const unsigned int y2d=2;
1674  // For the case, the 2d grid lies
1675  // in x-y or y-z plane instead, the
1676  // following code must be extended
1677  // to find the right value for
1678  // coord, and setting x2d and y2d
1679  // accordingly.
1680 
1681  // First, open the file
1682  NcFile nc (filename.c_str());
1683  AssertThrow(nc.is_valid(), ExcIO());
1684 
1685  // then read n_cells
1686  NcDim *elements_dim=nc.get_dim("no_of_elements");
1687  AssertThrow(elements_dim->is_valid(), ExcIO());
1688  const unsigned int n_cells=elements_dim->size();
1689 
1690  // then we read
1691  // int marker(no_of_markers)
1692  NcDim *marker_dim=nc.get_dim("no_of_markers");
1693  AssertThrow(marker_dim->is_valid(), ExcIO());
1694  const unsigned int n_markers=marker_dim->size();
1695 
1696  NcVar *marker_var=nc.get_var("marker");
1697  AssertThrow(marker_var->is_valid(), ExcIO());
1698  AssertThrow(marker_var->num_dims()==1, ExcIO());
1699  AssertThrow(static_cast<unsigned int>(
1700  marker_var->get_dim(0)->size())==n_markers, ExcIO());
1701 
1702  std::vector<int> marker(n_markers);
1703  // use &* to convert
1704  // vector<int>::iterator to int *
1705  marker_var->get(&*marker.begin(), n_markers);
1706 
1707  // next we read
1708  // int boundarymarker_of_surfaces(
1709  // no_of_surfaceelements)
1710  NcDim *bquads_dim=nc.get_dim("no_of_surfacequadrilaterals");
1711  AssertThrow(bquads_dim->is_valid(), ExcIO());
1712  const unsigned int n_bquads=bquads_dim->size();
1713 
1714  NcVar *bmarker_var=nc.get_var("boundarymarker_of_surfaces");
1715  AssertThrow(bmarker_var->is_valid(), ExcIO());
1716  AssertThrow(bmarker_var->num_dims()==1, ExcIO());
1717  AssertThrow(static_cast<unsigned int>(
1718  bmarker_var->get_dim(0)->size())==n_bquads, ExcIO());
1719 
1720  std::vector<int> bmarker(n_bquads);
1721  bmarker_var->get(&*bmarker.begin(), n_bquads);
1722 
1723  // for each marker count the
1724  // number of boundary quads
1725  // which carry this marker
1726  std::map<int, unsigned int> n_bquads_per_bmarker;
1727  for (unsigned int i=0; i<n_markers; ++i)
1728  {
1729  // the markers should all be
1730  // different
1731  AssertThrow(n_bquads_per_bmarker.find(marker[i])==
1732  n_bquads_per_bmarker.end(), ExcIO());
1733 
1734  n_bquads_per_bmarker[marker[i]]=
1735  count(bmarker.begin(), bmarker.end(), marker[i]);
1736  }
1737  // Note: the n_bquads_per_bmarker
1738  // map could be used to find the
1739  // right coord by finding the
1740  // marker0 such that
1741  // a/ n_bquads_per_bmarker[marker0]==n_cells
1742  // b/ point[coord]==0,
1743  // Condition a/ would hold for at
1744  // least two markers, marker0 and
1745  // marker1, whereas b/ would hold
1746  // for marker0 only. For marker1 we
1747  // then had point[coord]=constant
1748  // with e.g. constant=1 or -1
1749 
1750  // next we read
1751  // int points_of_surfacequadrilaterals(
1752  // no_of_surfacequadrilaterals,
1753  // points_per_surfacequadrilateral)
1754  NcDim *quad_vertices_dim=nc.get_dim("points_per_surfacequadrilateral");
1755  AssertThrow(quad_vertices_dim->is_valid(), ExcIO());
1756  const unsigned int vertices_per_quad=quad_vertices_dim->size();
1758 
1759  NcVar *vertex_indices_var=nc.get_var("points_of_surfacequadrilaterals");
1760  AssertThrow(vertex_indices_var->is_valid(), ExcIO());
1761  AssertThrow(vertex_indices_var->num_dims()==2, ExcIO());
1762  AssertThrow(static_cast<unsigned int>(
1763  vertex_indices_var->get_dim(0)->size())==n_bquads, ExcIO());
1764  AssertThrow(static_cast<unsigned int>(
1765  vertex_indices_var->get_dim(1)->size())==vertices_per_quad, ExcIO());
1766 
1767  std::vector<int> vertex_indices(n_bquads*vertices_per_quad);
1768  vertex_indices_var->get(&*vertex_indices.begin(), n_bquads, vertices_per_quad);
1769 
1770  for (unsigned int i=0; i<vertex_indices.size(); ++i)
1771  AssertThrow(vertex_indices[i]>=0, ExcIO());
1772 
1773  // next we read
1774  // double points_xc(no_of_points)
1775  // double points_yc(no_of_points)
1776  // double points_zc(no_of_points)
1777  NcDim *vertices_dim=nc.get_dim("no_of_points");
1778  AssertThrow(vertices_dim->is_valid(), ExcIO());
1779  const unsigned int n_vertices=vertices_dim->size();
1780 
1781  NcVar *points_xc=nc.get_var("points_xc");
1782  NcVar *points_yc=nc.get_var("points_yc");
1783  NcVar *points_zc=nc.get_var("points_zc");
1784  AssertThrow(points_xc->is_valid(), ExcIO());
1785  AssertThrow(points_yc->is_valid(), ExcIO());
1786  AssertThrow(points_zc->is_valid(), ExcIO());
1787  AssertThrow(points_xc->num_dims()==1, ExcIO());
1788  AssertThrow(points_yc->num_dims()==1, ExcIO());
1789  AssertThrow(points_zc->num_dims()==1, ExcIO());
1790  AssertThrow(points_yc->get_dim(0)->size()==
1791  static_cast<int>(n_vertices), ExcIO());
1792  AssertThrow(points_zc->get_dim(0)->size()==
1793  static_cast<int>(n_vertices), ExcIO());
1794  AssertThrow(points_xc->get_dim(0)->size()==
1795  static_cast<int>(n_vertices), ExcIO());
1796  std::vector<std::vector<double> > point_values(
1797  3, std::vector<double> (n_vertices));
1798  points_xc->get(&*point_values[0].begin(), n_vertices);
1799  points_yc->get(&*point_values[1].begin(), n_vertices);
1800  points_zc->get(&*point_values[2].begin(), n_vertices);
1801 
1802  // and fill the vertices
1803  std::vector<Point<spacedim> > vertices (n_vertices);
1804  for (unsigned int i=0; i<n_vertices; ++i)
1805  {
1806  vertices[i](0)=point_values[x2d][i];
1807  vertices[i](1)=point_values[y2d][i];
1808  }
1809 
1810  // For all boundary quads in the
1811  // point[coord]=0 plane add the
1812  // bmarker to zero_plane_markers
1813  std::map<int, bool> zero_plane_markers;
1814  for (unsigned int quad=0; quad<n_bquads; ++quad)
1815  {
1816  bool zero_plane=true;
1817  for (unsigned int i=0; i<vertices_per_quad; ++i)
1818  if (point_values[coord][vertex_indices[quad*vertices_per_quad+i]]!=0)
1819  {
1820  zero_plane=false;
1821  break;
1822  }
1823 
1824  if (zero_plane)
1825  zero_plane_markers[bmarker[quad]]=true;
1826  }
1827  unsigned int sum_of_zero_plane_cells=0;
1828  for (std::map<int, bool>::const_iterator iter=zero_plane_markers.begin();
1829  iter != zero_plane_markers.end(); ++iter)
1830  sum_of_zero_plane_cells+=n_bquads_per_bmarker[iter->first];
1831  AssertThrow(sum_of_zero_plane_cells==n_cells, ExcIO());
1832 
1833  // fill cells with all quads
1834  // associated with
1835  // zero_plane_markers
1836  std::vector<CellData<dim> > cells(n_cells);
1837  for (unsigned int quad=0, cell=0; quad<n_bquads; ++quad)
1838  {
1839  bool zero_plane=false;
1840  for (std::map<int, bool>::const_iterator iter=zero_plane_markers.begin();
1841  iter != zero_plane_markers.end(); ++iter)
1842  if (bmarker[quad]==iter->first)
1843  {
1844  zero_plane=true;
1845  break;
1846  }
1847 
1848  if (zero_plane)
1849  {
1850  for (unsigned int i=0; i<vertices_per_quad; ++i)
1851  {
1852  Assert(point_values[coord][vertex_indices[
1853  quad*vertices_per_quad+i]]==0, ExcNotImplemented());
1854  cells[cell].vertices[i]=vertex_indices[quad*vertices_per_quad+i];
1855  }
1856  ++cell;
1857  }
1858  }
1859 
1860  SubCellData subcelldata;
1861  GridTools::delete_unused_vertices(vertices, cells, subcelldata);
1863  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
1864 #endif
1865 }
1866 
1867 
1868 template <>
1869 void GridIn<3>::read_netcdf (const std::string &filename)
1870 {
1871 #ifndef DEAL_II_WITH_NETCDF
1872  // do something with the function argument
1873  // to make sure it at least looks used,
1874  // even if it is not
1875  (void)filename;
1876  AssertThrow(false, ExcNeedsNetCDF());
1877 #else
1878  const unsigned int dim=3;
1879  const unsigned int spacedim=3;
1880  Assert (tria != nullptr, ExcNoTriangulationSelected());
1881  // this function assumes the TAU
1882  // grid format.
1883 
1884  // First, open the file
1885  NcFile nc (filename.c_str());
1886  AssertThrow(nc.is_valid(), ExcIO());
1887 
1888  // then read n_cells
1889  NcDim *elements_dim=nc.get_dim("no_of_elements");
1890  AssertThrow(elements_dim->is_valid(), ExcIO());
1891  const unsigned int n_cells=elements_dim->size();
1892  // and n_hexes
1893  NcDim *hexes_dim=nc.get_dim("no_of_hexaeders");
1894  AssertThrow(hexes_dim->is_valid(), ExcIO());
1895  const unsigned int n_hexes=hexes_dim->size();
1896  AssertThrow(n_hexes==n_cells,
1897  ExcMessage("deal.II can handle purely hexaedral grids, only."));
1898 
1899  // next we read
1900  // int points_of_hexaeders(
1901  // no_of_hexaeders,
1902  // points_per_hexaeder)
1903  NcDim *hex_vertices_dim=nc.get_dim("points_per_hexaeder");
1904  AssertThrow(hex_vertices_dim->is_valid(), ExcIO());
1905  const unsigned int vertices_per_hex=hex_vertices_dim->size();
1907 
1908  NcVar *vertex_indices_var=nc.get_var("points_of_hexaeders");
1909  AssertThrow(vertex_indices_var->is_valid(), ExcIO());
1910  AssertThrow(vertex_indices_var->num_dims()==2, ExcIO());
1911  AssertThrow(static_cast<unsigned int>(
1912  vertex_indices_var->get_dim(0)->size())==n_cells, ExcIO());
1913  AssertThrow(static_cast<unsigned int>(
1914  vertex_indices_var->get_dim(1)->size())==vertices_per_hex, ExcIO());
1915 
1916  std::vector<int> vertex_indices(n_cells*vertices_per_hex);
1917  // use &* to convert
1918  // vector<int>::iterator to int *
1919  vertex_indices_var->get(&*vertex_indices.begin(), n_cells, vertices_per_hex);
1920 
1921  for (unsigned int i=0; i<vertex_indices.size(); ++i)
1922  AssertThrow(vertex_indices[i]>=0, ExcIO());
1923 
1924  // next we read
1925  // double points_xc(no_of_points)
1926  // double points_yc(no_of_points)
1927  // double points_zc(no_of_points)
1928  NcDim *vertices_dim=nc.get_dim("no_of_points");
1929  AssertThrow(vertices_dim->is_valid(), ExcIO());
1930  const unsigned int n_vertices=vertices_dim->size();
1931 
1932  NcVar *points_xc=nc.get_var("points_xc");
1933  NcVar *points_yc=nc.get_var("points_yc");
1934  NcVar *points_zc=nc.get_var("points_zc");
1935  AssertThrow(points_xc->is_valid(), ExcIO());
1936  AssertThrow(points_yc->is_valid(), ExcIO());
1937  AssertThrow(points_zc->is_valid(), ExcIO());
1938  AssertThrow(points_xc->num_dims()==1, ExcIO());
1939  AssertThrow(points_yc->num_dims()==1, ExcIO());
1940  AssertThrow(points_zc->num_dims()==1, ExcIO());
1941  AssertThrow(points_yc->get_dim(0)->size()==
1942  static_cast<int>(n_vertices), ExcIO());
1943  AssertThrow(points_zc->get_dim(0)->size()==
1944  static_cast<int>(n_vertices), ExcIO());
1945  AssertThrow(points_xc->get_dim(0)->size()==
1946  static_cast<int>(n_vertices), ExcIO());
1947  std::vector<std::vector<double> > point_values(
1948  3, std::vector<double> (n_vertices));
1949  points_xc->get(&*point_values[0].begin(), n_vertices);
1950  points_yc->get(&*point_values[1].begin(), n_vertices);
1951  points_zc->get(&*point_values[2].begin(), n_vertices);
1952 
1953  // and fill the vertices
1954  std::vector<Point<spacedim> > vertices (n_vertices);
1955  for (unsigned int i=0; i<n_vertices; ++i)
1956  {
1957  vertices[i](0)=point_values[0][i];
1958  vertices[i](1)=point_values[1][i];
1959  vertices[i](2)=point_values[2][i];
1960  }
1961 
1962  // and cells
1963  std::vector<CellData<dim> > cells(n_cells);
1964  for (unsigned int cell=0; cell<n_cells; ++cell)
1965  for (unsigned int i=0; i<vertices_per_hex; ++i)
1966  cells[cell].vertices[i]=vertex_indices[cell*vertices_per_hex+i];
1967 
1968  // for setting up the SubCellData
1969  // we read the vertex indices of
1970  // the boundary quadrilaterals and
1971  // their boundary markers
1972 
1973  // first we read
1974  // int points_of_surfacequadrilaterals(
1975  // no_of_surfacequadrilaterals,
1976  // points_per_surfacequadrilateral)
1977  NcDim *quad_vertices_dim=nc.get_dim("points_per_surfacequadrilateral");
1978  AssertThrow(quad_vertices_dim->is_valid(), ExcIO());
1979  const unsigned int vertices_per_quad=quad_vertices_dim->size();
1981 
1982  NcVar *bvertex_indices_var=nc.get_var("points_of_surfacequadrilaterals");
1983  AssertThrow(bvertex_indices_var->is_valid(), ExcIO());
1984  AssertThrow(bvertex_indices_var->num_dims()==2, ExcIO());
1985  const unsigned int n_bquads=bvertex_indices_var->get_dim(0)->size();
1986  AssertThrow(static_cast<unsigned int>(
1987  bvertex_indices_var->get_dim(1)->size())==
1989 
1990  std::vector<int> bvertex_indices(n_bquads*vertices_per_quad);
1991  bvertex_indices_var->get(&*bvertex_indices.begin(), n_bquads, vertices_per_quad);
1992 
1993  // next we read
1994  // int boundarymarker_of_surfaces(
1995  // no_of_surfaceelements)
1996  NcDim *bquads_dim=nc.get_dim("no_of_surfacequadrilaterals");
1997  AssertThrow(bquads_dim->is_valid(), ExcIO());
1998  AssertThrow(static_cast<unsigned int>(
1999  bquads_dim->size())==n_bquads, ExcIO());
2000 
2001  NcVar *bmarker_var=nc.get_var("boundarymarker_of_surfaces");
2002  AssertThrow(bmarker_var->is_valid(), ExcIO());
2003  AssertThrow(bmarker_var->num_dims()==1, ExcIO());
2004  AssertThrow(static_cast<unsigned int>(
2005  bmarker_var->get_dim(0)->size())==n_bquads, ExcIO());
2006 
2007  std::vector<int> bmarker(n_bquads);
2008  bmarker_var->get(&*bmarker.begin(), n_bquads);
2009  // we only handle boundary
2010  // indicators that fit into an
2011  // types::boundary_id. Also, we don't
2012  // take numbers::internal_face_boundary_id
2013  // as it denotes an internal face
2014  for (unsigned int i=0; i<bmarker.size(); ++i)
2015  Assert(0<=bmarker[i] &&
2016  static_cast<types::boundary_id>(bmarker[i])!=numbers::internal_face_boundary_id,
2017  ExcIO());
2018 
2019  // finally we setup the boundary
2020  // information
2021  SubCellData subcelldata;
2022  subcelldata.boundary_quads.resize(n_bquads);
2023  for (unsigned int i=0; i<n_bquads; ++i)
2024  {
2025  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
2026  subcelldata.boundary_quads[i].vertices[v]=bvertex_indices[
2028  subcelldata.boundary_quads[i].boundary_id
2029  = static_cast<types::boundary_id>(bmarker[i]);
2030  }
2031 
2032  GridTools::delete_unused_vertices(vertices, cells, subcelldata);
2035  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
2036 #endif
2037 }
2038 
2039 
2040 template <int dim, int spacedim>
2042  std::vector<unsigned int> &tecplot2deal,
2043  unsigned int &n_vars,
2044  unsigned int &n_vertices,
2045  unsigned int &n_cells,
2046  std::vector<unsigned int> &IJK,
2047  bool &structured,
2048  bool &blocked)
2049 {
2050  Assert(tecplot2deal.size()==dim, ExcInternalError());
2051  Assert(IJK.size()==dim, ExcInternalError());
2052  // initialize the output variables
2053  n_vars=0;
2054  n_vertices=0;
2055  n_cells=0;
2056  switch (dim)
2057  {
2058  case 3:
2059  IJK[2]=0;
2060  DEAL_II_FALLTHROUGH;
2061  case 2:
2062  IJK[1]=0;
2063  DEAL_II_FALLTHROUGH;
2064  case 1:
2065  IJK[0]=0;
2066  }
2067  structured=true;
2068  blocked=false;
2069 
2070  // convert the string to upper case
2071  std::transform(header.begin(),header.end(),header.begin(),::toupper);
2072 
2073  // replace all tabs, commas, newlines by
2074  // whitespaces
2075  std::replace(header.begin(),header.end(),'\t',' ');
2076  std::replace(header.begin(),header.end(),',',' ');
2077  std::replace(header.begin(),header.end(),'\n',' ');
2078 
2079  // now remove whitespace in front of and
2080  // after '='
2081  std::string::size_type pos=header.find('=');
2082 
2083  while (pos!=static_cast<std::string::size_type>(std::string::npos))
2084  if (header[pos+1]==' ')
2085  header.erase(pos+1,1);
2086  else if (header[pos-1]==' ')
2087  {
2088  header.erase(pos-1,1);
2089  --pos;
2090  }
2091  else
2092  pos=header.find('=',++pos);
2093 
2094  // split the string into individual entries
2095  std::vector<std::string> entries=Utilities::break_text_into_lines(header,1,' ');
2096 
2097  // now go through the list and try to extract
2098  for (unsigned int i=0; i<entries.size(); ++i)
2099  {
2100  if (Utilities::match_at_string_start(entries[i],"VARIABLES=\""))
2101  {
2102  ++n_vars;
2103  // we assume, that the first variable
2104  // is x or no coordinate at all (not y or z)
2105  if (Utilities::match_at_string_start(entries[i],"VARIABLES=\"X\""))
2106  {
2107  tecplot2deal[0]=0;
2108  }
2109  ++i;
2110  while (entries[i][0]=='"')
2111  {
2112  if (entries[i]=="\"X\"")
2113  tecplot2deal[0]=n_vars;
2114  else if (entries[i]=="\"Y\"")
2115  {
2116  // we assume, that y contains
2117  // zero data in 1d, so do
2118  // nothing
2119  if (dim>1)
2120  tecplot2deal[1]=n_vars;
2121  }
2122  else if (entries[i]=="\"Z\"")
2123  {
2124  // we assume, that z contains
2125  // zero data in 1d and 2d, so
2126  // do nothing
2127  if (dim>2)
2128  tecplot2deal[2]=n_vars;
2129  }
2130  ++n_vars;
2131  ++i;
2132  }
2133  // set i back, so that the next
2134  // string is treated correctly
2135  --i;
2136 
2137  AssertThrow(n_vars>=dim,
2138  ExcMessage("Tecplot file must contain at least one variable for each dimension"));
2139  for (unsigned int d=1; d<dim; ++d)
2140  AssertThrow(tecplot2deal[d]>0,
2141  ExcMessage("Tecplot file must contain at least one variable for each dimension."));
2142  }
2143  else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=ORDERED"))
2144  structured=true;
2145  else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FELINESEG") && dim==1)
2146  structured=false;
2147  else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FEQUADRILATERAL") && dim==2)
2148  structured=false;
2149  else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FEBRICK") && dim==3)
2150  structured=false;
2151  else if (Utilities::match_at_string_start(entries[i],"ZONETYPE="))
2152  // unsupported ZONETYPE
2153  {
2154  AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ZONETYPE."));
2155  }
2156  else if (Utilities::match_at_string_start(entries[i],"DATAPACKING=POINT"))
2157  blocked=false;
2158  else if (Utilities::match_at_string_start(entries[i],"DATAPACKING=BLOCK"))
2159  blocked=true;
2160  else if (Utilities::match_at_string_start(entries[i],"F=POINT"))
2161  {
2162  structured=true;
2163  blocked=false;
2164  }
2165  else if (Utilities::match_at_string_start(entries[i],"F=BLOCK"))
2166  {
2167  structured=true;
2168  blocked=true;
2169  }
2170  else if (Utilities::match_at_string_start(entries[i],"F=FEPOINT"))
2171  {
2172  structured=false;
2173  blocked=false;
2174  }
2175  else if (Utilities::match_at_string_start(entries[i],"F=FEBLOCK"))
2176  {
2177  structured=false;
2178  blocked=true;
2179  }
2180  else if (Utilities::match_at_string_start(entries[i],"ET=QUADRILATERAL") && dim==2)
2181  structured=false;
2182  else if (Utilities::match_at_string_start(entries[i],"ET=BRICK") && dim==3)
2183  structured=false;
2184  else if (Utilities::match_at_string_start(entries[i],"ET="))
2185  // unsupported ElementType
2186  {
2187  AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ElementType."));
2188  }
2189  else if (Utilities::match_at_string_start(entries[i],"I="))
2190  IJK[0]=Utilities::get_integer_at_position(entries[i],2).first;
2191  else if (Utilities::match_at_string_start(entries[i],"J="))
2192  {
2193  IJK[1]=Utilities::get_integer_at_position(entries[i],2).first;
2194  AssertThrow(dim>1 || IJK[1]==1,
2195  ExcMessage("Parameter 'J=' found in tecplot, although this is only possible for dimensions greater than 1."));
2196  }
2197  else if (Utilities::match_at_string_start(entries[i],"K="))
2198  {
2199  IJK[2]=Utilities::get_integer_at_position(entries[i],2).first;
2200  AssertThrow(dim>2 || IJK[2]==1,
2201  ExcMessage("Parameter 'K=' found in tecplot, although this is only possible for dimensions greater than 2."));
2202  }
2203  else if (Utilities::match_at_string_start(entries[i],"N="))
2204  n_vertices=Utilities::get_integer_at_position(entries[i],2).first;
2205  else if (Utilities::match_at_string_start(entries[i],"E="))
2206  n_cells=Utilities::get_integer_at_position(entries[i],2).first;
2207  }
2208 
2209  // now we have read all the fields we are
2210  // interested in. do some checks and
2211  // calculate the variables
2212  if (structured)
2213  {
2214  n_vertices=1;
2215  n_cells=1;
2216  for (unsigned int d=0; d<dim; ++d)
2217  {
2218  AssertThrow(IJK[d]>0,
2219  ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
2220  n_vertices*=IJK[d];
2221  n_cells*=(IJK[d]-1);
2222  }
2223  }
2224  else
2225  {
2226  AssertThrow(n_vertices>0,
2227  ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
2228  if (n_cells==0)
2229  // this means an error, although
2230  // tecplot itself accepts entries like
2231  // 'J=20' instead of 'E=20'. therefore,
2232  // take the max of IJK
2233  n_cells=*std::max_element(IJK.begin(),IJK.end());
2234  AssertThrow(n_cells>0,
2235  ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
2236  }
2237 }
2238 
2239 
2240 
2241 
2242 template <>
2243 void GridIn<2>::read_tecplot (std::istream &in)
2244 {
2245  const unsigned int dim=2;
2246  const unsigned int spacedim=2;
2247  Assert (tria != nullptr, ExcNoTriangulationSelected());
2248  AssertThrow (in, ExcIO());
2249 
2250  // skip comments at start of file
2251  skip_comment_lines (in, '#');
2252 
2253  // some strings for parsing the header
2254  std::string line, header;
2255 
2256  // first, concatenate all header lines
2257  // create a searchstring with almost all
2258  // letters. exclude e and E from the letters
2259  // to search, as they might appear in
2260  // exponential notation
2261  std::string letters ="abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ";
2262 
2263  getline(in,line);
2264  while (line.find_first_of(letters)!=std::string::npos)
2265  {
2266  header+=" "+line;
2267  getline(in,line);
2268  }
2269 
2270  // now create some variables holding
2271  // important information on the mesh, get
2272  // this information from the header string
2273  std::vector<unsigned int> tecplot2deal(dim);
2274  std::vector<unsigned int> IJK(dim);
2275  unsigned int n_vars,
2276  n_vertices,
2277  n_cells;
2278  bool structured,
2279  blocked;
2280 
2281  parse_tecplot_header(header,
2282  tecplot2deal,n_vars,n_vertices,n_cells,IJK,
2283  structured,blocked);
2284 
2285  // reserve space for vertices. note, that in
2286  // tecplot vertices are ordered beginning
2287  // with 1, whereas in deal all indices start
2288  // with 0. in order not to use -1 for all the
2289  // connectivity information, a 0th vertex
2290  // (unused) is inserted at the origin.
2291  std::vector<Point<spacedim> > vertices(n_vertices+1);
2292  vertices[0]=Point<spacedim>();
2293  // reserve space for cells
2294  std::vector<CellData<dim> > cells(n_cells);
2295  SubCellData subcelldata;
2296 
2297  if (blocked)
2298  {
2299  // blocked data format. first we get all
2300  // the values of the first variable for
2301  // all points, after that we get all
2302  // values for the second variable and so
2303  // on.
2304 
2305  // dummy variable to read in all the info
2306  // we do not want to use
2307  double dummy;
2308  // which is the first index to read in
2309  // the loop (see below)
2310  unsigned int next_index=0;
2311 
2312  // note, that we have already read the
2313  // first line containing the first variable
2314  if (tecplot2deal[0]==0)
2315  {
2316  // we need the information in this
2317  // line, so extract it
2318  std::vector<std::string> first_var=Utilities::break_text_into_lines(line,1);
2319  char *endptr;
2320  for (unsigned int i=1; i<first_var.size()+1; ++i)
2321  vertices[i](0) = std::strtod (first_var[i-1].c_str(), &endptr);
2322 
2323  // if there are many points, the data
2324  // for this var might continue in the
2325  // next line(s)
2326  for (unsigned int j=first_var.size()+1; j<n_vertices+1; ++j)
2327  in>>vertices[j](next_index);
2328  // now we got all values of the first
2329  // variable, so increase the counter
2330  next_index=1;
2331  }
2332 
2333  // main loop over all variables
2334  for (unsigned int i=1; i<n_vars; ++i)
2335  {
2336  // if we read all the important
2337  // variables and do not want to
2338  // read further, because we are
2339  // using a structured grid, we can
2340  // stop here (and skip, for
2341  // example, a whole lot of solution
2342  // variables)
2343  if (next_index==dim && structured)
2344  break;
2345 
2346  if ((next_index<dim) && (i==tecplot2deal[next_index]))
2347  {
2348  // we need this line, read it in
2349  for (unsigned int j=1; j<n_vertices+1; ++j)
2350  in>>vertices[j](next_index);
2351  ++next_index;
2352  }
2353  else
2354  {
2355  // we do not need this line, read
2356  // it in and discard it
2357  for (unsigned int j=1; j<n_vertices+1; ++j)
2358  in>>dummy;
2359  }
2360  }
2361  Assert(next_index==dim, ExcInternalError());
2362  }
2363  else
2364  {
2365  // the data is not blocked, so we get all
2366  // the variables for one point, then the
2367  // next and so on. create a vector to
2368  // hold these components
2369  std::vector<double> vars(n_vars);
2370 
2371  // now fill the first vertex. note, that we
2372  // have already read the first line
2373  // containing the first vertex
2374  std::vector<std::string> first_vertex=Utilities::break_text_into_lines(line,1);
2375  char *endptr;
2376  for (unsigned int d=0; d<dim; ++d)
2377  vertices[1](d) = std::strtod (first_vertex[tecplot2deal[d]].c_str(), &endptr);
2378 
2379  // read the remaining vertices from the
2380  // list
2381  for (unsigned int v=2; v<n_vertices+1; ++v)
2382  {
2383  for (unsigned int i=0; i<n_vars; ++i)
2384  in>>vars[i];
2385  // fill the vertex
2386  // coordinates. respect the position
2387  // of coordinates in the list of
2388  // variables
2389  for (unsigned int i=0; i<dim; ++i)
2390  vertices[v](i)=vars[tecplot2deal[i]];
2391  }
2392  }
2393 
2394  if (structured)
2395  {
2396  // this is the part of the code that only
2397  // works in 2d
2398  unsigned int I=IJK[0],
2399  J=IJK[1];
2400 
2401  unsigned int cell=0;
2402  // set up array of cells
2403  for (unsigned int j=0; j<J-1; ++j)
2404  for (unsigned int i=1; i<I; ++i)
2405  {
2406  cells[cell].vertices[0]=i+ j *I;
2407  cells[cell].vertices[1]=i+1+j *I;
2408  cells[cell].vertices[2]=i+1+(j+1)*I;
2409  cells[cell].vertices[3]=i +(j+1)*I;
2410  ++cell;
2411  }
2412  Assert(cell==n_cells, ExcInternalError());
2413  std::vector<unsigned int> boundary_vertices(2*I+2*J-4);
2414  unsigned int k=0;
2415  for (unsigned int i=1; i<I+1; ++i)
2416  {
2417  boundary_vertices[k]=i;
2418  ++k;
2419  boundary_vertices[k]=i+(J-1)*I;
2420  ++k;
2421  }
2422  for (unsigned int j=1; j<J-1; ++j)
2423  {
2424  boundary_vertices[k]=1+j*I;
2425  ++k;
2426  boundary_vertices[k]=I+j*I;
2427  ++k;
2428  }
2429  Assert(k==boundary_vertices.size(), ExcInternalError());
2430  // delete the duplicated vertices at the
2431  // boundary, which occur, e.g. in c-type
2432  // or o-type grids around a body
2433  // (airfoil). this automatically deletes
2434  // unused vertices as well.
2435  GridTools::delete_duplicated_vertices(vertices,cells,subcelldata,boundary_vertices);
2436  }
2437  else
2438  {
2439  // set up array of cells, unstructured
2440  // mode, so the connectivity is
2441  // explicitly given
2442  for (unsigned int i=0; i<n_cells; ++i)
2443  {
2444  // note that since in the input file
2445  // we found the number of cells at
2446  // the top, there should still be
2447  // input here, so check this:
2448  AssertThrow (in, ExcIO());
2449 
2450  // get the connectivity from the
2451  // input file. the vertices are
2452  // ordered like in the ucd format
2453  for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
2454  in>>cells[i].vertices[j];
2455  }
2456  // do some clean-up on vertices
2457  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
2458  }
2459 
2460  // check that no forbidden arrays are
2461  // used. as we do not read in any
2462  // subcelldata, nothing should happen here.
2463  Assert (subcelldata.check_consistency(dim), ExcInternalError());
2464  AssertThrow (in, ExcIO());
2465 
2466  // do some cleanup on cells
2469  tria->create_triangulation_compatibility (vertices, cells, subcelldata);
2470 }
2471 
2472 
2473 
2474 template <int dim, int spacedim>
2476 {
2477  Assert(false, ExcNotImplemented());
2478 }
2479 
2480 
2481 
2482 template <int dim, int spacedim>
2483 void GridIn<dim, spacedim>::read_assimp(const std::string &filename,
2484  const unsigned int mesh_index,
2485  const bool remove_duplicates,
2486  const double tol,
2487  const bool ignore_unsupported_types)
2488 {
2489 #ifdef DEAL_II_WITH_ASSIMP
2490  // Only good for surface grids.
2491  AssertThrow(dim<3, ExcImpossibleInDim(dim));
2492 
2493  // Create an instance of the Importer class
2494  Assimp::Importer importer;
2495 
2496  // And have it read the given file with some postprocessing
2497  const aiScene *scene = importer.ReadFile( filename.c_str(),
2498  aiProcess_RemoveComponent |
2499  aiProcess_JoinIdenticalVertices |
2500  aiProcess_ImproveCacheLocality |
2501  aiProcess_SortByPType |
2502  aiProcess_OptimizeGraph |
2503  aiProcess_OptimizeMeshes);
2504 
2505  // If the import failed, report it
2506  AssertThrow(scene, ExcMessage(importer.GetErrorString()))
2507 
2508  AssertThrow(scene->mNumMeshes, ExcMessage("Input file contains no meshes."));
2509 
2510  AssertThrow((mesh_index == numbers::invalid_unsigned_int) ||
2511  (mesh_index < scene->mNumMeshes),
2512  ExcMessage("Too few meshes in the file."));
2513 
2514  unsigned int start_mesh = (mesh_index == numbers::invalid_unsigned_int ?
2515  0 : mesh_index);
2516  unsigned int end_mesh = (mesh_index == numbers::invalid_unsigned_int ?
2517  scene->mNumMeshes : mesh_index+1);
2518 
2519  // Deal.II objects are created empty, and then filled with imported file.
2520  std::vector<Point<spacedim> > vertices;
2521  std::vector<CellData<dim> > cells;
2522  SubCellData subcelldata;
2523 
2524  // A series of counters to merge cells.
2525  unsigned int v_offset=0;
2526  unsigned int c_offset=0;
2527 
2528  // The index of the mesh will be used as a material index.
2529  for (unsigned int m=start_mesh; m<end_mesh; ++m)
2530  {
2531  const aiMesh *mesh = scene->mMeshes[m];
2532 
2533  // Check that we know what to do with this mesh, otherwise just
2534  // ignore it
2535  if ( (dim == 2) && mesh->mPrimitiveTypes != aiPrimitiveType_POLYGON)
2536  {
2537  AssertThrow(ignore_unsupported_types,
2538  ExcMessage("Incompatible mesh " + std::to_string(m) +
2539  "/" + std::to_string(scene->mNumMeshes)));
2540  continue;
2541  }
2542  else if ( (dim == 1) && mesh->mPrimitiveTypes != aiPrimitiveType_LINE)
2543  {
2544  AssertThrow(ignore_unsupported_types,
2545  ExcMessage("Incompatible mesh " + std::to_string(m) +
2546  "/" + std::to_string(scene->mNumMeshes)));
2547  continue;
2548  }
2549  // Vertices
2550  const unsigned int n_vertices = mesh->mNumVertices;
2551  const aiVector3D *mVertices = mesh->mVertices;
2552 
2553  // Faces
2554  const unsigned int n_faces = mesh->mNumFaces;
2555  const aiFace *mFaces = mesh->mFaces;
2556 
2557  vertices.resize(v_offset+n_vertices);
2558  cells.resize(c_offset+n_faces);
2559 
2560  for (unsigned int i=0; i<n_vertices; ++i)
2561  for (unsigned int d=0; d<spacedim; ++d)
2562  vertices[i+v_offset][d] = mVertices[i][d];
2563 
2564  unsigned int valid_cell = c_offset;
2565  for (unsigned int i=0; i<n_faces; ++i)
2566  {
2567  if (mFaces[i].mNumIndices == GeometryInfo<dim>::vertices_per_cell)
2568  {
2569  for (unsigned int f=0; f<GeometryInfo<dim>::vertices_per_cell; ++f)
2570  {
2571  cells[valid_cell].vertices[f] = mFaces[i].mIndices[f]+v_offset;
2572  }
2573  cells[valid_cell].material_id = (types::material_id) m;
2574  ++valid_cell;
2575  }
2576  else
2577  {
2578  AssertThrow(ignore_unsupported_types,
2579  ExcMessage("Face " + std::to_string(i) + " of mesh "
2580  + std::to_string(m) + " has "
2581  + std::to_string(mFaces[i].mNumIndices)
2582  + " vertices. We expected only "
2583  + std::to_string(GeometryInfo<dim>::vertices_per_cell)));
2584  }
2585  }
2586  cells.resize(valid_cell);
2587 
2588  // The vertices are added all at once. Cells are checked for
2589  // validity, so only valid_cells are now present in the deal.II
2590  // list of cells.
2591  v_offset += n_vertices;
2592  c_offset = valid_cell;
2593  }
2594 
2595  // No cells were read
2596  if (cells.size() == 0)
2597  return;
2598 
2599  if (remove_duplicates)
2600  {
2601  // The function delete_duplicated_vertices() needs to be called more
2602  // than once if a vertex is duplicated more than once. So we keep
2603  // calling it until the number of vertices does not change any more.
2604  unsigned int n_verts = 0;
2605  while (n_verts != vertices.size())
2606  {
2607  n_verts = vertices.size();
2608  std::vector<unsigned int> considered_vertices;
2609  GridTools::delete_duplicated_vertices(vertices, cells, subcelldata,
2610  considered_vertices, tol);
2611  }
2612  }
2613 
2614  GridTools::delete_unused_vertices(vertices, cells, subcelldata);
2615  if (dim == spacedim)
2617  (vertices,cells);
2618 
2620  if (dim == 2)
2621  tria->create_triangulation_compatibility(vertices, cells, subcelldata);
2622  else
2623  tria->create_triangulation(vertices, cells, subcelldata);
2624 #else
2625  (void) filename;
2626  (void) mesh_index;
2627  (void) remove_duplicates;
2628  (void) tol;
2629  (void) ignore_unsupported_types;
2630  Assert(false, ExcNeedsAssimp());
2631 #endif
2632 }
2633 
2634 
2635 template <int dim, int spacedim>
2637 {
2638  std::string line;
2639  while (in)
2640  {
2641  // get line
2642  getline (in, line);
2643 
2644  // check if this is a line that
2645  // consists only of spaces, and
2646  // if not put the whole thing
2647  // back and return
2648  if (std::find_if (line.begin(), line.end(),
2649  std::bind (std::not_equal_to<char>(),std::placeholders::_1,' '))
2650  != line.end())
2651  {
2652  in.putback ('\n');
2653  for (int i=line.length()-1; i>=0; --i)
2654  in.putback (line[i]);
2655  return;
2656  }
2657 
2658  // else: go on with next line
2659  }
2660 }
2661 
2662 
2663 
2664 template <int dim, int spacedim>
2666  const char comment_start)
2667 {
2668  char c;
2669  // loop over the following comment
2670  // lines
2671  while (in.get(c) && c == comment_start)
2672  // loop over the characters after
2673  // the comment starter
2674  while (in.get() != '\n')
2675  ;
2676 
2677 
2678  // put back first character of
2679  // first non-comment line
2680  if (in)
2681  in.putback (c);
2682 
2683  // at last: skip additional empty lines, if present
2684  skip_empty_lines(in);
2685 }
2686 
2687 
2688 
2689 template <int dim, int spacedim>
2690 void GridIn<dim, spacedim>::debug_output_grid (const std::vector<CellData<dim> > &/*cells*/,
2691  const std::vector<Point<spacedim> > &/*vertices*/,
2692  std::ostream &/*out*/)
2693 {
2694  Assert (false, ExcNotImplemented());
2695 }
2696 
2697 
2698 
2699 template <>
2700 void
2701 GridIn<2>::debug_output_grid (const std::vector<CellData<2> > &cells,
2702  const std::vector<Point<2> > &vertices,
2703  std::ostream &out)
2704 {
2705  double min_x = vertices[cells[0].vertices[0]](0),
2706  max_x = vertices[cells[0].vertices[0]](0),
2707  min_y = vertices[cells[0].vertices[0]](1),
2708  max_y = vertices[cells[0].vertices[0]](1);
2709 
2710  for (unsigned int i=0; i<cells.size(); ++i)
2711  {
2712  for (unsigned int v=0; v<4; ++v)
2713  {
2714  const Point<2> &p = vertices[cells[i].vertices[v]];
2715 
2716  if (p(0) < min_x)
2717  min_x = p(0);
2718  if (p(0) > max_x)
2719  max_x = p(0);
2720  if (p(1) < min_y)
2721  min_y = p(1);
2722  if (p(1) > max_y)
2723  max_y = p(1);
2724  };
2725 
2726  out << "# cell " << i << std::endl;
2727  Point<2> center;
2728  for (unsigned int f=0; f<4; ++f)
2729  center += vertices[cells[i].vertices[f]];
2730  center /= 4;
2731 
2732  out << "set label \"" << i << "\" at "
2733  << center(0) << ',' << center(1)
2734  << " center"
2735  << std::endl;
2736 
2737  // first two line right direction
2738  for (unsigned int f=0; f<2; ++f)
2739  out << "set arrow from "
2740  << vertices[cells[i].vertices[f]](0) << ','
2741  << vertices[cells[i].vertices[f]](1)
2742  << " to "
2743  << vertices[cells[i].vertices[(f+1)%4]](0) << ','
2744  << vertices[cells[i].vertices[(f+1)%4]](1)
2745  << std::endl;
2746  // other two lines reverse direction
2747  for (unsigned int f=2; f<4; ++f)
2748  out << "set arrow from "
2749  << vertices[cells[i].vertices[(f+1)%4]](0) << ','
2750  << vertices[cells[i].vertices[(f+1)%4]](1)
2751  << " to "
2752  << vertices[cells[i].vertices[f]](0) << ','
2753  << vertices[cells[i].vertices[f]](1)
2754  << std::endl;
2755  out << std::endl;
2756  };
2757 
2758 
2759  out << std::endl
2760  << "set nokey" << std::endl
2761  << "pl [" << min_x << ':' << max_x << "]["
2762  << min_y << ':' << max_y << "] "
2763  << min_y << std::endl
2764  << "pause -1" << std::endl;
2765 }
2766 
2767 
2768 
2769 template <>
2770 void
2771 GridIn<3>::debug_output_grid (const std::vector<CellData<3> > &cells,
2772  const std::vector<Point<3> > &vertices,
2773  std::ostream &out)
2774 {
2775  for (unsigned int cell=0; cell<cells.size(); ++cell)
2776  {
2777  // line 0
2778  out << vertices[cells[cell].vertices[0]]
2779  << std::endl
2780  << vertices[cells[cell].vertices[1]]
2781  << std::endl << std::endl << std::endl;
2782  // line 1
2783  out << vertices[cells[cell].vertices[1]]
2784  << std::endl
2785  << vertices[cells[cell].vertices[2]]
2786  << std::endl << std::endl << std::endl;
2787  // line 2
2788  out << vertices[cells[cell].vertices[3]]
2789  << std::endl
2790  << vertices[cells[cell].vertices[2]]
2791  << std::endl << std::endl << std::endl;
2792  // line 3
2793  out << vertices[cells[cell].vertices[0]]
2794  << std::endl
2795  << vertices[cells[cell].vertices[3]]
2796  << std::endl << std::endl << std::endl;
2797  // line 4
2798  out << vertices[cells[cell].vertices[4]]
2799  << std::endl
2800  << vertices[cells[cell].vertices[5]]
2801  << std::endl << std::endl << std::endl;
2802  // line 5
2803  out << vertices[cells[cell].vertices[5]]
2804  << std::endl
2805  << vertices[cells[cell].vertices[6]]
2806  << std::endl << std::endl << std::endl;
2807  // line 6
2808  out << vertices[cells[cell].vertices[7]]
2809  << std::endl
2810  << vertices[cells[cell].vertices[6]]
2811  << std::endl << std::endl << std::endl;
2812  // line 7
2813  out << vertices[cells[cell].vertices[4]]
2814  << std::endl
2815  << vertices[cells[cell].vertices[7]]
2816  << std::endl << std::endl << std::endl;
2817  // line 8
2818  out << vertices[cells[cell].vertices[0]]
2819  << std::endl
2820  << vertices[cells[cell].vertices[4]]
2821  << std::endl << std::endl << std::endl;
2822  // line 9
2823  out << vertices[cells[cell].vertices[1]]
2824  << std::endl
2825  << vertices[cells[cell].vertices[5]]
2826  << std::endl << std::endl << std::endl;
2827  // line 10
2828  out << vertices[cells[cell].vertices[2]]
2829  << std::endl
2830  << vertices[cells[cell].vertices[6]]
2831  << std::endl << std::endl << std::endl;
2832  // line 11
2833  out << vertices[cells[cell].vertices[3]]
2834  << std::endl
2835  << vertices[cells[cell].vertices[7]]
2836  << std::endl << std::endl << std::endl;
2837  };
2838 }
2839 
2840 
2841 
2842 template <int dim, int spacedim>
2843 void GridIn<dim, spacedim>::read (const std::string &filename,
2844  Format format)
2845 {
2846  // Search file class for meshes
2847  PathSearch search("MESH");
2848  std::string name;
2849  // Open the file and remember its name
2850  if (format == Default)
2851  name = search.find(filename);
2852  else
2853  name = search.find(filename, default_suffix(format));
2854 
2855  std::ifstream in(name.c_str());
2856 
2857  if (format == Default)
2858  {
2859  const std::string::size_type slashpos = name.find_last_of('/');
2860  const std::string::size_type dotpos = name.find_last_of('.');
2861  if (dotpos < name.length()
2862  && (dotpos > slashpos || slashpos == std::string::npos))
2863  {
2864  std::string ext = name.substr(dotpos+1);
2865  format = parse_format(ext);
2866  }
2867  }
2868  if (format == netcdf)
2869  read_netcdf(filename);
2870  else
2871  read(in, format);
2872 }
2873 
2874 
2875 template <int dim, int spacedim>
2876 void GridIn<dim, spacedim>::read (std::istream &in,
2877  Format format)
2878 {
2879  if (format == Default)
2880  format = default_format;
2881 
2882  switch (format)
2883  {
2884  case dbmesh:
2885  read_dbmesh (in);
2886  return;
2887 
2888  case msh:
2889  read_msh (in);
2890  return;
2891 
2892  case vtk:
2893  read_vtk (in);
2894  return;
2895 
2896  case unv:
2897  read_unv (in);
2898  return;
2899 
2900  case ucd:
2901  read_ucd (in);
2902  return;
2903 
2904  case abaqus:
2905  read_abaqus(in);
2906  return;
2907 
2908  case xda:
2909  read_xda (in);
2910  return;
2911 
2912  case netcdf:
2913  Assert(false, ExcMessage("There is no read_netcdf(istream &) function. "
2914  "Use the read_netcdf(string &filename) "
2915  "functions, instead."));
2916  return;
2917 
2918  case tecplot:
2919  read_tecplot (in);
2920  return;
2921 
2922  case assimp:
2923  Assert(false, ExcMessage("There is no read_assimp(istream &) function. "
2924  "Use the read_assimp(string &filename, ...) "
2925  "functions, instead."));
2926  return;
2927 
2928  case Default:
2929  break;
2930  }
2931  Assert (false, ExcInternalError());
2932 }
2933 
2934 
2935 
2936 template <int dim, int spacedim>
2937 std::string
2939 {
2940  switch (format)
2941  {
2942  case dbmesh:
2943  return ".dbmesh";
2944  case msh:
2945  return ".msh";
2946  case vtk:
2947  return ".vtk";
2948  case unv:
2949  return ".unv";
2950  case ucd:
2951  return ".inp";
2952  case abaqus:
2953  return ".inp"; // Typical suffix for Abaqus mesh files conflicts with UCD.
2954  case xda:
2955  return ".xda";
2956  case netcdf:
2957  return ".nc";
2958  case tecplot:
2959  return ".dat";
2960  default:
2961  Assert (false, ExcNotImplemented());
2962  return ".unknown_format";
2963  }
2964 }
2965 
2966 
2967 
2968 template <int dim, int spacedim>
2970 GridIn<dim, spacedim>::parse_format (const std::string &format_name)
2971 {
2972  if (format_name == "dbmesh")
2973  return dbmesh;
2974 
2975  if (format_name == "msh")
2976  return msh;
2977 
2978  if (format_name == "unv")
2979  return unv;
2980 
2981  if (format_name == "vtk")
2982  return vtk;
2983 
2984  // This is also the typical extension of Abaqus input files.
2985  if (format_name == "inp")
2986  return ucd;
2987 
2988  if (format_name == "ucd")
2989  return ucd;
2990 
2991  if (format_name == "xda")
2992  return xda;
2993 
2994  if (format_name == "netcdf")
2995  return netcdf;
2996 
2997  if (format_name == "nc")
2998  return netcdf;
2999 
3000  if (format_name == "tecplot")
3001  return tecplot;
3002 
3003  if (format_name == "dat")
3004  return tecplot;
3005 
3006  if (format_name == "plt")
3007  // Actually, this is the extension for the
3008  // tecplot binary format, which we do not
3009  // support right now. However, some people
3010  // tend to create tecplot ascii files with
3011  // the extension 'plt' instead of
3012  // 'dat'. Thus, include this extension
3013  // here. If it actually is a binary file,
3014  // the read_tecplot() function will fail
3015  // and throw an exception, anyway.
3016  return tecplot;
3017 
3018  AssertThrow (false, ExcInvalidState ());
3019  // return something weird
3020  return Format(Default);
3021 }
3022 
3023 
3024 
3025 template <int dim, int spacedim>
3027 {
3028  return "dbmesh|msh|unv|vtk|ucd|abaqus|xda|netcdf|tecplot|assimp";
3029 }
3030 
3031 namespace
3032 {
3033  template <int dim>
3034  Abaqus_to_UCD<dim>::Abaqus_to_UCD ()
3035  : tolerance (5e-16) // Used to offset Cubit tolerance error when outputting value close to zero
3036  {
3037  AssertThrow(dim==2 || dim==3, ExcNotImplemented());
3038  }
3039 
3040  // Convert from a string to some other data type
3041  // Reference: http://www.codeguru.com/forum/showthread.php?t=231054
3042  template <class T> bool
3043  from_string (T &t,
3044  const std::string &s,
3045  std::ios_base& (*f) (std::ios_base &))
3046  {
3047  std::istringstream iss (s);
3048  return ! (iss >> f >> t).fail();
3049  }
3050 
3051  // Extract an integer from a string
3052  int
3053  extract_int (const std::string &s)
3054  {
3055  std::string tmp;
3056  for (unsigned int i = 0; i<s.size(); ++i)
3057  {
3058  if (isdigit(s[i]))
3059  {
3060  tmp += s[i];
3061  }
3062  }
3063 
3064  int number = 0;
3065  from_string(number, tmp, std::dec);
3066  return number;
3067  }
3068 
3069  template <int dim>
3070  void
3071  Abaqus_to_UCD<dim>::read_in_abaqus (std::istream &input_stream)
3072  {
3073  // References:
3074  // http://www.egr.msu.edu/software/abaqus/Documentation/docs/v6.7/books/usb/default.htm?startat=pt01ch02.html
3075  // http://www.cprogramming.com/tutorial/string.html
3076 
3077  AssertThrow (input_stream, ExcIO());
3078  std::string line;
3079  std::getline (input_stream, line);
3080 
3081  while (!input_stream.fail() && !input_stream.eof())
3082  {
3083  std::transform(line.begin(), line.end(), line.begin(), ::toupper);
3084 
3085  if (line.compare ("*HEADING") == 0 ||
3086  line.compare (0, 2, "**") == 0 ||
3087  line.compare (0, 5, "*PART") == 0)
3088  {
3089  // Skip header and comments
3090  while (!input_stream.fail() && !input_stream.eof())
3091  {
3092  std::getline (input_stream, line);
3093  if (line[0] == '*')
3094  goto cont; // My eyes, they burn!
3095  }
3096  }
3097  else if (line.compare (0, 5, "*NODE") == 0)
3098  {
3099  // Extract list of vertices
3100  // Header line might be:
3101  // *NODE, NSET=ALLNODES
3102  // *NODE
3103 
3104  // Contains lines in the form:
3105  // Index, x, y, z
3106  while (!input_stream.fail() && !input_stream.eof())
3107  {
3108  std::getline (input_stream, line);
3109  if (line[0] == '*')
3110  goto cont;
3111 
3112  std::vector <double> node (dim+1);
3113 
3114  std::istringstream iss (line);
3115  char comma;
3116  for (unsigned int i = 0; i < dim+1; ++i)
3117  iss >> node[i] >> comma;
3118 
3119  node_list.push_back (node);
3120  }
3121  }
3122  else if (line.compare (0, 8, "*ELEMENT") == 0)
3123  {
3124  // Element construction.
3125  // There are different header formats, the details
3126  // of which we're not particularly interested in except
3127  // whether they represent quads or hexahedrals.
3128  // *ELEMENT, TYPE=S4R, ELSET=EB<material id>
3129  // *ELEMENT, TYPE=C3D8R, ELSET=EB<material id>
3130  // *ELEMENT, TYPE=C3D8
3131  // Elements itself (n=4 or n=8):
3132  // Index, i[0], ..., i[n]
3133 
3134  int material = 0;
3135  // Scan for material id
3136  {
3137  const std::string before_material = "ELSET=EB";
3138  const std::size_t idx = line.find (before_material);
3139  if (idx != std::string::npos)
3140  {
3141  from_string (material, line.substr (idx + before_material.size()), std::dec);
3142  }
3143  }
3144 
3145  // Read ELEMENT definition
3146  std::getline (input_stream, line);
3147  while (!input_stream.fail() && !input_stream.eof())
3148  {
3149  if (line[0] == '*')
3150  goto cont;
3151 
3152  std::istringstream iss (line);
3153  char comma;
3154 
3155  // We will store the material id in the zeroth entry of the
3156  // vector and the rest of the elements represent the global
3157  // node numbers
3158  const unsigned int n_data_per_cell = 1+GeometryInfo<dim>::vertices_per_cell;
3159  std::vector <double> cell (n_data_per_cell);
3160  for (unsigned int i = 0; i < n_data_per_cell; ++i)
3161  iss >> cell[i] >> comma;
3162 
3163  // Overwrite cell index from file by material
3164  cell[0] = static_cast<double> (material);
3165  cell_list.push_back (cell);
3166 
3167  std::getline (input_stream, line);
3168  }
3169  }
3170  else if (line.compare (0, 8, "*SURFACE") == 0)
3171  {
3172  // Extract the definitions of boundary surfaces
3173  // Old format from Cubit:
3174  // *SURFACE, NAME=SS<boundary indicator>
3175  // <element index>, S<face number>
3176  // Abaqus default format:
3177  // *SURFACE, TYPE=ELEMENT, NAME=SURF-<indicator>
3178 
3179  // Get name of the surface and extract id from it;
3180  // this will be the boundary indicator
3181  const std::string name_key = "NAME=";
3182  const std::size_t name_idx_start = line.find(name_key) + name_key.size();
3183  std::size_t name_idx_end = line.find(',', name_idx_start);
3184  if (name_idx_end == std::string::npos)
3185  {
3186  name_idx_end = line.size();
3187  }
3188  const int b_indicator = extract_int(line.substr(name_idx_start, name_idx_end - name_idx_start));
3189 
3190  // Read SURFACE definition
3191  // Note that the orientation of the faces is embedded within the
3192  // definition of each "set" of faces that comprise the surface
3193  // These are either marked by an "S" or "E" in 3d or 2d respectively.
3194  std::getline (input_stream, line);
3195  while (!input_stream.fail() && !input_stream.eof())
3196  {
3197  if (line[0] == '*')
3198  goto cont;
3199 
3200  // Change all characters to upper case
3201  std::transform(line.begin(), line.end(), line.begin(), ::toupper);
3202 
3203  // Surface can be created from ELSET, or directly from cells
3204  // If elsets_list contains a key with specific name - refers to that ELSET, otherwise refers to cell
3205  std::istringstream iss (line);
3206  int el_idx;
3207  int face_number;
3208  char temp;
3209 
3210  // Get relevant faces, taking into account the element orientation
3211  std::vector <double> quad_node_list;
3212  const std::string elset_name = line.substr(0, line.find(','));
3213  if (elsets_list.count(elset_name) != 0)
3214  {
3215  // Surface refers to ELSET
3216  std::string stmp;
3217  iss >> stmp >> temp >> face_number;
3218 
3219  const std::vector<int> cells = elsets_list[elset_name];
3220  for (unsigned int i = 0; i <cells.size(); ++i)
3221  {
3222  el_idx = cells[i];
3223  quad_node_list = get_global_node_numbers (el_idx, face_number);
3224  quad_node_list.insert (quad_node_list.begin(), b_indicator);
3225 
3226  face_list.push_back (quad_node_list);
3227  }
3228  }
3229  else
3230  {
3231  // Surface refers directly to elements
3232  char comma;
3233  iss >> el_idx >> comma >> temp >> face_number;
3234  quad_node_list = get_global_node_numbers (el_idx, face_number);
3235  quad_node_list.insert (quad_node_list.begin(), b_indicator);
3236 
3237  face_list.push_back (quad_node_list);
3238  }
3239 
3240  std::getline (input_stream, line);
3241  }
3242  }
3243  else if (line.compare (0, 6, "*ELSET") == 0)
3244  {
3245  // Get ELSET name.
3246  // Materials are attached to elsets with specific name
3247  std::string elset_name;
3248  {
3249  const std::string elset_key = "*ELSET, ELSET=";
3250  const std::size_t idx = line.find(elset_key);
3251  if (idx != std::string::npos)
3252  {
3253  const std::string comma = ",";
3254  const std::size_t first_comma = line.find(comma);
3255  const std::size_t second_comma = line.find(comma, first_comma+1);
3256  const std::size_t elset_name_start = line.find(elset_key) + elset_key.size();
3257  elset_name = line.substr(elset_name_start, second_comma-elset_name_start);
3258  }
3259 
3260  }
3261 
3262  // There are two possibilities of storing cells numbers in ELSET:
3263  // 1. If the header contains the 'GENERATE' keyword, then the next line describes range of cells as:
3264  // cell_id_start, cell_id_end, cell_step
3265  // 2. If the header does not contain the 'GENERATE' keyword, then the next lines contain cells numbers
3266  std::vector<int> elements;
3267  const std::size_t generate_idx = line.find("GENERATE");
3268  if (generate_idx != std::string::npos)
3269  {
3270  // Option (1)
3271  std::getline (input_stream, line);
3272  std::istringstream iss (line);
3273  char comma;
3274  int elid_start;
3275  int elid_end;
3276  int elis_step = 1; // Default value set in case stride not provided
3277  // Some files don't have the stride size
3278  // Compare mesh test cases ./grids/abaqus/3d/other_simple.inp to ./grids/abaqus/2d/2d_test_abaqus.inp
3279  iss >> elid_start >> comma >> elid_end;
3280  // https://stackoverflow.com/questions/8046357/how-do-i-check-if-a-stringstream-variable-is-empty-null
3281  if (iss.rdbuf()->in_avail() != 0)
3282  iss >> comma >> elis_step;
3283  for (int i = elid_start; i <= elid_end; i+= elis_step)
3284  {
3285  elements.push_back(i);
3286  }
3287  elsets_list[elset_name] = elements;
3288 
3289  std::getline (input_stream, line);
3290  }
3291  else
3292  {
3293  // Option (2)
3294  std::getline (input_stream, line);
3295  while (!input_stream.fail() && !input_stream.eof())
3296  {
3297  if (line[0] == '*')
3298  break;
3299 
3300  std::istringstream iss (line);
3301  char comma;
3302  int elid;
3303  while (!iss.eof())
3304  {
3305  iss >> elid >> comma;
3306  elements.push_back (elid);
3307  }
3308 
3309  std::getline (input_stream, line);
3310  }
3311 
3312  elsets_list[elset_name] = elements;
3313  }
3314 
3315  goto cont;
3316  }
3317  else if (line.compare (0, 5, "*NSET") == 0)
3318  {
3319  // Skip nodesets; we have no use for them
3320  while (!input_stream.fail() && !input_stream.eof())
3321  {
3322  std::getline (input_stream, line);
3323  if (line[0] == '*')
3324  goto cont;
3325  }
3326  }
3327  else if (line.compare(0, 14, "*SOLID SECTION") == 0)
3328  {
3329  // The ELSET name, which describes a section for particular material
3330  const std::string elset_key = "ELSET=";
3331  const std::size_t elset_start = line.find("ELSET=") + elset_key.size();
3332  const std::size_t elset_end = line.find(',', elset_start+1);
3333  const std::string elset_name = line.substr(elset_start, elset_end-elset_start);
3334 
3335  // Solid material definition.
3336  // We assume that material id is taken from material name,
3337  // eg. "Material-1" -> ID=1
3338  const std::string material_key = "MATERIAL=";
3339  const std::size_t last_equal = line.find("MATERIAL=") + material_key.size();
3340  const std::size_t material_id_start = line.find('-', last_equal);
3341  int material_id = 0;
3342  from_string(material_id, line.substr(material_id_start+1), std::dec);
3343 
3344  // Assign material id to cells
3345  const std::vector<int> &elset_cells = elsets_list[elset_name];
3346  for (unsigned int i = 0; i < elset_cells.size(); ++i)
3347  {
3348  const int cell_id = elset_cells[i] - 1;
3349  cell_list[cell_id][0] = material_id;
3350  }
3351  }
3352  // Note: All other lines / entries are ignored
3353 
3354  std::getline (input_stream, line);
3355 
3356 cont:
3357  (void) 0;
3358  }
3359  }
3360 
3361  template <int dim>
3362  std::vector<double>
3363  Abaqus_to_UCD<dim>::get_global_node_numbers (const int face_cell_no,
3364  const int face_cell_face_no) const
3365  {
3366  std::vector<double> quad_node_list (GeometryInfo<dim>::vertices_per_face);
3367 
3368  // These orderings were reverse engineered by hand and may
3369  // conceivably be erroneous.
3370  // TODO: Currently one test (2d unstructured mesh) in the test
3371  // suite fails, presumably because of an ordering issue.
3372  if (dim == 2)
3373  {
3374  if (face_cell_face_no == 1)
3375  {
3376  quad_node_list[0] = cell_list[face_cell_no - 1][1];
3377  quad_node_list[1] = cell_list[face_cell_no - 1][2];
3378  }
3379  else if (face_cell_face_no == 2)
3380  {
3381  quad_node_list[0] = cell_list[face_cell_no - 1][2];
3382  quad_node_list[1] = cell_list[face_cell_no - 1][3];
3383  }
3384  else if (face_cell_face_no == 3)
3385  {
3386  quad_node_list[0] = cell_list[face_cell_no - 1][3];
3387  quad_node_list[1] = cell_list[face_cell_no - 1][4];
3388  }
3389  else if (face_cell_face_no == 4)
3390  {
3391  quad_node_list[0] = cell_list[face_cell_no - 1][4];
3392  quad_node_list[1] = cell_list[face_cell_no - 1][1];
3393  }
3394  else
3395  {
3396  AssertThrow(face_cell_face_no <= 4, ExcMessage("Invalid face number in 2d"));
3397  }
3398  }
3399  else if (dim == 3)
3400  {
3401  if (face_cell_face_no == 1)
3402  {
3403  quad_node_list[0] = cell_list[face_cell_no - 1][1];
3404  quad_node_list[1] = cell_list[face_cell_no - 1][4];
3405  quad_node_list[2] = cell_list[face_cell_no - 1][3];
3406  quad_node_list[3] = cell_list[face_cell_no - 1][2];
3407  }
3408  else if (face_cell_face_no == 2)
3409  {
3410  quad_node_list[0] = cell_list[face_cell_no - 1][5];
3411  quad_node_list[1] = cell_list[face_cell_no - 1][8];
3412  quad_node_list[2] = cell_list[face_cell_no - 1][7];
3413  quad_node_list[3] = cell_list[face_cell_no - 1][6];
3414  }
3415  else if (face_cell_face_no == 3)
3416  {
3417  quad_node_list[0] = cell_list[face_cell_no - 1][1];
3418  quad_node_list[1] = cell_list[face_cell_no - 1][2];
3419  quad_node_list[2] = cell_list[face_cell_no - 1][6];
3420  quad_node_list[3] = cell_list[face_cell_no - 1][5];
3421  }
3422  else if (face_cell_face_no == 4)
3423  {
3424  quad_node_list[0] = cell_list[face_cell_no - 1][2];
3425  quad_node_list[1] = cell_list[face_cell_no - 1][3];
3426  quad_node_list[2] = cell_list[face_cell_no - 1][7];
3427  quad_node_list[3] = cell_list[face_cell_no - 1][6];
3428  }
3429  else if (face_cell_face_no == 5)
3430  {
3431  quad_node_list[0] = cell_list[face_cell_no - 1][3];
3432  quad_node_list[1] = cell_list[face_cell_no - 1][4];
3433  quad_node_list[2] = cell_list[face_cell_no - 1][8];
3434  quad_node_list[3] = cell_list[face_cell_no - 1][7];
3435  }
3436  else if (face_cell_face_no == 6)
3437  {
3438  quad_node_list[0] = cell_list[face_cell_no - 1][1];
3439  quad_node_list[1] = cell_list[face_cell_no - 1][5];
3440  quad_node_list[2] = cell_list[face_cell_no - 1][8];
3441  quad_node_list[3] = cell_list[face_cell_no - 1][4];
3442  }
3443  else
3444  {
3445  AssertThrow(face_cell_no <= 6, ExcMessage("Invalid face number in 3d"));
3446  }
3447  }
3448  else
3449  {
3450  AssertThrow(dim==2 || dim==3, ExcNotImplemented());
3451  }
3452 
3453  return quad_node_list;
3454  }
3455 
3456  template <int dim>
3457  void
3458  Abaqus_to_UCD<dim>::write_out_avs_ucd (std::ostream &output) const
3459  {
3460  // References:
3461  // http://www.dealii.org/developer/doxygen/deal.II/structGeometryInfo.html
3462  // http://people.scs.fsu.edu/~burkardt/data/ucd/ucd.html
3463 
3464  AssertThrow (output, ExcIO());
3465 
3466  // save old formatting options
3467  const boost::io::ios_base_all_saver formatting_saver(output);
3468 
3469  // Write out title - Note: No other commented text can be inserted below the
3470  // title in a UCD file
3471  output << "# Abaqus to UCD mesh conversion" << std::endl;
3472  output << "# Mesh type: AVS UCD" << std::endl;
3473 
3474  // ========================================================
3475  // ASCII UCD File Format
3476  // The input file cannot contain blank lines or lines with leading blanks.
3477  // Comments, if present, must precede all data in the file.
3478  // Comments within the data will cause read errors.
3479  // The general order of the data is as follows:
3480  // 1. Numbers defining the overall structure, including the number of nodes,
3481  // the number of cells, and the length of the vector of data associated
3482  // with the nodes, cells, and the model.
3483  // e.g. 1:
3484  // <num_nodes> <num_cells> <num_ndata> <num_cdata> <num_mdata>
3485  // e.g. 2:
3486  // n_elements = n_hex_cells + n_bc_quads + n_quad_cells + n_bc_edges
3487  // outfile.write(str(n_nodes) + " " + str(n_elements) + " 0 0 0\n")
3488  // 2. For each node, its node id and the coordinates of that node in space.
3489  // Node-ids must be integers, but any number including non sequential
3490  // numbers can be used. Mid-edge nodes are treated like any other node.
3491  // 3. For each cell: its cell-id, material, cell type (hexahedral, pyramid,
3492  // etc.), and the list of node-ids that correspond to each of the cell's
3493  // vertices. The below table specifies the different cell types and the
3494  // keyword used to represent them in the file.
3495 
3496  // Write out header
3497  output << node_list.size() << "\t"
3498  << (cell_list.size() + face_list.size()) << "\t0\t0\t0"
3499  << std::endl;
3500 
3501  output.width (16);
3502  output.precision (8);
3503 
3504  // Write out node numbers
3505  // Loop over all nodes
3506  for (unsigned int ii = 0; ii < node_list.size(); ++ii)
3507  {
3508  // Node number
3509  output << node_list[ii][0] << "\t";
3510 
3511  // Node coordinates
3512  output.setf (std::ios::scientific, std::ios::floatfield);
3513  for (unsigned int jj = 1; jj < dim + 1; ++jj)
3514  {
3515  // invoke tolerance -> set points close to zero equal to zero
3516  if (std::abs (node_list[ii][jj]) > tolerance)
3517  output << static_cast<double> (node_list[ii][jj]) << "\t";
3518  else
3519  output << 0.0 << "\t";
3520  }
3521  if (dim == 2)
3522  output << 0.0 << "\t";
3523 
3524  output << std::endl;
3525  output.unsetf (std::ios::floatfield);
3526  }
3527 
3528  // Write out cell node numbers
3529  for (unsigned int ii = 0; ii < cell_list.size(); ++ii)
3530  {
3531  output << ii + 1 << "\t"
3532  << cell_list[ii][0] << "\t"
3533  << (dim == 2 ? "quad" : "hex") << "\t";
3534  for (unsigned int jj = 1; jj < GeometryInfo<dim>::vertices_per_cell + 1; ++jj)
3535  output << cell_list[ii][jj] << "\t";
3536 
3537  output << std::endl;
3538  }
3539 
3540  // Write out quad node numbers
3541  for (unsigned int ii = 0; ii < face_list.size(); ++ii)
3542  {
3543  output
3544  << ii + 1 << "\t"
3545  << face_list[ii][0] << "\t"
3546  << (dim == 2 ? "line" : "quad") << "\t";
3547  for (unsigned int jj = 1; jj < GeometryInfo<dim>::vertices_per_face + 1; ++jj)
3548  output << face_list[ii][jj] << "\t";
3549 
3550  output << std::endl;
3551  }
3552  }
3553 }
3554 
3555 
3556 //explicit instantiations
3557 #include "grid_in.inst"
3558 
3559 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
Definition: tria.h:249
static std::string get_format_names()
Definition: grid_in.cc:3026
static const unsigned int invalid_unsigned_int
Definition: types.h:173
static ::ExceptionBase & ExcNoTriangulationSelected()
void delete_duplicated_vertices(std::vector< Point< spacedim > > &all_vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata, std::vector< unsigned int > &considered_vertices, const double tol=1e-12)
Definition: grid_tools.cc:491
static ::ExceptionBase & ExcIO()
unsigned int boundary_id
Definition: types.h:110
Format
Definition: grid_in.h:307
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
Definition: utilities.cc:432
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
Definition: utilities.cc:339
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2, int arg3)
unsigned int material_id
Definition: types.h:133
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static Format parse_format(const std::string &format_name)
Definition: grid_in.cc:2970
static void skip_empty_lines(std::istream &in)
Definition: grid_in.cc:2636
void read_vtk(std::istream &in)
Definition: grid_in.cc:106
void read_dbmesh(std::istream &in)
Definition: grid_in.cc:908
void read_tecplot(std::istream &in)
Definition: grid_in.cc:2475
static ::ExceptionBase & ExcInvalidState()
static ::ExceptionBase & ExcMessage(std::string arg1)
bool check_consistency(const unsigned int dim) const
Definition: tria.cc:47
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static void parse_tecplot_header(std::string &header, std::vector< unsigned int > &tecplot2deal, unsigned int &n_vars, unsigned int &n_vertices, unsigned int &n_cells, std::vector< unsigned int > &IJK, bool &structured, bool &blocked)
Definition: grid_in.cc:2041
static ::ExceptionBase & ExcNeedsNetCDF()
#define Assert(cond, exc)
Definition: exceptions.h:1142
static void invert_all_cells_of_negative_grid(const std::vector< Point< spacedim > > &all_vertices, std::vector< CellData< dim > > &original_cells)
static void skip_comment_lines(std::istream &in, const char comment_start)
Definition: grid_in.cc:2665
bool match_at_string_start(const std::string &name, const std::string &pattern)
Definition: utilities.cc:416
void read_ucd(std::istream &in, const bool apply_all_indicators_to_manifolds=false)
Definition: grid_in.cc:629
static ::ExceptionBase & ExcNeedsAssimp()
GridIn()
Definition: grid_in.cc:92
static void reorder_cells(std::vector< CellData< dim > > &original_cells, const bool use_new_style_ordering=false)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:98
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::string find(const std::string &filename, const char *open_mode="r")
Definition: path_search.cc:172
void read_xda(std::istream &in)
Definition: grid_in.cc:1074
void read_msh(std::istream &in)
Definition: grid_in.cc:1232
unsigned int manifold_id
Definition: types.h:122
std::vector< CellData< 2 > > boundary_quads
Definition: tria.h:257
void read_netcdf(const std::string &filename)
static std::string default_suffix(const Format format)
Definition: grid_in.cc:2938
void read_unv(std::istream &in)
Definition: grid_in.cc:393
void delete_unused_vertices(std::vector< Point< spacedim > > &vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata)
Definition: grid_tools.cc:395
void read(std::istream &in, Format format=Default)
Definition: grid_in.cc:2876
static ::ExceptionBase & ExcNotImplemented()
const types::boundary_id internal_face_boundary_id
Definition: types.h:219
void read_assimp(const std::string &filename, const unsigned int mesh_index=numbers::invalid_unsigned_int, const bool remove_duplicates=true, const double tol=1e-12, const bool ignore_unsupported_element_types=true)
Definition: grid_in.cc:2483
void read_abaqus(std::istream &in, const bool apply_all_indicators_to_manifolds=false)
Definition: grid_in.cc:863
static void debug_output_grid(const std::vector< CellData< dim > > &cells, const std::vector< Point< spacedim > > &vertices, std::ostream &out)
Definition: grid_in.cc:2690
const types::material_id invalid_material_id
Definition: types.h:194
void attach_triangulation(Triangulation< dim, spacedim > &tria)
Definition: grid_in.cc:98
static ::ExceptionBase & ExcInternalError()