COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
Reader.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
7 #include <boost/foreach.hpp>
8 #include <boost/tokenizer.hpp>
9 
10 #include "common/Log.hpp"
11 #include "common/Builder.hpp"
13 #include "common/OptionList.hpp"
14 #include "common/OptionT.hpp"
15 #include "common/PropertyList.hpp"
16 #include "common/StreamHelpers.hpp"
18 #include "common/Table.hpp"
19 #include "common/List.hpp"
20 #include "common/DynTable.hpp"
21 
22 #include "common/PE/debug.hpp"
23 
24 #include "mesh/Region.hpp"
25 #include "mesh/Mesh.hpp"
26 #include "mesh/Dictionary.hpp"
28 #include "mesh/MeshElements.hpp"
32 #include "mesh/Field.hpp"
33 #include "mesh/Space.hpp"
34 #include "mesh/Cells.hpp"
35 #include "smurf/smurf.h"
36 
37 #include "mesh/smurf/Reader.hpp"
38 
39 
41 
42 namespace cf3 {
43 namespace mesh {
44 namespace smurf {
45 
46  using namespace common;
47 
49 
51 
53 
54 Reader::Reader( const std::string& name )
55 : MeshReader(name),
56  Shared()
57 {
58 
59  // options
60 // options().add("part", PE::Comm::instance().rank() )
61 // .description("Number of the part of the mesh to read. (e.g. rank of processor)")
62 // .pretty_name("Part");
63 
64 // options().add("nb_parts", PE::Comm::instance().size() )
65 // .description("Total number of parts. (e.g. number of processors)")
66 // .pretty_name("nb_parts");
67 
68  options().add("read_fields", true)
69  .description("Read the data from the mesh")
70  .pretty_name("Read Fields")
71  .mark_basic();
72 
73  // properties
74 
75  properties()["brief"] = std::string("Smurf file reader component");
76 
77 // std::string desc;
78 // desc += "This component can read in parallel.\n";
79 // desc += "It can also read multiple files in serial, combining them in one large mesh.\n";
80 // desc += "Available coolfluid-element types are:\n";
81 // boost_foreach(const std::string& supported_type, m_supported_types)
82 // desc += " - " + supported_type + "\n";
83 // properties()["description"] = desc;
84 
85  IO_rank = 0;
86 }
87 
89 
90 std::vector<std::string> Reader::get_extensions()
91 {
92  std::vector<std::string> extensions;
93  extensions.push_back(".smurf");
94  return extensions;
95 }
96 
98 
100 {
101 
102  // if the file is present open it
103  boost::filesystem::path fp (file.path());
104  if(!boost::filesystem::exists(fp))
105  throw boost::filesystem::filesystem_error( fp.string() + " does not exist", boost::system::error_code() );
106 
107  m_file_basename = boost::filesystem::basename(fp);
108 
109  // set the internal mesh pointer
110  m_mesh = Handle<Mesh>(mesh.handle<Component>());
111 
112  // Create a region component inside the mesh with a generic mesh name
113  // NOTE: since gmsh contains several 'physical entities' in one mesh, we create one region per physical entity
114  m_region = Handle<Region>(m_mesh->topology().handle<Component>());
115 
116  CFinfo << "smurf: opening file " << fp.string() << CFendl;
117  SmURF::MeshReader mreader(fp.string());
118 
119  std::string title_;
120  std::vector<std::string> vn_;
121 
122  // headers section
123  mreader.readMainHeader(title_,vn_);
124 
125  CFdebug << "smurf: reading mesh \"" << title_ << "\"" << CFendl;
126 
127  m_mesh_dimension = options().value<Uint>("dimension");
128  std::vector< SmURF::TecZone > zheaders = mreader.readZoneHeaders();
129 
130  // data section
131  Uint i = 0;
132  boost_foreach( SmURF::TecZone& zone, zheaders)
133  {
134  std::vector< std::vector< unsigned > > ve;
135  std::vector< std::vector< double > > dump;
136 
137  // ASSUME ALL VARIABLE DATA IS IN ZONE 1 (VARSHARELISTS!!)
138  mreader.readZoneData(zone,ve,!i?m_vv:dump);
139  if (dump.size())
140  throw NotSupported(FromHere(), "Sorry! Only binary tecplot files with varsharelists are supported (i.e. all node data should be attributed to the first zone)");
141 
142  std::string cf_elem_name;
143  // correct connectivity numbering
144  if (ve.size() && zone.type==SmURF::FELINESEG) {
145 
146  // collapse line segments to points
147  if (ve[0][0]==ve[0][1]) {
148  cf_elem_name = "cf3.mesh.LagrangeP0.Point1D";
149  for (unsigned c=0; c<ve.size(); ++c) {
150  ve[c].resize(1);
151  }
152  }
153  }
154  else if (ve.size() && zone.type==SmURF::FEBRICK) {
155 
156  if (ve[0][2]==ve[0][3] && ve[0][6]==ve[0][7]) { //*2
157 
158  // collapse an hexahedron to a prism
159  cf_elem_name = "cf3.mesh.LagrangeP1.Prism3D";
160  for (unsigned c=0; c<ve.size(); ++c) {
161  const std::vector< unsigned > ent = ve[c]; // element nodes, original (tecplot)
162  std::vector< unsigned >& eng = ve[c]; // ..., modified (gambit)
163  eng.resize(6);
164  eng[0] = ent[0];
165  eng[1] = ent[1];
166  eng[2] = ent[2];
167  eng[3] = ent[4];
168  eng[4] = ent[5];
169  eng[5] = ent[6];
170  }
171 
172  }
173  else if ((ve[0][4]==ve[0][5]) && (ve[0][4]==ve[0][6]) && (ve[0][4]==ve[0][7])) { //*3
174 
175  // collapse an hexahedron to a pyramid
176  cf_elem_name = "cf3.mesh.LagrangeP1.Pyramid3D";
177  for (unsigned c=0; c<ve.size(); ++c) {
178  const std::vector< unsigned > ent = ve[c]; // element nodes, original (tecplot)
179  std::vector< unsigned >& eng = ve[c]; // ..., modified (gambit)
180  eng.resize(5);
181  eng[0] = ent[0];
182  eng[1] = ent[1];
183  eng[2] = ent[3];
184  eng[3] = ent[2];
185  eng[4] = ent[4];
186  }
187 
188  }
189  else { //*1
190 
191  // correct node ordering for bricks
192  for (unsigned c=0; c<ve.size(); ++c) {
193  std::swap(ve[c][2],ve[c][3]);
194  std::swap(ve[c][6],ve[c][7]);
195  }
196  }
197  }
198 
199  cf_elem_name = cf_elem_name==""?Shared::tp_name_to_cf_name(m_tp_elem_dim[zone.type], zone.type):cf_elem_name;
200 
201  // Read variables
202  CFdebug << "smurf: reading zone \"" << zone.title << "\"" << CFendl
203  << " time : " << zone.time << CFendl
204  << " nodes: " << zone.i << CFendl
205  << " elems: " << zone.j << CFendl
206  << " etype: " << cf_elem_name << CFendl;
207 
209 
210  Handle<Region> region = create_region(zone.title);
211 
212  Dictionary& nodes = m_mesh->geometry_fields();
213 
214  boost::shared_ptr< ElementType > allocated_type = build_component_abstract_type<ElementType>(cf_elem_name,"tmp");
215  boost::shared_ptr< Entities > elements;
216  if (allocated_type->dimensionality() == allocated_type->dimension()-1)
217  elements = build_component_abstract_type<Entities>("cf3.mesh.Faces","elements_"+allocated_type->derived_type_name());
218  else if(allocated_type->dimensionality() == allocated_type->dimension())
219  elements = build_component_abstract_type<Entities>("cf3.mesh.Cells","elements_"+allocated_type->derived_type_name());
220  else
221  elements = build_component_abstract_type<Entities>("cf3.mesh.Elements","elements_"+allocated_type->derived_type_name());
222  region->add_component(elements);
223  elements->initialize(cf_elem_name,nodes);
224 
225  Connectivity& elem_table = Handle<Elements>(elements)->geometry_space().connectivity();
226  elem_table.set_row_size(Shared::m_nodes_in_tp_elem[zone.type]);
227  elem_table.resize(ve.size());
228  elements->rank() .resize(ve.size()); // something to do with parallel?
229  elements->glb_idx().resize(ve.size()); // something to do with parallel?
230  for (int i=0; i<ve.size(); ++i)
231  for (int j=0; j<ve[i].size(); ++j)
232  elem_table[i][j] = ve[i][j];
233  ++i;
234  }
235 
236  m_total_nb_nodes = m_vv[0].size();
237 
238  CFdebug << "smurf: nb_nodes : " << m_total_nb_nodes << CFendl
239  << " dimension: " << Shared::dim_name[m_mesh_dimension] << CFendl;
240 
242  m_mesh->initialize_nodes(m_used_nodes.size(), m_mesh_dimension);
243 
244 
245  // coordinates
246  Dictionary& nodes = m_mesh->geometry_fields();
247  nodes.resize(m_vv[0].size());
248  for (Uint dim=0; dim<m_mesh_dimension; ++dim)
249  for (Uint j=0; j<m_vv[0].size(); ++j)
250  nodes.coordinates()[j][dim] = m_vv[dim][j];
251 
252  // other fields (one field per variable)
253  for (Uint i=m_mesh_dimension; i<m_vv.size(); ++i)
254  {
255  CFdebug << " variable : " << vn_[i] <<CFendl;
256  mesh::Field& field = nodes.create_field(vn_[i]);
257  for (Uint j=0; j<m_vv[0].size(); ++j)
258  field[j][0] = m_vv[i][j];
259  }
260 
262 
263  mesh.raise_mesh_loaded(); // something to do with parallel?
264 }
265 
267 
268 Handle< Region > Reader::create_region(std::string const& relative_path)
269 {
270  typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
271  boost::char_separator<char> sep("/");
272  Tokenizer tokens(relative_path, sep);
273 
274  Handle< Region > region = m_region;
275  for (Tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
276  {
277  std::string name = *tok_iter;
278  Handle< Component > new_region = region->get_child(name);
279  if (is_null(new_region)) region->create_component<Region>(name);
280  region = Handle<Region>(region->get_child(name));
281  }
282  return region;
283 }
284 
286 
288 {
290  boost_foreach(Cells& elements, find_components_recursively<Cells>(mesh.topology()))
291  {
292  if (elements.element_type().derived_type_name() == "cf3.mesh.LagrangeP2.Quad2D")
293  {
294  Real jacobian_determinant=0;
295  Uint nb_nodes_per_elem = elements.element_type().nb_nodes();
296  std::vector<Uint> tmp_nodes(nb_nodes_per_elem);
297  for (Uint e=0; e<elements.size(); ++e)
298  {
299  jacobian_determinant = elements.element_type().jacobian_determinant(elements.geometry_space().shape_function().local_coordinates().row(0),elements.geometry_space().get_coordinates(e));
300  if (jacobian_determinant < 0)
301  {
302  // reverse the connectivity nodes order
303  for (Uint n=0;n<nb_nodes_per_elem; ++n)
304  tmp_nodes[n] = elements.geometry_space().connectivity()[e][n];
305  if (elements.element_type().derived_type_name() == "cf3.mesh.LagrangeP2.Quad2D")
306  {
307  elements.geometry_space().connectivity()[e][0] = tmp_nodes[0];
308  elements.geometry_space().connectivity()[e][1] = tmp_nodes[3];
309  elements.geometry_space().connectivity()[e][2] = tmp_nodes[2];
310  elements.geometry_space().connectivity()[e][3] = tmp_nodes[1];
311  elements.geometry_space().connectivity()[e][4] = tmp_nodes[7];
312  elements.geometry_space().connectivity()[e][5] = tmp_nodes[6];
313  elements.geometry_space().connectivity()[e][6] = tmp_nodes[5];
314  elements.geometry_space().connectivity()[e][7] = tmp_nodes[4];
315  elements.geometry_space().connectivity()[e][8] = tmp_nodes[8];
316  }
317  }
318  }
319  }
320  }
321 }
322 
324 
325 } // smurf
326 } // mesh
327 } // cf3
#define CFinfo
these are always defined
Definition: Log.hpp:104
const ShapeFunction & shape_function() const
Definition: Space.cpp:102
std::string name(ComponentWrapper &self)
Field & create_field(const std::string &name, const Uint cols)
Create a new field in this group.
Definition: Dictionary.cpp:178
boost::proto::terminal< SFOp< JacobianDeterminantOp > >::type const jacobian_determinant
bool is_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:151
Helper class to create the Builder and place it in the factory.
Definition: Builder.hpp:212
Space & geometry_space() const
Definition: Entities.hpp:94
virtual Real jacobian_determinant(const RealVector &mapped_coord, const RealMatrix &nodes) const =0
virtual const RealMatrix & local_coordinates() const =0
virtual std::string derived_type_name() const =0
std::string path() const
Definition: URI.cpp:253
#define cf3_assert(a)
Definition: Assertions.hpp:93
ElementType & element_type() const
return the elementType
Definition: Entities.cpp:116
#define boost_foreach
lowercase version of BOOST_FOREACH
Definition: Foreach.hpp:16
const std::string & name() const
Access the name of the component.
Definition: Component.hpp:146
const Field & coordinates() const
Definition: Dictionary.cpp:481
static const Uint m_tp_elem_dim[nb_tp_types]
Definition: Shared.hpp:45
#define CFendl
Definition: Log.hpp:109
static const Uint m_nodes_in_tp_elem[nb_tp_types]
Definition: Shared.hpp:44
Conversions from and to std::string.
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
boost::proto::terminal< SFOp< NodesOp > >::type const nodes
unsigned j
Definition: smurf.h:25
std::string title
Definition: smurf.h:20
Uint size() const
return the number of elements
Definition: Entities.cpp:161
Handle< Region > create_region(std::string const &relative_path)
Definition: Reader.cpp:268
cf3::common::ComponentBuilder< smurf::Reader, MeshReader, LibSmurf > aSmurfReader_Builder
Definition: Reader.cpp:50
PropertyList & properties()
Definition: Component.cpp:842
unsigned i
Definition: smurf.h:25
static std::string tp_name_to_cf_name(const Uint dim, const Uint tp_type)
Definition: Shared.cpp:378
std::string m_file_basename
Definition: Reader.hpp:68
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
Top-level namespace for coolfluid.
Definition: Action.cpp:18
const TYPE value(const std::string &opt_name) const
Get the value of the option with given name.
Definition: OptionList.hpp:104
Handle< Region > m_region
Definition: Reader.hpp:66
virtual std::vector< std::string > get_extensions()
Definition: Reader.cpp:90
virtual void do_read_mesh_into(const common::URI &fp, Mesh &mesh)
Definition: Reader.cpp:99
RealMatrix get_coordinates(const Uint elem_idx) const
Lookup element coordinates.
Definition: Space.cpp:179
void raise_mesh_loaded()
Definition: Mesh.cpp:479
void readMainHeader(std::string &htitle, std::vector< std::string > &hvnames)
Definition: smurf.cpp:259
std::vector< std::vector< double > > m_vv
Definition: Reader.hpp:74
Reader(const std::string &name)
constructor
Definition: Reader.cpp:54
void set_row_size(const Uint nb_cols)
Definition: Table.hpp:78
double time
Definition: smurf.h:21
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
static const std::string dim_name[4]
Definition: Shared.hpp:48
void resize(const Uint size)
Resize the contained fields.
Definition: Dictionary.cpp:106
Uint nb_nodes() const
Definition: ElementType.hpp:73
std::set< Uint > m_used_nodes
Definition: Reader.hpp:78
Region & topology() const
Definition: Mesh.hpp:51
void fix_negative_volumes(Mesh &mesh)
Definition: Reader.cpp:287
Handle< Component > handle()
Get a handle to the component.
Definition: Component.hpp:179
ZoneType type
Definition: smurf.h:23
OptionList & options()
Definition: Component.cpp:856
SelectOptionType< T >::type & add(const std::string &name, const T &default_value=T())
Definition: OptionList.hpp:45
#define CFdebug
Definition: Log.hpp:107
Base class for defining CF components.
Definition: Component.hpp:82
Handle< Mesh > m_mesh
Definition: Reader.hpp:65
Connectivity & connectivity()
connectivity table to dictionary entries
Definition: Space.hpp:110
bool is_not_null(T ptr)
predicate for comparison to nullptr
Definition: CF.hpp:147
virtual void resize(const Uint nb_rows)
Definition: Table.hpp:85
#define FromHere()
Send comments to:
COOLFluiD Web Admin