Flow123d  last_with_con_2.0.0-4-g42e6930
field_elementwise.impl.hh
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 field_elementwise.impl.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_ELEMENTWISE_IMPL_HH_
19 #define FIELD_ELEMENTWISE_IMPL_HH_
20 
21 
23 #include "system/file_path.hh"
24 #include "input/input_type.hh"
25 #include "mesh/msh_gmshreader.h"
26 #include "mesh/reader_instances.hh"
27 
28 /// Implementation.
29 
30 namespace IT = Input::Type;
31 
32 FLOW123D_FORCE_LINK_IN_CHILD(field_elementwise)
33 
34 
35 template <int spacedim, class Value>
36 const Input::Type::Record & FieldElementwise<spacedim, Value>::get_input_type()
37 {
38  return it::Record("FieldElementwise", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
41  "Input file with ASCII GMSH file format.")
43  "The values of the Field are read from the ```$ElementData``` section with field name given by this key.")
44  .close();
45 }
46 
47 
48 template <int spacedim, class Value>
50  Input::register_class< FieldElementwise<spacedim, Value>, unsigned int >("FieldElementwise") +
52 
53 
54 
55 template <int spacedim, class Value>
57 : FieldAlgorithmBase<spacedim, Value>(n_comp),
58  internal_raw_data(true), mesh_(NULL)
59 
60 {
61  n_components_ = this->value_.n_rows() * this->value_.n_cols();
62 }
63 
64 
65 
66 template <int spacedim, class Value>
68  unsigned int n_components)
69 : FieldAlgorithmBase<spacedim, Value>(n_components),
70 internal_raw_data(false), mesh_(NULL)
71 {
72  n_components_ = this->value_.n_rows() * this->value_.n_cols();
73  data_ = data;
74 }
75 
76 
77 
78 
79 template <int spacedim, class Value>
81  cout << string(reader_file_) << endl;
82  OLD_ASSERT( internal_raw_data, "Trying to initialize internal FieldElementwise from input.");
83  OLD_ASSERT( reader_file_ == FilePath(), "Multiple call of init_from_input.\n");
84  reader_file_ = FilePath( rec.val<FilePath>("gmsh_file") );
86 
87  field_name_ = rec.val<std::string>("field_name");
88 }
89 
90 
91 
92 template <int spacedim, class Value>
93 void FieldElementwise<spacedim, Value>::set_data_row(unsigned int boundary_idx, typename Value::return_type &value) {
94  Value ref(value);
95  OLD_ASSERT( this->value_.n_cols() == ref.n_cols(), "Size of variable vectors do not match.\n" );
96  OLD_ASSERT( mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
97  OLD_ASSERT( boundary_domain_ , "Method set_data_row can be used only for boundary fields.");
98  unsigned int vec_pos = boundary_idx * n_components_;
100  for(unsigned int row=0; row < ref.n_rows(); row++)
101  for(unsigned int col=0; col < ref.n_cols(); col++, vec_pos++)
102  vec[vec_pos] = ref(row,col);
103 
104 }
105 
106 
107 template <int spacedim, class Value>
109  OLD_ASSERT(mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
110  if ( reader_file_ == FilePath() ) return false;
111 
112  //walkaround for the steady time governor - there is no data to be read in time==infinity
113  //TODO: is it possible to check this before calling set_time?
114  //if (time.end() == numeric_limits< double >::infinity()) return false;
115 
116  GMSH_DataHeader search_header;
117  search_header.actual=false;
118  search_header.field_name=field_name_;
119  search_header.n_components=n_components_;
120  search_header.n_entities=n_entities_;
121  search_header.time=time.end();
122 
123 
124  data_ = ReaderInstances::instance()->get_reader(reader_file_)->get_element_data<typename Value::element_type>(search_header,
126  return search_header.actual;
127 }
128 
129 
130 
131 template <int spacedim, class Value>
132 void FieldElementwise<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
133  // set mesh only once or to same value
134  OLD_ASSERT(mesh_ == nullptr || mesh_ == mesh, "Trying to change mesh of the FieldElementwise.");
135  boundary_domain_ = boundary_domain;
136 
137  mesh_=mesh;
138  if (boundary_domain_) {
140  } else {
142  }
143 
144  // allocate
145  if (!data_) {
146  data_ = std::make_shared<std::vector<typename Value::element_type>>();
147  data_->resize(n_entities_ * n_components_);
148  }
149 
150 }
151 
152 
153 
154 /**
155  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
156  */
157 template <int spacedim, class Value>
158 typename Value::return_type const & FieldElementwise<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
159 {
160  OLD_ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
161  OLD_ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
162 
163  unsigned int idx = n_components_*elm.idx();
165 
166  return Value::from_raw(this->r_value_, (typename Value::element_type *)(&vec[idx]));
167 }
168 
169 
170 
171 /**
172  * Returns std::vector of scalar values in several points at once.
173  */
174 template <int spacedim, class Value>
177 {
178  OLD_ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
179  OLD_ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
180  OLD_ASSERT_EQUAL( point_list.size(), value_list.size() );
181  if (boost::is_floating_point< typename Value::element_type>::value) {
182  unsigned int idx = n_components_*elm.idx();
184 
185  typename Value::return_type const &ref = Value::from_raw(this->r_value_, (typename Value::element_type *)(&vec[idx]));
186  for(unsigned int i=0; i< value_list.size(); i++) {
187  OLD_ASSERT( Value(value_list[i]).n_rows()==this->value_.n_rows(),
188  "value_list[%d] has wrong number of rows: %d; should match number of components: %d\n",
189  i, Value(value_list[i]).n_rows(),this->value_.n_rows());
190 
191  value_list[i] = ref;
192  }
193  } else {
194  xprintf(UsrErr, "FieldElementwise is not implemented for discrete return types.\n");
195  }
196 }
197 
198 
199 
200 template <int spacedim, class Value>
202 
203 
204 
205 #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.
virtual void init_from_input(const Input::Record &rec)
unsigned int component_idx_
Specify if the field is part of a MultiField and which component it is.
bool is_boundary() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:109
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:99
Definition: mesh.h:95
void set_data_row(unsigned int boundary_idx, typename Value::return_type &value)
Value::return_type r_value_
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:286
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:391
#define OLD_ASSERT(...)
Definition: global_defs.h:131
unsigned int n_entities
Number of rows.
unsigned int n_elements() const
Definition: mesh.h:138
bool is_elemental() const
Definition: accessors.hh:75
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.hh:606
bool set_time(const TimeStep &time) override
vector< int > const & elements_id_maps(bool boundary_domain) const
Definition: mesh.cc:706
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:87
FieldElementwise(unsigned int n_comp=0)
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:468
ElementVector bc_elements
Definition: mesh.h:229
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:48
Definition: system.hh:59
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)
unsigned int n_entities_
Number of rows in data_ buffer.
std::shared_ptr< GmshMeshReader > get_reader(const FilePath &file_path)
#define OLD_ASSERT_EQUAL(a, b)
Definition: global_defs.h:133
virtual void set_mesh(const Mesh *mesh, bool boundary_domain)
Record type proxy class.
Definition: type_record.hh:171
static ReaderInstances * instance()
Returns singleton instance.
unsigned int idx() const
Definition: accessors.hh:113
Class for declaration of the input data that are in string format.
Definition: type_base.hh:568
Representation of one time step..
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180