Flow123d  release_2.2.0-36-g163dc99
msh_basereader.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file msh_basereader.cc
15  * @brief
16  * @author dalibor
17  */
18 
19 
20 #include "io/msh_basereader.hh"
21 #include "io/msh_gmshreader.h"
22 #include "io/msh_vtkreader.hh"
23 #include "system/sys_profiler.hh"
24 
25 
27 : tok_(file_name) {
28 }
29 
30 std::shared_ptr< BaseMeshReader > BaseMeshReader::reader_factory(const FilePath &file_name) {
31  std::shared_ptr<BaseMeshReader> reader_ptr;
32  if ( file_name.extension() == ".msh" ) {
33  reader_ptr = std::make_shared<GmshMeshReader>(file_name);
34  } else if ( file_name.extension() == ".vtu" ) {
35  reader_ptr = std::make_shared<VtkMeshReader>(file_name);
36  } else {
37  THROW(ExcWrongExtension() << EI_FileExtension(file_name.extension()) << EI_MeshFile((string)file_name) );
38  }
39  return reader_ptr;
40 }
41 
43  START_TIMER("BaseMeshReader - mesh factory");
44 
45  Input::Array region_list;
46  Mesh * mesh = new Mesh( input_mesh_rec );
47 
48  try {
49  std::shared_ptr< BaseMeshReader > reader = BaseMeshReader::reader_factory(input_mesh_rec.val<FilePath>("mesh_file"));
50  reader->read_physical_names(mesh);
51  if (input_mesh_rec.opt_val("regions", region_list)) {
52  mesh->read_regions_from_input(region_list);
53  }
54  reader->read_raw_mesh(mesh);
55  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_mesh_rec)
56  mesh->setup_topology();
57  mesh->check_and_finish();
58  return mesh;
59 
60 }
61 
63  ASSERT(mesh).error("Argument mesh is NULL.\n");
64  tok_.set_position( Tokenizer::Position() );
65  read_nodes(mesh);
66  read_elements(mesh);
67 }
68 
69 
71  if (boundary_domain) return boundary_elements_id_;
72  else return bulk_elements_id_;
73 }
74 
75 template<typename T>
76 typename ElementDataCache<T>::ComponentDataPtr BaseMeshReader::get_element_data( std::string field_name, double time,
77  unsigned int n_entities, unsigned int n_components, bool boundary_domain, unsigned int component_idx) {
79  .error("Vector of mapping VTK to GMSH element is not initialized. Did you call check_compatible_mesh?");
80 
81  MeshDataHeader actual_header = this->find_header(time, field_name);
82  ElementDataFieldMap::iterator it=element_data_values_.find(field_name);
83  if (it == element_data_values_.end()) {
84  element_data_values_[field_name] = std::make_shared< ElementDataCache<T> >();
85  it=element_data_values_.find(field_name);
86  }
87 
88  if ( !it->second->is_actual(actual_header.time, field_name) ) {
89  unsigned int size_of_cache; // count of vectors stored in cache
90 
91  // check that the header is valid, try to correct
92  if (actual_header.n_entities != n_entities) {
93  WarningOut().fmt("In file '{}', '{}' section for field '{}', time: {}.\nWrong number of entities: {}, using {} instead.\n",
94  tok_.f_name(), data_section_name_, field_name, actual_header.time, actual_header.n_entities, n_entities);
95  // actual_header.n_entities=n_entities;
96  }
97 
98  if (n_components == 1) {
99  // read for MultiField to 'n_comp' vectors
100  // or for Field if ElementData contains only one value
101  size_of_cache = actual_header.n_components;
102  }
103  else {
104  // read for Field if more values is stored to one vector
105  size_of_cache = 1;
106  if (actual_header.n_components != n_components) {
107  WarningOut().fmt("In file '{}', '{}' section for field '{}', time: {}.\nWrong number of components: {}, using {} instead.\n",
108  tok_.f_name(), data_section_name_, field_name, actual_header.time, actual_header.n_components, n_components);
109  actual_header.n_components=n_components;
110  }
111  }
112 
113  element_data_values_[field_name]
114  = std::make_shared< ElementDataCache<T> >(actual_header, size_of_cache, n_components*n_entities);
115  this->read_element_data(*(it->second), actual_header, n_components, boundary_domain );
116  }
117 
118  if (component_idx == std::numeric_limits<unsigned int>::max()) component_idx = 0;
119  ElementDataCache<T> &current_cache = dynamic_cast<ElementDataCache<T> &>(*(it->second));
120  return current_cache.get_component_data(component_idx);
121 }
122 
123 
124 // explicit instantiation of template methods
125 #define MESH_READER_GET_ELEMENT_DATA(TYPE) \
126 template typename ElementDataCache<TYPE>::ComponentDataPtr BaseMeshReader::get_element_data<TYPE>(std::string field_name, double time, \
127  unsigned int n_entities, unsigned int n_components, bool boundary_domain, unsigned int component_idx);
128 
130 MESH_READER_GET_ELEMENT_DATA(unsigned int);
132 
std::shared_ptr< std::vector< T > > ComponentDataPtr
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
ElementDataFieldMap element_data_values_
Cache with last read element data.
void check_and_finish()
Definition: mesh.cc:720
BaseMeshReader(const FilePath &file_name)
Constructor.
unsigned int n_entities
Number of rows.
#define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor)
Definition: accessors.hh:64
Definition: mesh.h:97
std::string data_section_name_
Store name of field data section specify for type of mesh file.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
#define MESH_READER_GET_ELEMENT_DATA(TYPE)
bool opt_val(const string &key, Ret &value) const
virtual void read_nodes(Mesh *mesh)=0
void read_regions_from_input(Input::Array region_list)
Definition: mesh.cc:710
static Mesh * mesh_factory(const Input::Record &input_mesh_rec)
vector< int > bulk_elements_id_
void setup_topology()
Definition: mesh.cc:230
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
const Ret val(const string &key) const
void read_raw_mesh(Mesh *mesh)
virtual void read_elements(Mesh *mesh)=0
#define START_TIMER(tag)
Starts a timer with specified tag.
double time
Time of field data (used only for GMSH reader)
ElementDataCache< T >::ComponentDataPtr get_element_data(std::string field_name, double time, unsigned int n_entities, unsigned int n_components, bool boundary_domain, unsigned int component_idx)
virtual void read_element_data(ElementDataCacheBase &data_cache, MeshDataHeader actual_header, unsigned int n_components, bool boundary_domain)=0
string extension() const
Definition: file_path.cc:198
virtual MeshDataHeader & find_header(double time, std::string field_name)=0
unsigned int n_components
Number of values on one row.
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
vector< int > boundary_elements_id_
ComponentDataPtr get_component_data(unsigned int component_idx)
Return vector of element data for get component.
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:236
static std::shared_ptr< BaseMeshReader > reader_factory(const FilePath &file_name)
Tokenizer tok_
Tokenizer used for reading ASCII file format.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
std::vector< int > const & get_element_vector(bool boundary_domain)