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