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