11 #include <boost/foreach.hpp>
22 template<
int spacedim,
class Value>
25 read_field_descriptor_hook( &read_field_descriptor )
30 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
34 template<
int spacedim,
class Value>
37 read_field_descriptor_hook( &read_field_descriptor )
41 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
48 template<
int spacedim,
class Value>
52 read_field_descriptor_hook( other.read_field_descriptor_hook )
64 template<
int spacedim,
class Value>
67 ASSERT(this->is_copy_,
"Try to assign to non-copy field '%s' from the field '%s'.", this->name().c_str(), other.
name().c_str());
68 ASSERT(other.
shared_->mesh_,
"Must call set_mesh before assign to other field.\n");
71 if (&other ==
this)
return *
this;
74 shared_->is_fully_initialized_ =
false;
87 this->set_mesh( *(shared_->mesh_) );
95 template<
int spacedim,
class Value>
105 if (is_enum_valued) {
106 ar_list.push_back(make_input_tree());
107 return ar_list.back();
109 return FieldBaseType::input_type;
116 template <
class FieldBaseType>
120 "NULL pointer to selection in Field::get_input_type(), while Value==FieldEnum.\n");
121 return FieldBaseType::get_input_type(sel);
125 template <
class FieldBaseType>
128 return FieldBaseType::get_input_type(
nullptr);
135 template<
int spacedim,
class Value>
138 "Can not use make_input_tree() for non-enum valued fields, use get_inout_type() instead.\n" );
139 return get_input_type_resolution<FieldBaseType>( shared_->element_selection_ ,boost::is_same<typename Value::element_type, FieldEnum>());
144 template<
int spacedim,
class Value>
149 no_check_control_field_=std::make_shared<ControlField>(control_field);
150 shared_->no_check_values_=value_list;
154 template<
int spacedim,
class Value>
158 if (shared_->mesh_ && shared_->mesh_ != &in_mesh) {
159 THROW(ExcFieldMeshDifference() << EI_Field(name()) );
162 shared_->mesh_ = &in_mesh;
165 region_fields_.resize( mesh()->region_db().size() );
167 data_->region_history_.resize( mesh()->region_db().size(), init_history );
169 if (no_check_control_field_) no_check_control_field_->set_mesh(in_mesh);
184 template <
int spacedim,
class Value>
200 template<
int spacedim,
class Value>
206 ASSERT(field,
"Null field pointer.\n");
210 ASSERT( mesh(),
"Null mesh pointer, set_mesh() has to be called before set_field().\n");
211 if (domain.size() == 0)
return;
214 field->set_mesh( mesh() , is_bc() );
217 for(
const Region ®: domain) {
218 RegionHistory ®ion_history = data_->region_history_[reg.idx()];
220 ASSERT( region_history.size() == 0 || region_history[0].first < hp.first,
"Can not insert smaller time %g then last time %g in field's history.\n",
221 hp.first, region_history[0].first );
222 region_history.push_front(hp);
224 set_history_changed();
229 template<
int spacedim,
class Value>
235 set_field(domain, FieldBaseType::function_factory(a_rec, n_comp()), time);
240 template<
int spacedim,
class Value>
244 if (rec.opt_val(field.name(), field_record))
245 return FieldBaseType::function_factory(field_record, field.n_comp() );
253 template<
int spacedim,
class Value>
256 ASSERT( mesh() ,
"NULL mesh pointer of field '%s'. set_mesh must be called before.\n",name().c_str());
257 ASSERT( limit_side_ !=
LimitSide::unknown,
"Must set limit side on field '%s' before calling set_time.\n",name().c_str());
260 if (time.
t() == last_time_)
return changed();
264 if (no_check_control_field_) {
265 no_check_control_field_->set_limit_side(limit_side_);
266 no_check_control_field_->set_time(time);
269 set_time_result_ = TimeStatus::constant;
272 update_history(time);
273 check_initialized_region_fields_();
277 for(
const Region ®: mesh()->region_db().get_region_set(
"ALL") ) {
278 auto rh = data_->region_history_[reg.idx()];
282 if (reg.is_boundary() == is_bc() && !rh.empty() ) {
283 double last_time_in_history = rh.front().first;
284 unsigned int history_size=rh.size();
285 unsigned int i_history;
287 if ( time.
gt(last_time_in_history) ) {
292 if (limit_side_ == LimitSide::right) {
298 i_history=min(i_history, history_size - 1);
299 ASSERT(i_history >= 0,
"Empty field history.");
301 auto new_ptr = rh.at(i_history).second;
302 if (new_ptr != region_fields_[reg.idx()]) {
303 region_fields_[reg.idx()]=new_ptr;
304 set_time_result_ = TimeStatus::changed;
308 if ( new_ptr->set_time(time.
t()) ) set_time_result_ = TimeStatus::changed;
319 template<
int spacedim,
class Value>
321 ASSERT(this->is_copy_,
"Try to call copy from the field '%s' to the non-copy field '%s'.", other.
name().c_str(), this->name().c_str());
322 if (
typeid(other) ==
typeid(*this)) {
324 this->operator=(other_field);
330 template<
int spacedim,
class Value>
340 template<
int spacedim,
class Value>
342 auto f = region_fields_[elm.
region().
idx()];
343 if (f)
return f->field_result();
349 template<
int spacedim,
class Value>
351 ASSERT( mesh(),
"Null mesh pointer, set_mesh() has to be called before.\n");
355 if (shared_->input_list_.size() != 0) {
356 while( shared_->list_it_ != shared_->input_list_.end()
357 && time.
ge( input_time = shared_->list_it_->val<
double>(
"time") ) ) {
361 std::string domain_name;
363 if (shared_->list_it_->opt_val(
"r_set", domain_name)) {
364 domain = mesh()->region_db().get_region_set(domain_name);
366 }
else if (shared_->list_it_->opt_val(
"region", domain_name)) {
368 Region region = mesh()->region_db().find_label(domain_name);
370 domain.push_back(region);
372 xprintf(
Warn,
"Unknown region with label: '%s'\n", domain_name.c_str());
374 }
else if (shared_->list_it_->opt_val(
"rid",
id)) {
376 Region region = mesh()->region_db().find_id(
id);
378 domain.push_back(region);
380 xprintf(
Warn,
"Unknown region with id: '%d'\n",
id);
382 THROW(ExcMissingDomain()
383 << EI_Field(this->name())
384 << shared_->list_it_->ei_address() );
387 if (domain.size() == 0) {
392 FieldBasePtr field_instance = read_field_descriptor_hook(*(shared_->list_it_), *
this);
397 field_instance->set_mesh( mesh() , is_bc() );
398 for(
const Region ®: domain) {
399 data_->region_history_[reg.idx()].push_front(
409 template<
int spacedim,
class Value>
411 ASSERT(mesh(),
"Null mesh pointer.");
412 if (shared_->is_fully_initialized_)
return;
417 for(
const Region ® : mesh()->region_db().get_region_set(
"ALL") )
418 if (reg.is_boundary() == is_bc()) {
420 if ( rh.empty() || ! rh[0].second)
423 if (no_check_control_field_ && no_check_control_field_->is_constant(reg) ) {
426 FieldEnum value = no_check_control_field_->value(elm.centre(),elm);
428 if ( std::find(shared_->no_check_values_.begin(), shared_->no_check_values_.end(), value)
429 != shared_->no_check_values_.end() )
432 if (shared_->default_ !=
"") {
433 regions_to_init.push_back( reg );
435 xprintf(
UsrErr,
"Missing value of the field '%s' on region ID: %d label: %s.\n",
436 name().c_str(), reg.id(), reg.label().c_str() );
442 if ( regions_to_init.size() ) {
443 xprintf(
Warn,
"Using default value '%s' for part of field '%s'.\n", input_default().c_str(), name().c_str());
446 string default_input=input_default();
447 auto input_type = get_input_type();
451 auto field_ptr = FieldBaseType::function_factory( a_rec , n_comp() );
452 field_ptr->set_mesh( mesh(), is_bc() );
453 for(
const Region ®: regions_to_init) {
454 data_->region_history_[reg.idx()]
458 shared_->is_fully_initialized_;
474 template<
int spacedim,
class Value>
481 template<
int spacedim,
class Value>
483 sub_fields_.resize( names.size() );
485 for(
unsigned int i_comp=0; i_comp < size(); i_comp++)
487 sub_fields_[i_comp].units( units() );
489 if (sub_names_[i_comp].length() == 0)
490 sub_fields_[i_comp].name( name() );
492 sub_fields_[i_comp].name( sub_names_[i_comp] +
"_" + name());
498 template<
int spacedim,
class Value>
503 template<
int spacedim,
class Value>
507 field.set_limit_side(side);
511 template<
int spacedim,
class Value>
517 if (field.set_time(time))
525 template<
int spacedim,
class Value>
527 shared_->mesh_ = &mesh;
528 for(
unsigned int i_comp=0; i_comp < size(); i_comp++)
529 sub_fields_[i_comp].set_mesh(mesh);
533 template<
int spacedim,
class Value>
535 if (
typeid(other) ==
typeid(*
this)) {
537 this->operator=(other_field);
539 auto const &other_field =
dynamic_cast< SubFieldType const &
>(other);
540 sub_fields_.resize(1);
541 sub_fields_[0] = other_field;
547 template<
int spacedim,
class Value>
559 template<
int spacedim,
class Value>
561 bool const_all=
false;
562 for(
auto field : sub_fields_) const_all = const_all || field.is_constant(reg);