Flow123d  master-a4da60c
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"
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(AssemblyInternals &asm_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(asm_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
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 cache_reallocate(AssemblyInternals &asm_internals, unsigned int region_idx) const override
Implements FieldCommon::cache_allocate.
Definition: field.impl.hh:702
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.
Holds common data shared between GenericAssemblz and Assembly<dim> classes.
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Store data of one initialization message.