Flow123d  jenkins-Flow123d-windows-release-multijob-285
field_elementwise.impl.hh
Go to the documentation of this file.
1 /*
2  * field_elementwise.impl.hh
3  *
4  * Created on: Jan 23, 2013
5  * Author: jb
6  */
7 
8 #ifndef FIELD_ELEMENTWISE_IMPL_HH_
9 #define FIELD_ELEMENTWISE_IMPL_HH_
10 
11 
13 #include "system/file_path.hh"
14 #include "input/input_type.hh"
15 #include "mesh/msh_gmshreader.h"
16 #include "mesh/reader_instances.hh"
17 
18 /// Implementation.
19 
20 namespace IT = Input::Type;
21 
22 template <int spacedim, class Value>
25 
26 
27 template <int spacedim, class Value>
29  Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit
30  )
31 {
32  it::Record type=
33  it::Record("FieldElementwise", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
34  .derive_from(a_type)
36  "Input file with ASCII GMSH file format.")
38  "The values of the Field are read from the \\$ElementData section with field name given by this key.")
39  .close();
40 
41  return type;
42 }
43 
44 
45 
46 template <int spacedim, class Value>
48 : FieldAlgorithmBase<spacedim, Value>(n_comp),
49  internal_raw_data(true), mesh_(NULL)
50 
51 {
52  n_components_ = this->value_.n_rows() * this->value_.n_cols();
53 }
54 
55 
56 
57 template <int spacedim, class Value>
59  unsigned int n_components)
60 : FieldAlgorithmBase<spacedim, Value>(n_components),
61 internal_raw_data(false), mesh_(NULL)
62 {
63  n_components_ = this->value_.n_rows() * this->value_.n_cols();
64  data_ = data;
65 }
66 
67 
68 
69 
70 template <int spacedim, class Value>
72  cout << string(reader_file_) << endl;
73  ASSERT( internal_raw_data, "Trying to initialize internal FieldElementwise from input.");
74  ASSERT( reader_file_ == FilePath(), "Multiple call of init_from_input.\n");
75  reader_file_ = FilePath( rec.val<FilePath>("gmsh_file") );
76  ReaderInstances::instance()->get_reader(reader_file_);
77 
78  field_name_ = rec.val<std::string>("field_name");
79 }
80 
81 
82 
83 template <int spacedim, class Value>
84 void FieldElementwise<spacedim, Value>::set_data_row(unsigned int boundary_idx, typename Value::return_type &value) {
85  Value ref(value);
86  ASSERT( this->value_.n_cols() == ref.n_cols(), "Size of variable vectors do not match.\n" );
87  ASSERT( mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
88  ASSERT( boundary_domain_ , "Method set_data_row can be used only for boundary fields.");
89  unsigned int vec_pos = boundary_idx * n_components_;
90  std::vector<typename Value::element_type> &vec = *( data_.get() );
91  for(unsigned int row=0; row < ref.n_rows(); row++)
92  for(unsigned int col=0; col < ref.n_cols(); col++, vec_pos++)
93  vec[vec_pos] = ref(row,col);
94 
95 }
96 
97 
98 template <int spacedim, class Value>
100  ASSERT(mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
101  if ( reader_file_ == FilePath() ) return false;
102 
103  //walkaround for the steady time governor - there is no data to be read in time==infinity
104  //TODO: is it possible to check this before calling set_time?
105  //if (time.end() == numeric_limits< double >::infinity()) return false;
106 
107  GMSH_DataHeader search_header;
108  search_header.actual=false;
109  search_header.field_name=field_name_;
110  search_header.n_components=n_components_;
111  search_header.n_entities=n_entities_;
112  search_header.time=time.end();
113 
114 
115  data_ = ReaderInstances::instance()->get_reader(reader_file_)->get_element_data<typename Value::element_type>(search_header,
116  mesh_->elements_id_maps(boundary_domain_), this->component_idx_);
117  return search_header.actual;
118 }
119 
120 
121 
122 template <int spacedim, class Value>
123 void FieldElementwise<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
124  // set mesh only once or to same value
125  ASSERT(mesh_ == nullptr || mesh_ == mesh, "Trying to change mesh of the FieldElementwise.");
126  boundary_domain_ = boundary_domain;
127 
128  mesh_=mesh;
129  if (boundary_domain_) {
130  n_entities_=mesh_->bc_elements.size();
131  } else {
132  n_entities_=mesh_->n_elements();
133  }
134 
135  // allocate
136  if (!data_) {
137  data_ = std::make_shared<std::vector<typename Value::element_type>>();
138  data_->resize(n_entities_ * n_components_);
139  }
140 
141 }
142 
143 
144 
145 /**
146  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
147  */
148 template <int spacedim, class Value>
149 typename Value::return_type const & FieldElementwise<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
150 {
151  ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
152  ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
153 
154  unsigned int idx = n_components_*elm.idx();
155  std::vector<typename Value::element_type> &vec = *( data_.get() );
156 
157  return Value::from_raw(this->r_value_, (typename Value::element_type *)(&vec[idx]));
158 }
159 
160 
161 
162 /**
163  * Returns std::vector of scalar values in several points at once.
164  */
165 template <int spacedim, class Value>
168 {
169  ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
170  ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
171  ASSERT_EQUAL( point_list.size(), value_list.size() );
172  if (boost::is_floating_point< typename Value::element_type>::value) {
173  unsigned int idx = n_components_*elm.idx();
174  std::vector<typename Value::element_type> &vec = *( data_.get() );
175 
176  typename Value::return_type const &ref = Value::from_raw(this->r_value_, (typename Value::element_type *)(&vec[idx]));
177  for(unsigned int i=0; i< value_list.size(); i++) {
178  ASSERT( Value(value_list[i]).n_rows()==this->value_.n_rows(),
179  "value_list[%d] has wrong number of rows: %d; should match number of components: %d\n",
180  i, Value(value_list[i]).n_rows(),this->value_.n_rows());
181 
182  value_list[i] = ref;
183  }
184  } else {
185  xprintf(UsrErr, "FieldElementwise is not implemented for discrete return types.\n");
186  }
187 }
188 
189 
190 
191 template <int spacedim, class Value>
193 
194 
195 
196 #endif /* FIELD_ELEMENTWISE_IMPL_HH_ */
std::string field_name
std::shared_ptr< std::vector< typename Value::element_type > > data_
Raw buffer of n_entities rows each containing Value::size() doubles.
static Input::Type::Record get_input_type(Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit)
virtual void init_from_input(const Input::Record &rec)
bool is_boundary() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:99
static Default obligatory()
Definition: type_record.hh:89
Definition: mesh.h:109
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
void set_data_row(unsigned int boundary_idx, typename Value::return_type &value)
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:401
unsigned int n_entities
Number of rows.
bool is_elemental() const
Definition: accessors.hh:65
#define ASSERT(...)
Definition: global_defs.h:121
static FileName input()
Definition: type_base.hh:464
bool set_time(const TimeStep &time) override
#define ASSERT_EQUAL(a, b)
Definition: global_defs.h:136
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:100
FieldElementwise(unsigned int n_comp=0)
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
ElementVector bc_elements
Definition: mesh.h:213
const Record & close() const
Definition: type_record.cc:314
double end() const
Space< spacedim >::Point Point
unsigned int n_components
Number of values on one row.
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Dedicated class for storing path to input and output files.
Definition: file_path.hh:32
Definition: system.hh:72
unsigned int n_components_
Size of Value.
Value value_
Last value, prevents passing large values (vectors) by value.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
std::shared_ptr< GmshMeshReader > get_reader(const FilePath &file_path)
virtual void set_mesh(const Mesh *mesh, bool boundary_domain)
Record type proxy class.
Definition: type_record.hh:169
static ReaderInstances * instance()
Returns singleton instance.
unsigned int idx() const
Definition: accessors.hh:103
Representation of one time step.
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430