Flow123d
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 
17 /// Implementation.
18 
19 namespace IT = Input::Type;
20 
21 template <int spacedim, class Value>
24 
25 
26 template <int spacedim, class Value>
28  Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit
29  )
30 {
31  it::Record type=
32  it::Record("FieldElementwise", FieldBase<spacedim,Value>::template_name()+" Field constant in space.")
33  .derive_from(a_type)
35  "Input file with ASCII GMSH file format.")
37  "The values of the Field are read from the $ElementData section with field name given by this key.")
38  .close();
39 
40  return type;
41 }
42 
43 
44 
45 template <int spacedim, class Value>
47 : FieldBase<spacedim, Value>(n_comp),
48  internal_raw_data(true), data_(NULL), reader_(NULL), mesh_(NULL)
49 
50 {
51  n_components_ = this->value_.n_rows() * this->value_.n_cols();
52 }
53 
54 
55 
56 template <int spacedim, class Value>
57 FieldElementwise<spacedim, Value>::FieldElementwise(double *data_ptr, unsigned int n_components, unsigned int size )
58 : FieldBase<spacedim, Value>(n_components),
59  internal_raw_data(false), data_size_(size), data_(data_ptr), reader_(NULL), mesh_(NULL)
60 {
61  n_components_ = this->value_.n_rows() * this->value_.n_cols();
62 }
63 
64 
65 
66 template <int spacedim, class Value>
68  ASSERT( internal_raw_data, "Trying to initialize internal FieldElementwise from input.");
69  FilePath input_file = rec.val<FilePath>("gmsh_file");
70  ASSERT( reader_ == NULL, "Multiple call of init_from_input.\n");
71  reader_ = new GmshMeshReader(input_file);
72 
73  field_name_ = rec.val<std::string>("field_name");
74 }
75 
76 
77 
78 template <int spacedim, class Value>
79 void FieldElementwise<spacedim, Value>::set_data_row(unsigned int boundary_idx, typename Value::return_type &value) {
80  Value ref(value);
81  ASSERT( this->value_.n_cols() == ref.n_cols(), "Size of variable vectors do not match.\n" );
82  ASSERT( mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
83  ASSERT( boundary_domain_ , "Method set_data_row can be used only for boundary fields.");
84  typename Value::element_type *ptr=(typename Value::element_type *) ( data_+(boundary_idx)*n_components_);
85  for(unsigned int row=0; row < ref.n_rows(); row++)
86  for(unsigned int col=0; col < ref.n_cols(); col++, ptr++)
87  *ptr = ref(row,col);
88 }
89 
90 
91 template <int spacedim, class Value>
93  ASSERT(mesh_, "Null mesh pointer of elementwise field: %s, did you call set_mesh()?\n", field_name_.c_str());
94  ASSERT(data_, "Null data pointer.\n");
95  if (reader_ == NULL) return false;
96 
97  //walkaround for the steady time governor - there is no data to be read in time==infinity
98  //TODO: is it possible to check this before calling set_time?
99  if (time == numeric_limits< double >::infinity()) return false;
100 
101  GMSH_DataHeader search_header;
102  search_header.actual=false;
103  search_header.field_name=field_name_;
104  search_header.n_components=n_components_;
105  search_header.n_entities=n_entities_;
106  search_header.time=time;
107 
108 
109  reader_->read_element_data(search_header, data_, mesh_->elements_id_maps(boundary_domain_) );
110  return search_header.actual;
111 }
112 
113 
114 
115 template <int spacedim, class Value>
116 void FieldElementwise<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
117  // set mesh only once or to same value
118  ASSERT(mesh_ == nullptr || mesh_ == mesh, "Trying to change mesh of the FieldElementwise.");
119  boundary_domain_ = boundary_domain;
120 
121  mesh_=mesh;
122  if (boundary_domain_) {
123  n_entities_=mesh_->bc_elements.size();
124  } else {
125  n_entities_=mesh_->n_elements();
126  }
127 
128  // allocate
129  if (data_ == NULL) {
130  data_size_ = n_entities_ * n_components_;
131  data_ = new double[data_size_];
132  std::fill(data_, data_ + data_size_, 0.0);
133  }
134 
135 }
136 
137 
138 
139 /**
140  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
141  */
142 template <int spacedim, class Value>
143 typename Value::return_type const & FieldElementwise<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
144 {
145  ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
146  ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
147 
148  unsigned int idx = n_components_*elm.idx();
149 
150  return Value::from_raw(this->r_value_, (typename Value::element_type *)(data_+idx));
151 }
152 
153 
154 
155 /**
156  * Returns std::vector of scalar values in several points at once.
157  */
158 template <int spacedim, class Value>
161 {
162  ASSERT( elm.is_elemental(), "FieldElementwise works only for 'elemental' ElementAccessors.\n");
163  ASSERT( elm.is_boundary() == boundary_domain_, "Trying to get value of FieldElementwise '%s' for wrong ElementAccessor type (boundary/bulk).\n", field_name_.c_str() );
164  ASSERT_EQUAL( point_list.size(), value_list.size() );
165  if (boost::is_floating_point< typename Value::element_type>::value) {
166  unsigned int idx = n_components_*elm.idx();
167 
168  typename Value::return_type const &ref = Value::from_raw(this->r_value_, (typename Value::element_type *)(data_+idx));
169  for(unsigned int i=0; i< value_list.size(); i++) value_list[i] = ref;
170  } else {
171  xprintf(UsrErr, "FieldElementwise is not implemented for discrete return types.\n");
172  }
173 }
174 
175 
176 
177 template <int spacedim, class Value>
179  if (internal_raw_data && data_ != NULL) delete [] data_;
180  if (reader_ != NULL) delete reader_;
181 }
182 
183 
184 
185 #endif /* FIELD_ELEMENTWISE_IMPL_HH_ */