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