Flow123d  JS_before_hm-927-g0a4a2b5
field.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.impl.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_IMPL_HH_
19 #define FIELD_IMPL_HH_
20 
21 #include <boost/foreach.hpp>
22 
23 #include "field.hh"
24 #include "field_algo_base.impl.hh"
25 #include "field_fe.hh"
26 #include "fields/eval_subset.hh"
27 #include "fields/eval_points.hh"
30 #include "mesh/region.hh"
32 #include "input/accessors.hh"
33 #include "io/observe.hh"
34 #include "io/output_mesh.hh"
35 #include "io/output_element.hh"
36 
37 
38 /******************************************************************************************
39  * Implementation of Field<...>
40  */
41 
42 template<int spacedim, class Value>
44 : data_(std::make_shared<SharedData>()),
45  value_cache_( FieldValueCache<typename Value::element_type>(Value::NRows_, Value::NCols_) )
46 {
47  // n_comp is nonzero only for variable size vectors Vector, VectorEnum, ..
48  // this invariant is kept also by n_comp setter
49  shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
50  this->add_factory( std::make_shared<FactoryBase>() );
51 
52  this->multifield_ = false;
53 }
54 
55 
56 template<int spacedim, class Value>
57 Field<spacedim,Value>::Field(const string &name, bool bc)
58 : data_(std::make_shared<SharedData>()),
59  value_cache_( FieldValueCache<typename Value::element_type>(Value::NRows_, Value::NCols_) )
60 {
61  // n_comp is nonzero only for variable size vectors Vector, VectorEnum, ..
62  // this invariant is kept also by n_comp setter
63  shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
64  shared_->bc_=bc;
65  this->name( name );
66  this->add_factory( std::make_shared<FactoryBase>() );
67  this->multifield_ = false;
68 }
69 
70 
71 
72 template<int spacedim, class Value>
73 Field<spacedim,Value>::Field(unsigned int component_index, string input_name, string name, bool bc)
74 : data_(std::make_shared<SharedData>()),
75  value_cache_( FieldValueCache<typename Value::element_type>(Value::NRows_, Value::NCols_) )
76 {
77  // n_comp is nonzero only for variable size vectors Vector, VectorEnum, ..
78  // this invariant is kept also by n_comp setter
79  shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
80  this->set_component_index(component_index);
81  this->name_ = (name=="") ? input_name : name;
82  this->shared_->input_name_ = input_name;
83  shared_->bc_ = bc;
84 
85  this->multifield_ = false;
86 }
87 
88 
89 template<int spacedim, class Value>
91 : FieldCommon(other),
92  data_(other.data_),
94  factories_(other.factories_),
96 {
97  if (other.no_check_control_field_)
98  no_check_control_field_ = make_shared<ControlField>(*other.no_check_control_field_);
99 
100  this->multifield_ = false;
101 }
102 
103 
104 template<int spacedim, class Value>
106 {
107  //ASSERT( flags().match(FieldFlag::input_copy) )(this->name())(other.name()).error("Try to assign to non-copy field from the field.");
108  ASSERT(other.shared_->mesh_).error("Must call set_mesh before assign to other field.\n");
109  ASSERT( !shared_->mesh_ || (shared_->mesh_==other.shared_->mesh_) ).error("Assignment between fields with different meshes.\n");
110 
111  // check for self assignement
112  if (&other == this) return *this;
113 
114  // class members derived from FieldCommon
115  shared_ = other.shared_;
116  shared_->is_fully_initialized_ = false;
118  last_time_ = other.last_time_;
122  this->multifield_ = false;
123 
124  // class members of Field class
125  data_ = other.data_;
126  factories_ = other.factories_;
128  value_cache_ = other.value_cache_;
129 
130  if (other.no_check_control_field_) {
131  no_check_control_field_ = make_shared<ControlField>(*other.no_check_control_field_);
132  }
133 
134  return *this;
135 }
136 
137 
138 
139 template<int spacedim, class Value>
140 typename Value::return_type Field<spacedim,Value>::operator() (BulkPoint &p) {
141  return value_cache_.template get_value<Value>(*p.elm_cache_map(), p.dh_cell(), p.eval_point_idx());
142 }
143 
144 
145 
146 template<int spacedim, class Value>
147 typename Value::return_type Field<spacedim,Value>::operator() (EdgePoint &p) {
148  return value_cache_.template get_value<Value>(*p.elm_cache_map(), p.dh_cell_side().cell(), p.eval_point_idx());
149 }
150 
151 
152 
153 template<int spacedim, class Value>
154 typename arma::Mat<typename Value::element_type>::template fixed<Value::NRows_, Value::NCols_>
155 Field<spacedim,Value>::operator[] (unsigned int i_cache_point) const
156 {
157  return this->value_cache().data().template mat<Value::NRows_, Value::NCols_>(i_cache_point);
158 }
159 
160 
161 
162 template<int spacedim, class Value>
164  return FieldBaseType::get_input_type_instance(shared_->input_element_selection_);
165 }
166 
167 
168 
169 template<int spacedim, class Value>
171  ASSERT(false).error("This method can't be used for Field");
172 
173  it::Array arr = it::Array( it::Integer() );
174  return arr;
175 }
176 
177 
178 
179 template<int spacedim, class Value>
181  const Field<spacedim, typename FieldValue<spacedim>::Enum > &control_field,
182  const vector<FieldEnum> &value_list) -> Field &
183 {
184  no_check_control_field_=std::make_shared<ControlField>(control_field);
185  shared_->no_check_values_=value_list;
186  return *this;
187 }
188 
189 template<int spacedim, class Value>
190 void Field<spacedim,Value>::set_mesh(const Mesh &in_mesh) {
191  // since we allow copy of fields before set_mesh is called
192  // we have to check that all copies set the same mesh
193  if (shared_->mesh_ && shared_->mesh_ != &in_mesh) {
194  THROW(ExcFieldMeshDifference() << EI_Field(name()) );
195  }
196 
197  shared_->mesh_ = &in_mesh;
198 
199  // initialize table if it is empty, we assume that the RegionDB is closed at this moment
200  region_fields_.resize( mesh()->region_db().size() );
201  RegionHistory init_history(history_length_limit_); // capacity
202  data_->region_history_.resize( mesh()->region_db().size(), init_history );
203 
204  if (no_check_control_field_) no_check_control_field_->set_mesh(in_mesh);
205 }
206 
207 
208 /*
209 template<int spacedim, class Value>
210 std::shared_ptr< typename Field<spacedim,Value>::FieldBaseType >
211 Field<spacedim,Value>::operator[] (Region reg)
212 {
213  ASSERT_LT(reg.idx(), this->region_fields_.size());
214  return this->region_fields_[reg.idx()];
215 }
216 */
217 
218 
219 template <int spacedim, class Value>
221  ASSERT(this->set_time_result_ != TimeStatus::unknown).error("Unknown time status.\n");
222  ASSERT_LT(reg.idx(), this->region_fields_.size());
223  FieldBasePtr region_field = this->region_fields_[reg.idx()];
224  return ( region_field && region_field->is_constant_in_space() );
225 }
226 
227 
228 template<int spacedim, class Value>
230  const RegionSet &domain,
231  FieldBasePtr field,
232  double time)
233 {
234  ASSERT_PTR(field).error("Null field pointer.\n");
235 
236  ASSERT_PTR( mesh() ).error("Null mesh pointer, set_mesh() has to be called before set_field().\n");
237  if (domain.size() == 0) return;
238 
239  ASSERT_EQ( field->n_comp() , shared_->n_comp_);
240  field->set_mesh( mesh() , is_bc() );
241 
242  HistoryPoint hp = HistoryPoint(time, field);
243  for(const Region &reg: domain) {
244  RegionHistory &region_history = data_->region_history_[reg.idx()];
245  // insert hp into descending time sequence
246  ASSERT( region_history.size() == 0 || region_history[0].first < hp.first)(hp.first)(region_history[0].first)
247  .error("Can not insert smaller time then last time in field's history.\n");
248  region_history.push_front(hp);
249  }
251 }
252 
253 
254 
255 template<int spacedim, class Value>
257  const RegionSet &domain,
258  const Input::AbstractRecord &a_rec,
259  double time)
260 {
261  FieldAlgoBaseInitData init_data(input_name(), n_comp(), units(), limits(), flags());
262  set_field(domain, FieldBaseType::function_factory(a_rec, init_data), time);
263 }
264 
265 
266 
267 
268 template<int spacedim, class Value>
269 bool Field<spacedim, Value>::set_time(const TimeStep &time_step, LimitSide limit_side)
270 {
271  ASSERT_PTR( mesh() )( name() ).error("NULL mesh pointer of field with given name. set_mesh must be called before.\n");
272 
273  // Skip setting time if the new time is equal to current time of the field
274  // and if either the field is continuous in that time or the current limit side is same as the new one.
275  if (time_step.end() == last_time_) {
276  if ( ! is_jump_time() ||
277  limit_side == last_limit_side_) {
278  last_limit_side_ = limit_side;
279  return changed();
280  }
281  }
282 
283  last_time_=time_step.end();
284  last_limit_side_ = limit_side;
285 
286  // possibly update our control field
288  no_check_control_field_->set_time(time_step, limit_side);
289  }
290 
292 
293  // read all descriptors satisfying time.ge(input_time)
294  update_history(time_step);
296 
297  //
298  is_jump_time_=false;
299  // set time_step on all regions
300  // for regions that match type of the field domain
301  for(const Region &reg: mesh()->region_db().get_region_set("ALL") ) {
302  auto rh = data_->region_history_[reg.idx()];
303 
304  // skip regions with no matching BC flag
305  if (reg.is_boundary() != is_bc()) continue;
306 
307  // Check regions with empty history, possibly set default.
308  if ( rh.empty()) continue;
309 
310  double last_time_in_history = rh.front().first;
311  unsigned int history_size=rh.size();
312  unsigned int i_history;
313  ASSERT( time_step.ge(last_time_in_history) ).error("Setting field time back in history not fully supported yet!");
314 
315  // set history index
316  if ( time_step.gt(last_time_in_history) ) {
317  // in smooth time_step
318  i_history=0;
319  } else {
320  // time_step .eq. input_time; i.e. jump time
321  is_jump_time_=true;
322  if (limit_side == LimitSide::right) {
323  i_history=0;
324  } else {
325  i_history=1;
326  }
327  }
328  i_history=min(i_history, history_size - 1);
329  ASSERT(i_history >= 0).error("Empty field history.");
330  // possibly update field pointer
331 
332  auto new_ptr = rh.at(i_history).second;
333  if (new_ptr != region_fields_[reg.idx()]) {
334  region_fields_[reg.idx()]=new_ptr;
336  }
337  // let FieldBase implementation set the time
338  if ( new_ptr->set_time(time_step) ) set_time_result_ = TimeStatus::changed;
339 
340  }
341 
342  return changed();
343 }
344 
345 
346 template<int spacedim, class Value>
348  ASSERT( flags().match(FieldFlag::equation_input))(other.name().c_str())(this->name().c_str())
349  .error("Can not copy to the non-input field.");
350 
351  // do not use copy if the field have its own input
353  && this->shared_->input_list_.size() != 0 ) return;
354 
355  if (typeid(other) == typeid(*this)) {
356  auto const &other_field = dynamic_cast< Field<spacedim, Value> const &>(other);
357  this->operator=(other_field);
358  }
359 }
360 
361 
362 
363 template<int spacedim, class Value>
364 void Field<spacedim, Value>::field_output(std::shared_ptr<OutputTime> stream)
365 {
366  // currently we cannot output boundary fields
367  if (!is_bc()) {
368  const OutputTime::DiscreteSpace type = this->get_output_type();
369 
371  this->compute_field_data( type, stream);
372  }
373 }
374 
375 
376 template<int spacedim, class Value>
377 void Field<spacedim, Value>::observe_output(std::shared_ptr<Observe> observe)
378 {
379  typedef typename Value::element_type ElemType;
380 
381  if (observe->point_ds()->size() == 0) return;
382 
383  ElementDataCache<ElemType> &output_data = observe->prepare_compute_data<ElemType>(this->name(), this->time(),
384  (unsigned int)Value::NRows_, (unsigned int)Value::NCols_);
385 
386  unsigned int loc_point_time_index, ele_index;
387  for(ObservePointAccessor op_acc : observe->local_range()) {
388  loc_point_time_index = op_acc.loc_point_time_index();
389  ele_index = op_acc.observe_point().element_idx();
390  const Value &obs_value =
391  Value( const_cast<typename Value::return_type &>(
392  this->value(op_acc.observe_point().global_coords(),
393  ElementAccessor<spacedim>(this->mesh(), ele_index)) ));
394  ASSERT_EQ(output_data.n_comp(), obs_value.n_rows()*obs_value.n_cols()).error();
395  output_data.store_value(loc_point_time_index, obs_value.mem_ptr());
396  }
397 }
398 
399 
400 
401 template<int spacedim, class Value>
403 
404  FieldResult result_all = result_none;
405  for(Region &reg : region_set) {
406  auto f = region_fields_[reg.idx()];
407  if (f) {
408  FieldResult fr = f->field_result();
409  if (result_all == result_none) // first region
410  result_all = fr;
411  else if (fr != result_all)
412  result_all = result_other; // if results from individual regions are different
413  } else return result_none; // if field is undefined on any region of the region set
414  }
415 
416  if (result_all == result_constant && region_set.size() > 1)
417  return result_other; // constant result for individual regions could be non-constant on the whole region set
418 
419  return result_all;
420 
421 }
422 
423 
424 template<int spacedim, class Value>
426 {
427  int nrows = Value::NRows_;
428  int ncols = Value::NCols_;
429  string type = "Integer";
431  type = "Double";
432 
433  return fmt::format("{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
434  nrows, ncols, type, this->limits().first, this->limits().second);
435 }
436 
437 
438 template<int spacedim, class Value>
440  ASSERT_PTR( mesh() ).error("Null mesh pointer, set_mesh() has to be called before.\n");
441 
442  // read input up to given time
443  double input_time;
444  if (shared_->input_list_.size() != 0) {
445  while( shared_->list_idx_ < shared_->input_list_.size()
446  && time.ge( input_time = time.read_time( shared_->input_list_[shared_->list_idx_].find<Input::Tuple>("time") ) ) ) {
447 
448  const Input::Record & actual_list_item = shared_->input_list_[shared_->list_idx_];
449  // get domain specification
450  RegionSet domain;
451  Input::Array domain_name_array;
452  unsigned int id;
453  if (actual_list_item.opt_val("region", domain_name_array)) {
454  std::vector<string> domain_names = mesh()->region_db().get_and_check_operands(domain_name_array);
455  domain = mesh()->region_db().union_set(domain_names);
456 
457  } else if (actual_list_item.opt_val("rid", id)) {
458  Region region;
459  try {
460  region = mesh()->region_db().find_id(id);
461  } catch (RegionDB::ExcUniqueRegionId &e) {
462  e << actual_list_item.ei_address();
463  throw;
464  }
465  if (region.is_valid())
466  domain.push_back(region);
467  else
468  THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(id) );
469  } else {
470  THROW(ExcMissingDomain()
471  << actual_list_item.ei_address() );
472  }
473 
474  // get field instance
475  for(auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
476  FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *this);
477  if (field_instance) // skip descriptors without related keys
478  {
479  // add to history
480  ASSERT_EQ( field_instance->n_comp() , shared_->n_comp_);
481  field_instance->set_mesh( mesh() , is_bc() );
482  for(const Region &reg: domain) {
483  // if region history is empty, add new field
484  // or if region history is not empty and the input_time is higher, add new field
485  // otherwise (region history is not empty and the input_time is the same),
486  // rewrite the region field
487  if( data_->region_history_[reg.idx()].size() == 0
488  || data_->region_history_[reg.idx()].back().first < input_time)
489  {
490  data_->region_history_[reg.idx()].push_front(
491  HistoryPoint(input_time, field_instance));
492  //DebugOut() << "Update history" << print_var(this->name()) << print_var(reg.label()) << print_var(input_time);
493  }
494  else
495  {
496  data_->region_history_[reg.idx()].back() =
497  HistoryPoint(input_time, field_instance);
498  }
499  }
500  break;
501  }
502  }
503 
504  ++shared_->list_idx_;
505  }
506  }
507 }
508 
509 template<int spacedim, class Value>
511  ASSERT_PTR(mesh()).error("Null mesh pointer.");
512  //if (shared_->is_fully_initialized_) return;
513 
514  // check there are no empty field pointers, collect regions to be initialized from default value
515  RegionSet regions_to_init; // empty vector
516 
517  for(const Region &reg : mesh()->region_db().get_region_set("ALL") )
518  if (reg.is_boundary() == is_bc()) { // for regions that match type of the field domain
519  RegionHistory &rh = data_->region_history_[reg.idx()];
520  if ( rh.empty() || ! rh[0].second) // empty region history
521  {
522  // test if check is turned on and control field is FieldConst
523  if (no_check_control_field_ && no_check_control_field_->is_constant(reg) ) {
524  // get constant enum value
525  auto elm = ElementAccessor<spacedim>(mesh(), reg);
526  FieldEnum value = no_check_control_field_->value(elm.centre(),elm);
527  // check that the value is in the disable list
528  if ( std::find(shared_->no_check_values_.begin(), shared_->no_check_values_.end(), value)
529  != shared_->no_check_values_.end() )
530  continue; // the field is not needed on this region
531  }
532  if (shared_->input_default_ != "") { // try to use default
533  regions_to_init.push_back( reg );
534  } else {
535  xprintf(UsrErr, "Missing value of the input field '%s' ('%s') on region ID: %d label: %s.\n",
536  input_name().c_str(), name().c_str(), reg.id(), reg.label().c_str() );
537  }
538  }
539  }
540 
541  // possibly set from default value
542  if ( regions_to_init.size() ) {
543  std::string region_list;
544  // has to deal with fact that reader can not deal with input consisting of simple values
545  string default_input=input_default();
546  auto input_type = get_input_type().make_instance().first;
547  Input::ReaderToStorage reader( default_input, *input_type, Input::FileFormat::format_JSON );
548 
549  auto a_rec = reader.get_root_interface<Input::AbstractRecord>();
550  FieldAlgoBaseInitData init_data(input_name(), n_comp(), units(), limits(), flags());
551  auto field_ptr = FieldBaseType::function_factory( a_rec , init_data );
552  field_ptr->set_mesh( mesh(), is_bc() );
553  for(const Region &reg: regions_to_init) {
554  data_->region_history_[reg.idx()]
555  .push_front(HistoryPoint( 0.0, field_ptr) );
556  region_list+=" "+reg.label();
557  }
558  FieldCommon::messages_data_.push_back( MessageData(input_default(), name(), region_list) );
559 
560  }
561  //shared_->is_fully_initialized_ = true;
562 }
563 
564 
565 template<int spacedim, class Value>
566 void Field<spacedim,Value>::add_factory(const std::shared_ptr<FactoryBase> factory) {
567  factories_.push_back( factory );
568 }
569 
570 
571 template<int spacedim, class Value>
573  Input::AbstractRecord field_record;
574  if (rec.opt_val(field.input_name(), field_record)) {
575  FieldAlgoBaseInitData init_data(field.input_name(), field.n_comp(), field.units(), field.limits(), field.get_flags());
576  return FieldBaseType::function_factory(field_record, init_data );
577  }
578  else
579  return FieldBasePtr();
580 }
581 
582 
583 template<int spacedim, class Value>
585  return in_rec.find<Input::AbstractRecord>(input_name);
586 }
587 
588 
589 
590 
591 template<int spacedim, class Value>
593  if (! flags().match(FieldFlag::declare_input)) return;
594 
595  // check that times forms ascending sequence
596  double time,last_time=0.0;
597 
599  it != list.end();
600  ++it) {
601  for(auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
602  if ( (*rit)->is_active_field_descriptor( (*it), this->input_name() ) ) {
603  shared_->input_list_.push_back( Input::Record( *it ) );
604  time = tg.read_time( it->find<Input::Tuple>("time") );
605  if (time < last_time) {
606  THROW( ExcNonascendingTime()
607  << EI_Time(time)
608  << EI_Field(input_name())
609  << it->ei_address());
610  }
611  last_time = time;
612 
613  break;
614  }
615  }
616  }
617 
618 }
619 
620 
621 
622 template<int spacedim, class Value>
623 void Field<spacedim,Value>::compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr<OutputTime> stream) {
624  typedef typename Value::element_type ElemType;
625 
626  OutputTime::OutputDataPtr output_data_base = stream->prepare_compute_data<ElemType>(this->name(), space_type,
627  (unsigned int)Value::NRows_, (unsigned int)Value::NCols_);
628 
629  try{
630  // try casting actual ElementDataCache
631  if( ! output_data_base->is_dummy()){
632  auto output_data = std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_data_base);
633  fill_data_cache(space_type, stream, output_data);
634  }
635 
636  } catch(const std::bad_cast& e){
637  // skip
638  }
639 
640  /* Set the last time */
641  stream->update_time(this->time());
642 
643 }
644 
645 template<int spacedim, class Value>
647  std::shared_ptr<OutputTime> stream,
648  std::shared_ptr<ElementDataCache<typename Value::element_type>> data_cache)
649 {
650  std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
651  ASSERT(output_mesh);
652 
653  /* Copy data to array */
654  switch(space_type) {
657  unsigned int node_index = 0;
658  for(const auto & ele : *output_mesh )
659  {
660  std::vector<Space<3>::Point> vertices = ele.vertex_list();
661  for(unsigned int i=0; i < ele.n_nodes(); i++)
662  {
663  const Value &node_value =
664  Value( const_cast<typename Value::return_type &>(
665  this->value(vertices[i],
666  ElementAccessor<spacedim>(ele.orig_mesh(), ele.orig_element_idx()) ))
667  );
668  ASSERT_EQ(data_cache->n_comp(), node_value.n_rows()*node_value.n_cols()).error();
669  data_cache->store_value(node_index, node_value.mem_ptr() );
670  ++node_index;
671  }
672  }
673  }
674  break;
675  case OutputTime::ELEM_DATA: {
676  for(const auto & ele : *output_mesh )
677  {
678  unsigned int ele_index = ele.idx();
679  const Value &ele_value =
680  Value( const_cast<typename Value::return_type &>(
681  this->value(ele.centre(),
682  ElementAccessor<spacedim>(ele.orig_mesh(), ele.orig_element_idx()))
683  )
684  );
685  ASSERT_EQ(data_cache->n_comp(), ele_value.n_rows()*ele_value.n_cols()).error();
686  data_cache->store_value(ele_index, ele_value.mem_ptr() );
687  }
688  }
689  break;
691  std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->get_field_fe();
692 
693  if (field_fe_ptr) {
694  auto native_output_data_base = stream->prepare_compute_data<double>(this->name(), space_type,
695  (unsigned int)Value::NRows_, (unsigned int)Value::NCols_);
696  // try casting actual ElementDataCache
697  auto native_output_data = std::dynamic_pointer_cast<ElementDataCache<double>>(native_output_data_base);
698  field_fe_ptr->native_data_to_cache(*native_output_data);
699  } else {
700  WarningOut().fmt("Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->name());
701  }
702  }
703  break;
706  //should not happen
707  break;
708  }
709 }
710 
711 template<int spacedim, class Value>
712 std::shared_ptr< FieldFE<spacedim, Value> > Field<spacedim,Value>::get_field_fe() {
713  ASSERT_EQ_DBG(this->mesh()->region_db().size(), region_fields_.size()).error();
714  ASSERT(!this->shared_->bc_).error("FieldFE output of native data is supported only for bulk fields!");
715 
716  std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
717 
718  bool is_fe = (region_fields_.size()>0); // indicate if FieldFE is defined on all bulk regions
719  is_fe = is_fe && region_fields_[1] && (typeid(*region_fields_[1]) == typeid(FieldFE<spacedim, Value>));
720  for (unsigned int i=3; i<2*this->mesh()->region_db().bulk_size(); i+=2)
721  if (!region_fields_[i] || (region_fields_[i] != region_fields_[1])) {
722  is_fe = false;
723  break;
724  }
725  if (is_fe) {
726  field_fe_ptr = std::dynamic_pointer_cast< FieldFE<spacedim, Value> >( region_fields_[1] );
727  }
728 
729  return field_fe_ptr;
730 }
731 
732 
733 template<int spacedim, class Value>
734 void Field<spacedim, Value>::cache_allocate(std::shared_ptr<EvalPoints> eval_points) {
736 }
737 
738 
739 template<int spacedim, class Value>
741  auto update_cache_data = cache_map.update_cache_data();
742 
743  // Call cache_update of FieldAlgoBase descendants
744  std::unordered_map<unsigned int, unsigned int>::iterator reg_elm_it;
745  for (reg_elm_it=update_cache_data.region_cache_indices_range_.begin(); reg_elm_it!=update_cache_data.region_cache_indices_range_.end(); ++reg_elm_it) {
746  region_fields_[reg_elm_it->first]->cache_update(value_cache_, cache_map, reg_elm_it->first);
747  }
748 }
749 
750 
751 
752 
753 
754 #endif /* FIELD_IMPL_HH_ */
void check_initialized_region_fields_()
Definition: field.impl.hh:510
Classes for auxiliary output mesh.
Iterator< ValueType > begin() const
void cache_update(ElementCacheMap &cache_map) override
Implements FieldCommon::cache_update.
Definition: field.impl.hh:740
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:75
virtual bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name)
Definition: field.impl.hh:584
pair< double, FieldBasePtr > HistoryPoint
Pair: time, pointer to FieldBase instance.
Definition: field.hh:375
const ElementCacheMap * elm_cache_map() const
Definition: eval_subset.hh:335
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:332
bool is_jump_time_
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
Point accessor allow iterate over bulk quadrature points defined in local element coordinates...
Definition: eval_subset.hh:215
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Point accessor allow iterate over quadrature points of given side defined in local element coordinate...
Definition: eval_subset.hh:289
FieldFlag::Flags get_flags() const
static const Input::Type::Instance & get_input_type_instance(Input::Type::Selection value_selection=Input::Type::Selection())
unsigned int bulk_size() const
Definition: region.cc:269
Reader for (slightly) modified input files.
const UpdateCacheHelper & update_cache_data() const
Return update cache data helper.
std::string get_value_attribute() const override
Definition: field.impl.hh:425
void fill_data_cache(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream, std::shared_ptr< ElementDataCache< typename Value::element_type >> data_cache)
Fills acutally the data cache with field values, used in compute_field_data.
Definition: field.impl.hh:646
OutputTime::DiscreteSpace get_output_type() const
std::string name_
DHCellAccessor dh_cell() const
Return DH cell accessor.
Definition: eval_subset.hh:250
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:92
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
unsigned int component_index_
std::pair< double, double > limits() const
Store data of one initialization message.
Definition: field_common.hh:90
void store_value(unsigned int idx, const T *value)
Directing class of FieldValueCache.
Definition: mesh.h:78
Iterator< Ret > find(const string &key) const
void update_history(const TimeStep &time)
Definition: field.impl.hh:439
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: output_time.hh:122
Helper class that stores data of generic types.
Definition: type_generic.hh:89
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
void observe_output(std::shared_ptr< Observe > observe) override
Definition: field.impl.hh:377
double last_time_
unsigned int eval_point_idx() const
Return index in EvalPoints object.
Definition: eval_subset.hh:340
RegionSet union_set(std::vector< std::string > set_names) const
Definition: region.cc:482
const std::string & input_default() const
bool set_time(const TimeStep &time, LimitSide limit_side) override
Definition: field.impl.hh:269
const RegionDB & region_db() const
Definition: mesh.h:143
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
Class holds precomputed field values of selected element set.
void field_output(std::shared_ptr< OutputTime > stream) override
Definition: field.impl.hh:364
Class for declaration of the integral input data.
Definition: type_base.hh:490
Basic time management functionality for unsteady (and steady) solvers (class Equation).
virtual FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
Definition: field.impl.hh:572
IT::Instance get_input_type() override
Definition: field.impl.hh:163
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Field()
Definition: field.impl.hh:43
Class for declaration of inputs sequences.
Definition: type_base.hh:346
std::shared_ptr< SharedData > data_
Definition: field.hh:389
static constexpr bool value
Definition: json.hpp:87
arma::Mat< typename Value::element_type >::template fixed< Value::NRows_, Value::NCols_ > operator[](unsigned int i_cache_point) const
Return item of value_cache_ given by i_cache_point.
Definition: field.impl.hh:155
constexpr bool match(Mask mask) const
Definition: flag_array.hh:163
std::shared_ptr< SharedData > shared_
IteratorBase end() const
DHCellSide dh_cell_side() const
Return DH cell accessor.
Definition: eval_subset.hh:325
EI_Address ei_address() const
Definition: accessors.cc:178
bool opt_val(const string &key, Ret &value) const
unsigned int eval_point_idx() const
Return index in EvalPoints object.
Definition: eval_subset.hh:260
double time() const
std::shared_ptr< FieldFE< spacedim, Value > > get_field_fe()
Definition: field.impl.hh:712
const Armor::Array< elm_type > & data() const
Return data vector.
const std::string & name() const
bool ge(double other_time) const
unsigned int FieldEnum
Definition: field_values.hh:57
FieldFlag::Flags & flags()
Region find_id(unsigned int id, unsigned int dim) const
Definition: region.cc:181
const UnitSI & units() const
std::vector< std::string > get_and_check_operands(const Input::Array &operands) const
Definition: region.cc:313
T get_root_interface() const
Returns the root accessor.
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
IT::Array get_multifield_input_type() override
Definition: field.impl.hh:170
#define xprintf(...)
Definition: system.hh:93
std::shared_ptr< ControlField > no_check_control_field_
Definition: field.hh:399
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:103
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:434
LimitSide last_limit_side_
double end() const
virtual void value_list(const Armor::array &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
Definition: field.hh:448
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
std::vector< FieldBasePtr > region_fields_
Definition: field.hh:404
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
FieldResult
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
Definition: field.impl.hh:402
const ElementCacheMap * elm_cache_map() const
Definition: eval_subset.hh:255
Definition: system.hh:65
bool is_jump_time()
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
static std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > function_factory(const Input::AbstractRecord &rec, const struct FieldAlgoBaseInitData &init_data)
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:96
static constexpr unsigned int n_cached_elements
Number of cached elements which values are stored in cache.
std::vector< std::shared_ptr< FactoryBase > > factories_
Definition: field.hh:406
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
auto disable_where(const Field< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> Field &
Definition: field.impl.hh:180
static std::vector< MessageData > messages_data_
Vector of data of initialization messages.
boost::circular_buffer< HistoryPoint > RegionHistory
Nearest history of one region.
Definition: field.hh:377
void set_component_index(unsigned int idx)
bool is_constant(Region reg) override
Definition: field.impl.hh:220
void add_factory(std::shared_ptr< FactoryBase > factory)
Definition: field.impl.hh:566
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
Definition: field.impl.hh:229
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:296
Class OutputElement and its iterator OutputElementIterator on the output mesh.
bool gt(double other_time) const
const Mesh * mesh() const
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:258
FieldCommon & name(const string &name)
unsigned int n_comp() const
bool changed() const
void set_mesh(const Mesh &mesh) override
Definition: field.impl.hh:190
void set_history_changed()
Point accessor allow iterate over local Observe points.
Definition: observe.hh:325
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
bool is_valid() const
Returns false if the region has undefined/invalid value.
Definition: region.hh:78
const std::string & input_name() const
void copy_from(const FieldCommon &other) override
Definition: field.impl.hh:347
unsigned int n_comp() const
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:33
void cache_allocate(std::shared_ptr< EvalPoints > eval_points) override
Implements FieldCommon::cache_allocate.
Definition: field.impl.hh:734
const FieldValueCache< typename Value::element_type > & value_cache() const
returns reference to FieldValueCache.
Definition: field.hh:336
bool is_bc() const
void compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream)
Definition: field.impl.hh:623
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
void init(std::shared_ptr< EvalPoints > eval_points, unsigned int n_cache_elements)
Initialize cache.
Representation of one time step..
TimeStatus set_time_result_
Field & operator=(const Field &other)
Definition: field.impl.hh:105
static const unsigned int history_length_limit_
LimitSide
Definition: field_common.hh:62
void set_input_list(const Input::Array &list, const TimeGovernor &tg) override
Definition: field.impl.hh:592
#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
Value::return_type operator()(BulkPoint &p)
Definition: field.impl.hh:140
Definition: field.hh:60
FieldValueCache< typename Value::element_type > value_cache_
Definition: field.hh:411
unsigned int idx() const
Returns a global index of the region.
Definition: region.hh:82