Flow123d  intersections_paper-476-gbe68821
field_fe.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 field_fe.cc
15  * @brief
16  */
17 
18 
19 #include "fields/field_fe.hh"
20 #include "fields/field_instances.hh" // for instantiation macros
21 #include "input/input_type.hh"
22 #include "fem/fe_p.hh"
23 #include "mesh/reader_instances.hh"
24 
25 
26 
27 
28 /// Implementation.
29 
30 namespace it = Input::Type;
31 
32 
33 
34 
36 
37 
38 template <int spacedim, class Value>
39 const Input::Type::Record & FieldFE<spacedim, Value>::get_input_type()
40 {
41  return it::Record("FieldFE", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field given by finite element approximation.")
45  "GMSH mesh with data. Can be different from actual computational mesh.")
47  "The values of the Field are read from the ```$ElementData``` section with field name given by this key.")
48  .close();
49 }
50 
51 template <int spacedim, class Value>
53  Input::register_class< FieldFE<spacedim, Value>, unsigned int >("FieldFE") +
55 
56 
57 
58 template <int spacedim, class Value>
59 FieldFE<spacedim, Value>::FieldFE( unsigned int n_comp)
60 : FieldAlgorithmBase<spacedim, Value>(n_comp),
61  data_vec_(nullptr),
62  dof_indices(nullptr),
63  field_name_("")
64 {}
65 
66 
67 template <int spacedim, class Value>
68 void FieldFE<spacedim, Value>::set_fe_data(std::shared_ptr<DOFHandlerMultiDim> dh,
69  MappingP1<1,3> *map1,
70  MappingP1<2,3> *map2,
71  MappingP1<3,3> *map3,
72  VectorSeqDouble *data)
73 {
74  dh_ = dh;
75  data_vec_ = data;
76 
77  unsigned int ndofs = max(dh_->fe<1>()->n_dofs(), max(dh_->fe<2>()->n_dofs(), dh_->fe<3>()->n_dofs()));
78  dof_indices = new unsigned int[ndofs];
79 
80  // initialization data of value handlers
81  FEValueInitData init_data;
82  init_data.dh = dh_;
83  init_data.data_vec = data_vec_;
84  init_data.ndofs = ndofs;
85  init_data.n_comp = this->n_comp();
86 
87  // initialize value handler objects
88  value_handler1_.initialize(init_data, map1);
89  value_handler2_.initialize(init_data, map2);
90  value_handler3_.initialize(init_data, map3);
91 }
92 
93 
94 
95 /**
96  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
97  */
98 template <int spacedim, class Value>
99 typename Value::return_type const & FieldFE<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
100 {
101  switch (elm.dim()) {
102  case 1:
103  return value_handler1_.value(p, elm);
104  case 2:
105  return value_handler2_.value(p, elm);
106  case 3:
107  return value_handler3_.value(p, elm);
108  default:
109  ASSERT(false).error("Invalid element dimension!");
110  }
111 
112  return this->r_value_;
113 }
114 
115 
116 
117 /**
118  * Returns std::vector of scalar values in several points at once.
119  */
120 template <int spacedim, class Value>
123 {
124  ASSERT_EQ( point_list.size(), value_list.size() ).error();
125 
126  switch (elm.dim()) {
127  case 1:
128  value_handler1_.value_list(point_list, elm, value_list);
129  break;
130  case 2:
131  value_handler2_.value_list(point_list, elm, value_list);
132  break;
133  case 3:
134  value_handler3_.value_list(point_list, elm, value_list);
135  break;
136  default:
137  ASSERT(false).error("Invalid element dimension!");
138  }
139 }
140 
141 
142 
143 template <int spacedim, class Value>
145  this->init_unit_conversion_coefficient(rec, init_data);
146  flags_ = init_data.flags_;
147 
148 
149  // read data from input record
150  reader_file_ = FilePath( rec.val<FilePath>("mesh_data_file") );
151  field_name_ = rec.val<std::string>("field_name");
152 }
153 
154 
155 
156 template <int spacedim, class Value>
157 void FieldFE<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
158  // Mesh can be set only for field initialized from input.
160  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
161  this->make_dof_handler(mesh);
162  }
163 }
164 
165 
166 
167 template <int spacedim, class Value>
169  // temporary solution - these objects will be set through FieldCommon
170  fe1_ = new FE_P_disc<0,1,3>();
171  fe2_ = new FE_P_disc<0,2,3>();
172  fe3_ = new FE_P_disc<0,3,3>();
173 
174  dh_ = std::make_shared<DOFHandlerMultiDim>( const_cast<Mesh &>(*mesh) );
175  dh_->distribute_dofs(*fe1_, *fe2_, *fe3_);
176  unsigned int ndofs = max(dh_->fe<1>()->n_dofs(), max(dh_->fe<2>()->n_dofs(), dh_->fe<3>()->n_dofs()));
177  dof_indices = new unsigned int[ndofs];
178 
179  // allocate data_vec_
180  unsigned int data_size = dh_->n_global_dofs();
181  data_vec_ = new VectorSeqDouble();
182  data_vec_->resize(data_size);
183 
184  // initialization data of value handlers
185  FEValueInitData init_data;
186  init_data.dh = dh_;
187  init_data.data_vec = data_vec_;
188  init_data.ndofs = ndofs;
189  init_data.n_comp = this->n_comp();
190 
191  // initialize value handler objects
192  value_handler1_.initialize(init_data);
193  value_handler2_.initialize(init_data);
194  value_handler3_.initialize(init_data);
195 }
196 
197 
198 
199 template <int spacedim, class Value>
201  // Time can be set only for field initialized from input.
203  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
204  ASSERT_PTR(dh_)(field_name_).error("Null target mesh pointer of finite element field, did you call set_mesh()?\n");
205  if ( reader_file_ == FilePath() ) return false;
206 
207  std::shared_ptr<Mesh> source_mesh = ReaderInstance::get_mesh(reader_file_);
208 
209  GMSH_DataHeader search_header;
210  search_header.actual = false;
211  search_header.field_name = field_name_;
212  search_header.n_components = this->value_.n_rows() * this->value_.n_cols();
213  search_header.n_entities = source_mesh->element.size();
214  search_header.time = time.end();
215 
216  bool boundary_domain_ = false;
217  auto data_vec = ReaderInstance::get_reader(reader_file_)->template get_element_data<double>(search_header,
218  source_mesh->elements_id_maps(boundary_domain_), this->component_idx_);
219  this->interpolate(data_vec);
220 
221  return search_header.actual;
222  } else return false;
223 
224 }
225 
226 
227 template <int spacedim, class Value>
229 {
230  std::shared_ptr<Mesh> source_mesh = ReaderInstance::get_mesh(reader_file_);
231  std::vector<double> sum_val(4);
232  std::vector<unsigned int> elem_count(4);
233  std::vector<unsigned int> searched_elements; // stored suspect elements in calculating the intersection
234 
235  FOR_ELEMENTS( dh_->mesh(), ele ) {
236  searched_elements.clear();
237  source_mesh->get_bih_tree().find_point(ele->centre(), searched_elements);
238  std::fill(sum_val.begin(), sum_val.end(), 0.0);
239  std::fill(elem_count.begin(), elem_count.end(), 0);
240  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++) {
241  ElementFullIter elm = source_mesh->element( *it );
242  bool contains=false;
243  switch (elm->dim()) {
244  case 1:
245  contains = value_handler1_.contains_point(ele->centre(), *elm);
246  break;
247  case 2:
248  contains = value_handler2_.contains_point(ele->centre(), *elm);
249  break;
250  case 3:
251  contains = value_handler3_.contains_point(ele->centre(), *elm);
252  break;
253  default:
254  ASSERT(false).error("Invalid element dimension!");
255  }
256  if (contains) {
257  // projection point in element
258  sum_val[elm->dim()] += (*data_vec)[*it];
259  ++elem_count[elm->dim()];
260  }
261  }
262  unsigned int dim = ele->dim();
263  double elem_value = 0.0;
264  do {
265  if (elem_count[dim] > 0) {
266  elem_value = sum_val[dim] / elem_count[dim];
267  break;
268  }
269  ++dim;
270  } while (dim<4);
271 
272  dh_->get_loc_dof_indices( ele, dof_indices);
274  (*data_vec_)[dof_indices[0]] = elem_value * this->unit_conversion_coefficient_;
275  }
276 }
277 
278 
279 
280 template <int spacedim, class Value>
282 {
283  if (dof_indices != nullptr) delete[] dof_indices;
284 }
285 
286 
287 // Instantiations of FieldFE
std::string field_name
virtual ~FieldFE()
Destructor.
Definition: field_fe.cc:281
void init_unit_conversion_coefficient(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Init value of unit_conversion_coefficient_ from input.
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Definition: field_fe.cc:121
std::shared_ptr< std::vector< T > > ComponentDataPtr
void interpolate(ElementDataCache< double >::ComponentDataPtr data_vec)
Interpolate data over all elements of target mesh.
Definition: field_fe.cc:228
VectorSeqDouble * data_vec_
Store data of Field.
Definition: field_fe.hh:114
unsigned int component_idx_
Specify if the field is part of a MultiField and which component it is.
void initialize(FEValueInitData init_data, MappingP1< elemdim, 3 > *map=nullptr)
Initialize data members.
#define FOR_ELEMENTS(_mesh_, __i)
Definition: mesh.h:444
std::string field_name_
field name read from input
Definition: field_fe.hh:140
FieldFlag::Flags flags_
FEValueHandler< 2, spacedim, Value > value_handler2_
Value handler that allows get value of 2D elements.
Definition: field_fe.hh:121
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:105
FilePath reader_file_
mesh reader file
Definition: field_fe.hh:137
#define INSTANCE_ALL(field)
Definition: mesh.h:95
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Definition: field_fe.cc:157
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
FEValueHandler< 3, spacedim, Value > value_handler3_
Value handler that allows get value of 3D elements.
Definition: field_fe.hh:123
bool set_time(const TimeStep &time) override
Definition: field_fe.cc:200
Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Returns one value in one given point.
Value::return_type r_value_
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:301
unsigned int size()
Getter for shared pointer of output data.
unsigned int * dof_indices
Array of indexes to data_vec_, used for get/set values.
Definition: field_fe.hh:116
constexpr bool match(Mask mask) const
Definition: flag_array.hh:163
double unit_conversion_coefficient_
Coeficient of conversion of user-defined unit.
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:193
unsigned int n_entities
Number of rows.
Discontinuous Lagrangean finite element on dim dimensional simplex.
Definition: fe_p.hh:202
std::shared_ptr< DOFHandlerMultiDim > dh_
DOF handler object.
Definition: field_fe.hh:112
FiniteElement< 2, 3 > * fe2_
Same as previous, but represents 2D element.
Definition: field_fe.hh:132
void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Returns std::vector of scalar values in several points at once.
VectorSeqDouble * data_vec
Store data of Field.
Definitions of basic Lagrangean finite elements with polynomial shape functions.
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:501
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
const Ret val(const string &key) const
void resize(unsigned int size)
Create shared pointer and PETSC vector with given size.
static std::shared_ptr< GmshMeshReader > get_reader(const FilePath &file_path)
static std::shared_ptr< Mesh > get_mesh(const FilePath &file_path)
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:488
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_fe.cc:99
double end() const
unsigned int ndofs
number of dofs
Space< spacedim >::Point Point
std::shared_ptr< DOFHandlerMultiDim > dh
DOF handler object.
unsigned int n_components
Number of values on one row.
void set_fe_data(std::shared_ptr< DOFHandlerMultiDim > dh, MappingP1< 1, 3 > *map1, MappingP1< 2, 3 > *map2, MappingP1< 3, 3 > *map3, VectorSeqDouble *data)
Definition: field_fe.cc:68
FEValueHandler< 1, spacedim, Value > value_handler1_
Value handler that allows get value of 1D elements.
Definition: field_fe.hh:119
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:213
Dedicated class for storing path to input and output files.
Definition: file_path.hh:48
Value value_
Last value, prevents passing large values (vectors) by value.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
FieldFE(unsigned int n_comp=0)
Definition: field_fe.cc:59
bool contains_point(arma::vec point, Element &elm)
Test if element contains given point.
const unsigned int n_dofs() const
Returns the number of degrees of freedom needed by the finite element.
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Definition: field_fe.cc:144
Record type proxy class.
Definition: type_record.hh:177
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:33
unsigned int dim() const
Definition: accessors.hh:83
FiniteElement< 1, 3 > * fe1_
Definition: field_fe.hh:130
unsigned int n_comp
number of components
FieldFlag::Flags flags_
Field flags.
Definition: field_fe.hh:143
Initialization structure of FEValueHandler class.
FiniteElement< 3, 3 > * fe3_
Same as previous, but represents 3D element.
Definition: field_fe.hh:134
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
Representation of one time step..
void make_dof_handler(const Mesh *mesh)
Create DofHandler object.
Definition: field_fe.cc:168
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:328
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
Definition: field_flag.hh:35
unsigned int n_comp() const
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:300