Flow123d  DF_patch_fevalues-8016b85
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  // This is a VERY old menaingless assert. Let see if we can live without it.
345  // ASSERT(i_history >= 0).error("Empty field history.");
346 
347  // possibly update field pointer
348 
349  auto new_ptr = rh.at(i_history).second;
350  if (new_ptr != region_fields_[reg.idx()]) {
351  region_fields_[reg.idx()]=new_ptr;
352  set_time_result_ = TimeStatus::changed;
353  }
354  // let FieldBase implementation set the time
355  if ( new_ptr->set_time(time_step) ) set_time_result_ = TimeStatus::changed;
356 
357  }
358 
359  return changed();
360 }
361 
362 
363 template<int spacedim, class Value>
365  ASSERT( flags().match(FieldFlag::equation_input))(other.name())(this->name())
366  .error("Can not copy to the non-input field.");
367 
368  // do not use copy if the field have its own input
369  if ( flags().match(FieldFlag::declare_input)
370  && this->shared_->input_list_.size() != 0 ) return;
371 
372  if (typeid(other) == typeid(*this)) {
373  auto const &other_field = dynamic_cast< Field<spacedim, Value> const &>(other);
374  this->operator=(other_field);
375  }
376 }
377 
378 
379 
380 template<int spacedim, class Value>
381 void Field<spacedim, Value>::field_output(std::shared_ptr<OutputTime> stream, OutputTime::DiscreteSpace type)
382 {
383  // currently we cannot output boundary fields
384  ASSERT_LT( type, OutputTime::N_DISCRETE_SPACES ).error();
385  this->compute_field_data( type, stream);
386 }
387 
388 
389 
390 template<int spacedim, class Value>
392 
393  FieldResult result_all = result_none;
394  for(Region &reg : region_set) {
395  auto f = region_fields_[reg.idx()];
396  if (f) {
397  FieldResult fr = f->field_result();
398  if (result_all == result_none) // first region
399  result_all = fr;
400  else if (fr != result_all)
401  result_all = result_other; // if results from individual regions are different
402  } else return result_none; // if field is undefined on any region of the region set
403  }
404 
405  if (result_all == result_constant && region_set.size() > 1)
406  return result_other; // constant result for individual regions could be non-constant on the whole region set
407 
408  return result_all;
409 
410 }
411 
412 
413 template<int spacedim, class Value>
415 {
416  int nrows = Value::NRows_;
417  int ncols = Value::NCols_;
418  string type = "Integer";
420  type = "Double";
421 
422  return fmt::format("{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
423  nrows, ncols, type, this->limits().first, this->limits().second);
424 }
425 
426 
427 template<int spacedim, class Value>
429  ASSERT_PTR( mesh() ).error("Null mesh pointer, set_mesh() has to be called before.\n");
430 
431  // read input up to given time
432  double input_time;
433  if (shared_->input_list_.size() != 0) {
434  while( shared_->list_idx_ < shared_->input_list_.size()
435  && time.ge( input_time = time.read_time( shared_->input_list_[shared_->list_idx_].find<Input::Tuple>("time") ) ) ) {
436 
437  const Input::Record & actual_list_item = shared_->input_list_[shared_->list_idx_];
438  // get domain specification
439  RegionSet domain;
440  Input::Array domain_name_array;
441  unsigned int id;
442  if (actual_list_item.opt_val("region", domain_name_array)) {
443  std::vector<string> domain_names = mesh()->region_db().get_and_check_operands(domain_name_array);
444  domain = mesh()->region_db().union_set(domain_names);
445 
446  } else if (actual_list_item.opt_val("rid", id)) {
447  Region region;
448  try {
449  region = mesh()->region_db().find_id(id);
450  } catch (RegionDB::ExcUniqueRegionId &e) {
451  e << actual_list_item.ei_address();
452  throw;
453  }
454  if (region.is_valid())
455  domain.push_back(region);
456  else
457  THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(id) );
458  } else {
459  THROW(ExcMissingDomain()
460  << actual_list_item.ei_address() );
461  }
462 
463  // get field instance
464  for(auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
465  FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *this);
466  if (field_instance) // skip descriptors without related keys
467  {
468  // add to history
469  ASSERT_EQ( field_instance->n_comp() , shared_->n_comp_);
470  field_instance->set_mesh( mesh() );
471  for(const Region &reg: domain) {
472  // if region history is empty, add new field
473  // or if region history is not empty and the input_time is higher, add new field
474  // otherwise (region history is not empty and the input_time is the same),
475  // rewrite the region field
476  if( data_->region_history_[reg.idx()].size() == 0
477  || data_->region_history_[reg.idx()].back().first < input_time)
478  {
479  data_->region_history_[reg.idx()].push_front(
480  HistoryPoint(input_time, field_instance));
481  //DebugOut() << "Update history" << print_var(this->name()) << print_var(reg.label()) << print_var(input_time);
482  }
483  else
484  {
485  data_->region_history_[reg.idx()].back() =
486  HistoryPoint(input_time, field_instance);
487  }
488  }
489  break;
490  }
491  }
492 
493  ++shared_->list_idx_;
494  }
495  }
496 }
497 
498 template<int spacedim, class Value>
500  ASSERT_PTR(mesh()).error("Null mesh pointer.");
501  //if (shared_->is_fully_initialized_) return;
502 
503  // check there are no empty field pointers, collect regions to be initialized from default value
504  RegionSet regions_to_init; // empty vector
505 
506  for(const Region &reg : mesh()->region_db().get_region_set("ALL") ) {
507  RegionHistory &rh = data_->region_history_[reg.idx()];
508  if ( rh.empty() || ! rh[0].second) // empty region history
509  {
510  // test if check is turned on and control field is FieldConst
511 // if (no_check_control_field_ && no_check_control_field_->is_constant(reg) ) {
512 // // get constant enum value
513 // auto elm = ElementAccessor<spacedim>(mesh(), reg);
514 // FieldEnum value = no_check_control_field_->value(elm.centre(),elm);
515 // // check that the value is in the disable list
516 // if ( std::find(shared_->no_check_values_.begin(), shared_->no_check_values_.end(), value)
517 // != shared_->no_check_values_.end() )
518 // continue; // the field is not needed on this region
519 // }
520  if (shared_->input_default_ != "") { // try to use default
521  regions_to_init.push_back( reg );
522  } else {
523  THROW( ExcMissingFieldValue() << EI_FieldInputName(input_name()) << EI_FieldName(name())
524  << EI_RegId(reg.id()) << EI_RegLabel(reg.label()) );
525  }
526  }
527  }
528 
529  // possibly set from default value
530  if ( regions_to_init.size() ) {
531  std::string region_list;
532  // has to deal with fact that reader can not deal with input consisting of simple values
533  string default_input=input_default();
534  auto input_type = get_input_type().make_instance().first;
535  Input::ReaderToStorage reader( default_input, *input_type, Input::FileFormat::format_JSON );
536 
537  auto a_rec = reader.get_root_interface<Input::AbstractRecord>();
538  FieldAlgoBaseInitData init_data(input_name(), n_comp(), units(), limits(), flags());
539  auto field_ptr = FieldBaseType::function_factory( a_rec , init_data );
540  field_ptr->set_mesh( mesh() );
541  for(const Region &reg: regions_to_init) {
542  data_->region_history_[reg.idx()]
543  .push_front(HistoryPoint( 0.0, field_ptr) );
544  region_list+=" "+reg.label();
545  }
546  FieldCommon::messages_data_.push_back( MessageData(input_default(), name(), region_list) );
547 
548  }
549  //shared_->is_fully_initialized_ = true;
550 }
551 
552 
553 template<int spacedim, class Value>
554 void Field<spacedim,Value>::add_factory(const std::shared_ptr<FactoryBase> factory) {
555  factories_.push_back( factory );
556 }
557 
558 
559 template<int spacedim, class Value>
561  Input::AbstractRecord field_record;
562  if (rec.opt_val(field.input_name(), field_record)) {
563  FieldAlgoBaseInitData init_data(field.input_name(), field.n_comp(), field.units(), field.limits(), field.get_flags());
564  return FieldBaseType::function_factory(field_record, init_data );
565  }
566  else
567  return FieldBasePtr();
568 }
569 
570 
571 template<int spacedim, class Value>
573  return in_rec.find<Input::AbstractRecord>(input_name);
574 }
575 
576 
577 
578 
579 template<int spacedim, class Value>
581  if (! flags().match(FieldFlag::declare_input)) return;
582 
583  // check that times forms ascending sequence
584  double time,last_time=0.0;
585 
587  it != list.end();
588  ++it) {
589  for(auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
590  if ( (*rit)->is_active_field_descriptor( (*it), this->input_name() ) ) {
591  shared_->input_list_.push_back( Input::Record( *it ) );
592  time = tg.read_time( it->find<Input::Tuple>("time") );
593  if (time < last_time) {
594  THROW( ExcNonascendingTime()
595  << EI_Time(time)
596  << EI_Field(input_name())
597  << it->ei_address());
598  }
599  last_time = time;
600 
601  break;
602  }
603  }
604  }
605 
606 }
607 
608 
609 
610 template<int spacedim, class Value>
611 void Field<spacedim,Value>::set_output_data_cache(OutputTime::DiscreteSpace space_type, std::shared_ptr<OutputTime> stream) {
612  typedef typename Value::element_type ElemType;
613 
614  auto output_cache_base = stream->prepare_compute_data<ElemType>(this->name(), space_type,
615  (unsigned int)Value::NRows_, (unsigned int)Value::NCols_);
616  output_data_cache_ = std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_cache_base);
617 }
618 
619 
620 template<int spacedim, class Value>
621 void Field<spacedim,Value>::compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr<OutputTime> stream) {
622  std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
623  ASSERT(output_mesh);
624 
625  ASSERT_EQ(space_type, OutputTime::NATIVE_DATA);
626 
627  /* Copy data to array */
628  std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->get_field_fe();
629 
630  if (field_fe_ptr) {
631  auto native_output_data_base = stream->prepare_compute_data<double>(this->name(), space_type,
632  (unsigned int)Value::NRows_, (unsigned int)Value::NCols_,
633  typeid(field_fe_ptr->get_dofhandler()->ds()->fe()[0_d].get()).name(), // should be used better solution of fe_type setting
634  // e.g. method 'name()' of FiniteElement and descendants
635  field_fe_ptr->get_dofhandler()->max_elem_dofs());
636  // try casting actual ElementDataCache
637  auto native_output_data = std::dynamic_pointer_cast<ElementDataCache<double>>(native_output_data_base);
638  field_fe_ptr->native_data_to_cache(*native_output_data);
639  } else {
640  WarningOut().fmt("Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->name());
641  }
642 
643  /* Set the last time */
644  stream->update_time(this->time());
645 
646 }
647 
648 
649 template<int spacedim, class Value>
651 {
652  for (unsigned int i=0; i<offsets.size(); ++i) {
653  if (offsets[i] == -1) continue; // skip empty value
654  auto ret_value = Value::get_from_array(this->value_cache_, i);
655  const Value &ele_value = Value( ret_value );
656  output_data_cache_->store_value(offsets[i], ele_value.mem_ptr() );
657  }
658 }
659 
660 
661 template<int spacedim, class Value>
662 void Field<spacedim,Value>::fill_observe_value(std::shared_ptr<ElementDataCacheBase> output_cache_base, const std::vector<int> &offsets)
663 {
664  typedef typename Value::element_type ElemType;
665 
666  std::shared_ptr<ElementDataCache<ElemType>> observe_data_cache =
667  std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_cache_base);
668 
669  for (unsigned int i=0; i<offsets.size(); ++i) {
670  if (offsets[i] == -1) continue; // skip empty value
671  auto ret_value = Value::get_from_array(this->value_cache_, i);
672  const Value &ele_value = Value( ret_value );
673  observe_data_cache->store_value(offsets[i], ele_value.mem_ptr() );
674  }
675 }
676 
677 
678 template<int spacedim, class Value>
679 std::shared_ptr< FieldFE<spacedim, Value> > Field<spacedim,Value>::get_field_fe() {
680  ASSERT_EQ(this->mesh()->region_db().size(), region_fields_.size()).error();
681  //ASSERT(!this->shared_->bc_).error("FieldFE output of native data is supported only for bulk fields!");
682 
683  std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
684 
685  bool is_fe = (region_fields_.size()>0); // indicate if FieldFE is defined on all bulk regions
686  is_fe = is_fe && region_fields_[1] && (typeid(*region_fields_[1]) == typeid(FieldFE<spacedim, Value>));
687  for (unsigned int i=3; i<2*this->mesh()->region_db().bulk_size(); i+=2)
688  if (!region_fields_[i] || (region_fields_[i] != region_fields_[1])) {
689  is_fe = false;
690  break;
691  }
692  if (is_fe) {
693  field_fe_ptr = std::dynamic_pointer_cast< FieldFE<spacedim, Value> >( region_fields_[1] );
694  }
695 
696  return field_fe_ptr;
697 }
698 
699 
700 template<int spacedim, class Value>
701 void Field<spacedim, Value>::cache_reallocate(const ElementCacheMap &cache_map, unsigned int region_idx) const {
702  // Call cache_reinit of FieldAlgoBase descendant on appropriate region
703  if (region_fields_[region_idx] != nullptr)
704  region_fields_[region_idx]->cache_reinit(cache_map);
705 }
706 
707 
708 template<int spacedim, class Value>
709 void Field<spacedim, Value>::cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const {
710  unsigned int region_idx = cache_map.region_idx_from_chunk_position(region_patch_idx);
711  if (region_fields_[region_idx] != nullptr) // skips bounadry regions for bulk fields and vice versa
712  region_fields_[region_idx]->cache_update(value_cache_, cache_map, region_patch_idx);
713 }
714 
715 
716 template<int spacedim, class Value>
718  if (region_fields_[i_reg] != nullptr) return region_fields_[i_reg]->set_dependency(*this->shared_->default_fieldset_);
719  else return std::vector<const FieldCommon *>();
720 }
721 
722 
723 template<int spacedim, class Value>
725  return &value_cache_;
726 }
727 
728 
729 template<>
731  return nullptr;
732 }
733 
734 template<>
736  return nullptr;
737 }
738 
739 
740 template<int spacedim, class Value>
742  return &value_cache_;
743 }
744 
745 
746 template<>
748  return nullptr;
749 }
750 
751 template<>
753  return nullptr;
754 }
755 
756 
757 
758 
759 
760 #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:572
virtual FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
Definition: field.impl.hh:560
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:580
std::string get_value_attribute() const override
Definition: field.impl.hh:414
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:650
void cache_reallocate(const ElementCacheMap &cache_map, unsigned int region_idx) const override
Implements FieldCommon::cache_allocate.
Definition: field.impl.hh:701
void cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const override
Implements FieldCommon::cache_update.
Definition: field.impl.hh:709
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:662
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:364
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
Definition: field.impl.hh:391
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:428
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:381
std::vector< const FieldCommon * > set_dependency(unsigned int i_reg) const override
Definition: field.impl.hh:717
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:499
void add_factory(std::shared_ptr< FactoryBase > factory)
Definition: field.impl.hh:554
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:679
FieldValueCache< double > * value_cache() override
Implements FieldCommon::value_cache.
Definition: field.impl.hh:724
void compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream)
Definition: field.impl.hh:621
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:611
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