Hermes2D  3.0
mesh_reader_h1d_xml.cpp
1 // This file is part of Hermes2D
2 //
3 // Hermes2D is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D; if not, see <http://www.gnu.prg/licenses/>.
15 
16 #include "mesh.h"
17 #include "mesh_reader_h1d_xml.h"
18 
19 using namespace std;
20 
21 namespace Hermes
22 {
23  namespace Hermes2D
24  {
25  MeshReaderH1DXML::MeshReaderH1DXML()
26  {
27  }
28 
29  MeshReaderH1DXML::~MeshReaderH1DXML()
30  {
31  }
32 
33  void MeshReaderH1DXML::load(const char *filename, MeshSharedPtr mesh)
34  {
35  mesh->free();
36 
37  try
38  {
39  ::xml_schema::flags parsing_flags = 0;
40  if (!this->validate)
41  parsing_flags = xml_schema::flags::dont_validate;
42 
43  std::auto_ptr<XMLMesh1D::mesh> parsed_xml_mesh(XMLMesh1D::mesh_(filename, parsing_flags));
44 
45  // Variables //
46  unsigned int variables_count = parsed_xml_mesh->variables().present() ? parsed_xml_mesh->variables()->var().size() : 0;
47  std::map<std::string, double> variables;
48  for (unsigned int variables_i = 0; variables_i < variables_count; variables_i++)
49 #ifdef _MSC_VER
50  variables.insert(std::pair<std::string, double>((std::string)parsed_xml_mesh->variables()->var().at(variables_i).name(), (double&&)parsed_xml_mesh->variables()->var().at(variables_i).value()));
51 #else
52  variables.insert(std::pair<std::string, double>((std::string)parsed_xml_mesh->variables()->var().at(variables_i).name(), parsed_xml_mesh->variables()->var().at(variables_i).value()));
53 #endif
54 
55  // Vertices //
56  int vertices_count = parsed_xml_mesh->v().size();
57 
58  // Initialize mesh.
59  int size = HashTable::H2D_DEFAULT_HASH_SIZE;
60  while (size < 8 * vertices_count)
61  size *= 2;
62  mesh->init(size);
63 
64  double a = std::numeric_limits<double>::infinity();
65  double b = -std::numeric_limits<double>::infinity();
66 
67  // Create top-level vertex nodes.
68  for (int vertices_i = 0; vertices_i < 2 * vertices_count; vertices_i++)
69  {
70  Node* node = mesh->nodes.add();
71  assert(node->id == vertices_i);
72  node->ref = TOP_LEVEL_REF;
73  node->type = HERMES_TYPE_VERTEX;
74  node->bnd = 0;
75  node->p1 = node->p2 = -1;
76  node->next_hash = nullptr;
77 
78  // variables matching.
79  std::string x = parsed_xml_mesh->v().at(vertices_i % vertices_count).x();
80  double x_value;
81 
82  // variables lookup.
83  bool x_found = false;
84  if (variables.find(x) != variables.end())
85  {
86  x_value = variables.find(x)->second;
87  x_found = true;
88  }
89 
90  // test of value if no variable found.
91  if (!x_found)
92  if (std::strtod(x.c_str(), nullptr) != 0.0)
93  x_value = std::strtod(x.c_str(), nullptr);
94  else
95  {
96  // This is a hard part, to find out if it is really zero.
97  int dot_position = strchr(x.c_str(), '.') == nullptr ? -1 : strchr(x.c_str(), '.') - x.c_str();
98  for (int i = 0; i < dot_position; i++)
99  if (strncmp(x.c_str() + i, "0", 1) != 0)
100  this->warn("Probably wrong syntax in the x coordinate of vertex no. %i.", vertices_i % vertices_count + 1);
101  for (int i = dot_position + 1; i < x.length(); i++)
102  if (strncmp(x.c_str() + i, "0", 1) != 0)
103  this->warn("Probably wrong syntax in the x coordinate of vertex no. %i.", vertices_i % vertices_count + 1);
104  x_value = std::strtod(x.c_str(), nullptr);
105  }
106 
107  // assignment.
108  node->x = x_value;
109  if (x_value > b)
110  b = x_value;
111  if (x_value < a)
112  a = x_value;
113 
114  if (vertices_i < vertices_count)
115  node->y = 0;
116  else
117  node->y = 1;
118  }
119  mesh->ntopvert = 2 * vertices_count;
120 
121  Node* node;
122  for_all_nodes(node, mesh)
123  if (node->y == 0)
124  node->y = 0;
125  else
126  node->y = (b - a) / 100;
127 
128  // Elements //
129  mesh->nbase = mesh->nactive = mesh->ninitial = vertices_count - 1;
130 
131  Element* e;
132  for (int element_i = 0; element_i < vertices_count - 1; element_i++)
133  {
134  mesh->element_markers_conversion.insert_marker("H1DMarker");
135 
136  int element_marker;
137  if (parsed_xml_mesh->v().at(element_i % vertices_count).m().present())
138  {
139  mesh->element_markers_conversion.insert_marker(parsed_xml_mesh->v().at(element_i % vertices_count).m().get());
140  element_marker = mesh->element_markers_conversion.get_internal_marker(parsed_xml_mesh->v().at(element_i % vertices_count).m().get()).marker;
141  }
142  else
143  element_marker = mesh->element_markers_conversion.get_internal_marker("H1DMarker").marker;
144 
145  e = mesh->create_quad(element_marker,
146  &mesh->nodes[element_i],
147  &mesh->nodes[element_i + 1],
148  &mesh->nodes[element_i + vertices_count + 1],
149  &mesh->nodes[element_i + vertices_count],
150  nullptr);
151 
152  mesh->boundary_markers_conversion.insert_marker("Unused");
153 
154  node = mesh->peek_edge_node(element_i, element_i + 1);
155  node->bnd = 1;
156  node->marker = mesh->boundary_markers_conversion.get_internal_marker("Unused").marker;
157  mesh->nodes[element_i].bnd = 1;
158  mesh->nodes[element_i + 1].bnd = 1;
159 
160  node = mesh->peek_edge_node(vertices_count + element_i, vertices_count + element_i + 1);
161  node->bnd = 1;
162  node->marker = mesh->boundary_markers_conversion.get_internal_marker("Unused").marker;
163  mesh->nodes[vertices_count + element_i].bnd = 1;
164  mesh->nodes[vertices_count + element_i + 1].bnd = 1;
165  }
166 
167  // Boundaries //
168  Node* en;
169  int v1_1 = 0;
170  int v2_1 = vertices_count;
171  int v1_2 = vertices_count - 1;
172  int v2_2 = 2 * vertices_count - 1;
173 
174  en = mesh->peek_edge_node(v1_1, v2_1);
175  // This functions check if the user-supplied marker on this element has been
176  // already used, and if not, inserts it in the appropriate structure.
177  mesh->boundary_markers_conversion.insert_marker("Left");
178  int marker = mesh->boundary_markers_conversion.get_internal_marker("Left").marker;
179  en->marker = marker;
180  en->bnd = 1;
181 
182  en = mesh->peek_edge_node(v1_2, v2_2);
183  // This functions check if the user-supplied marker on this element has been
184  // already used, and if not, inserts it in the appropriate structure.
185  mesh->boundary_markers_conversion.insert_marker("Right");
186  marker = mesh->boundary_markers_conversion.get_internal_marker("Right").marker;
187  en->marker = marker;
188  en->bnd = 1;
189 
190  mesh->nodes[v1_1].bnd = 1;
191  mesh->nodes[v2_1].bnd = 1;
192 
193  mesh->nodes[v1_2].bnd = 1;
194  mesh->nodes[v2_2].bnd = 1;
195  }
196  catch (const xml_schema::exception& e)
197  {
198  throw Hermes::Exceptions::MeshLoadFailureException(e.what());
199  }
200  }
201 
202  void MeshReaderH1DXML::save(const char *filename, MeshSharedPtr mesh)
203  {
205  }
206  }
207 }
double x
vertex node coordinates
Definition: element.h:63
unsigned type
0 = vertex node; 1 = edge node
Definition: element.h:52
int id
node id number
Definition: element.h:48
Definition: adapt.h:24
int marker
element marker
Definition: element.h:144
Node * next_hash
next node in hash synonym list
Definition: element.h:77
::xsd::cxx::tree::flags flags
Parsing and serialization flags.
Stores one element of a mesh.
Definition: element.h:107
::xsd::cxx::tree::exception< char > exception
Root of the C++/Tree exception hierarchy.
Stores one node of a mesh.
Definition: element.h:45
::std::auto_ptr< ::XMLMesh1D::mesh > mesh_(const ::std::string &uri,::xml_schema::flags f=0, const ::xml_schema::properties &p=::xml_schema::properties())
Parse a URI or a local file.
int p1
parent id numbers
Definition: element.h:75
unsigned bnd
1 = boundary node; 0 = inner node
Definition: element.h:54
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
unsigned ref
the number of elements using the node
Definition: element.h:50
int marker
edge marker
Definition: element.h:68