18 #ifndef FIELD_IMPL_HH_
19 #define FIELD_IMPL_HH_
36 template<
int spacedim,
class Value>
42 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
43 this->
add_factory( std::make_shared<FactoryBase>() );
49 template<
int spacedim,
class Value>
56 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
59 this->
add_factory( std::make_shared<FactoryBase>() );
65 template<
int spacedim,
class Value>
71 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
81 template<
int spacedim,
class Value>
85 region_fields_(other.region_fields_),
86 factories_(other.factories_)
95 template<
int spacedim,
class Value>
99 ASSERT(other.
shared_->mesh_).error(
"Must call set_mesh before assign to other field.\n");
103 if (&other ==
this)
return *
this;
107 shared_->is_fully_initialized_ =
false;
129 template<
int spacedim,
class Value>
131 return FieldBaseType::get_input_type_instance(
shared_->input_element_selection_);
136 template<
int spacedim,
class Value>
138 ASSERT(
false).error(
"This method can't be used for Field");
146 template<
int spacedim,
class Value>
152 shared_->no_check_values_=value_list;
156 template<
int spacedim,
class Value>
161 THROW(ExcFieldMeshDifference() << EI_Field(
name()) );
167 region_fields_.resize(
mesh()->region_db().
size() );
169 data_->region_history_.resize(
mesh()->region_db().
size(), init_history );
186 template <
int spacedim,
class Value>
191 return ( region_field && region_field->is_constant_in_space() );
195 template<
int spacedim,
class Value>
201 ASSERT_PTR(field).error(
"Null field pointer.\n");
203 ASSERT_PTR(
mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before set_field().\n");
204 if (domain.size() == 0)
return;
210 for(
const Region ®: domain) {
211 RegionHistory ®ion_history = data_->region_history_[reg.idx()];
213 ASSERT( region_history.size() == 0 || region_history[0].first < hp.first)(hp.first)(region_history[0].first)
214 .error(
"Can not insert smaller time then last time in field's history.\n");
215 region_history.push_front(hp);
222 template<
int spacedim,
class Value>
229 set_field(domain, FieldBaseType::function_factory(a_rec, init_data),
time);
235 template<
int spacedim,
class Value>
238 ASSERT_PTR(
mesh() )(
name() ).error(
"NULL mesh pointer of field with given name. set_mesh must be called before.\n");
261 update_history(time_step);
262 check_initialized_region_fields_();
268 for(
const Region ®:
mesh()->region_db().get_region_set(
"ALL") ) {
269 auto rh = data_->region_history_[reg.idx()];
272 if (reg.is_boundary() !=
is_bc())
continue;
275 if ( rh.empty())
continue;
277 double last_time_in_history = rh.front().first;
278 unsigned int history_size=rh.size();
279 unsigned int i_history;
280 ASSERT( time_step.
ge(last_time_in_history) ).error(
"Setting field time back in history not fully supported yet!");
283 if ( time_step.
gt(last_time_in_history) ) {
295 i_history=min(i_history, history_size - 1);
296 ASSERT(i_history >= 0).error(
"Empty field history.");
299 auto new_ptr = rh.at(i_history).second;
300 if (new_ptr != region_fields_[reg.idx()]) {
301 region_fields_[reg.idx()]=new_ptr;
313 template<
int spacedim,
class Value>
316 .error(
"Can not copy to the non-input field.");
320 && this->
shared_->input_list_.size() != 0 )
return;
322 if (
typeid(other) ==
typeid(*this)) {
330 template<
int spacedim,
class Value>
338 this->compute_field_data( type, stream);
343 template<
int spacedim,
class Value>
346 typedef typename Value::element_type ElemType;
348 if (observe->point_ds()->size() == 0)
return;
351 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
353 unsigned int loc_point_time_index, ele_index;
355 loc_point_time_index = op_acc.loc_point_time_index();
356 ele_index = op_acc.observe_point().element_idx();
357 const Value &obs_value =
358 Value(
const_cast<typename Value::return_type &
>(
359 this->
value(op_acc.observe_point().global_coords(),
361 ASSERT_EQ(output_data.
n_comp(), obs_value.n_rows()*obs_value.n_cols()).error();
362 output_data.
store_value(loc_point_time_index, obs_value.mem_ptr());
368 template<
int spacedim,
class Value>
372 for(
Region ® : region_set) {
373 auto f = region_fields_[reg.idx()];
378 else if (fr != result_all)
391 template<
int spacedim,
class Value>
394 int nrows = Value::NRows_;
395 int ncols = Value::NCols_;
396 string type =
"Integer";
400 return fmt::format(
"{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
401 nrows, ncols, type, this->
limits().first, this->
limits().second);
405 template<
int spacedim,
class Value>
407 ASSERT_PTR(
mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before.\n");
411 if (
shared_->input_list_.size() != 0) {
420 if (actual_list_item.
opt_val(
"region", domain_name_array)) {
424 }
else if (actual_list_item.
opt_val(
"rid",
id)) {
428 }
catch (RegionDB::ExcUniqueRegionId &e) {
433 domain.push_back(region);
435 THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(
id) );
437 THROW(ExcMissingDomain()
442 for(
auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
443 FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *
this);
448 field_instance->set_mesh(
mesh() ,
is_bc() );
449 for(
const Region ®: domain) {
454 if( data_->region_history_[reg.idx()].size() == 0
455 || data_->region_history_[reg.idx()].back().first < input_time)
457 data_->region_history_[reg.idx()].push_front(
463 data_->region_history_[reg.idx()].back() =
476 template<
int spacedim,
class Value>
484 for(
const Region ® :
mesh()->region_db().get_region_set(
"ALL") )
485 if (reg.is_boundary() ==
is_bc()) {
487 if ( rh.empty() || ! rh[0].second)
496 !=
shared_->no_check_values_.end() )
499 if (
shared_->input_default_ !=
"") {
500 regions_to_init.push_back( reg );
502 xprintf(
UsrErr,
"Missing value of the input field '%s' ('%s') on region ID: %d label: %s.\n",
503 input_name().c_str(),
name().c_str(), reg.id(), reg.label().c_str() );
509 if ( regions_to_init.size() ) {
510 std::string region_list;
518 auto field_ptr = FieldBaseType::function_factory( a_rec , init_data );
520 for(
const Region ®: regions_to_init) {
521 data_->region_history_[reg.idx()]
523 region_list+=
" "+reg.label();
532 template<
int spacedim,
class Value>
534 factories_.push_back( factory );
538 template<
int spacedim,
class Value>
550 template<
int spacedim,
class Value>
558 template<
int spacedim,
class Value>
563 double time,last_time=0.0;
569 if ( (*rit)->is_active_field_descriptor( (*
it), this->input_name() ) ) {
572 if (
time < last_time) {
573 THROW( ExcNonascendingTime()
576 <<
it->ei_address());
589 template<
int spacedim,
class Value>
591 typedef typename Value::element_type ElemType;
594 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
598 if( ! output_data_base->is_dummy()){
599 auto output_data = std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_data_base);
603 }
catch(
const std::bad_cast& e){
608 stream->update_time(this->
time());
612 template<
int spacedim,
class Value>
614 std::shared_ptr<OutputTime> stream,
617 std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
624 unsigned int node_index = 0;
625 for(
const auto & ele : *output_mesh )
628 for(
unsigned int i=0; i < ele.n_nodes(); i++)
630 const Value &node_value =
631 Value(
const_cast<typename Value::return_type &
>(
632 this->
value(vertices[i],
635 ASSERT_EQ(data_cache->n_comp(), node_value.n_rows()*node_value.n_cols()).error();
636 data_cache->store_value(node_index, node_value.mem_ptr() );
643 for(
const auto & ele : *output_mesh )
645 unsigned int ele_index = ele.idx();
646 const Value &ele_value =
647 Value(
const_cast<typename Value::return_type &
>(
648 this->
value(ele.centre(),
652 ASSERT_EQ(data_cache->n_comp(), ele_value.n_rows()*ele_value.n_cols()).error();
653 data_cache->store_value(ele_index, ele_value.mem_ptr() );
658 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->
get_field_fe();
661 auto native_output_data_base = stream->prepare_compute_data<
double>(this->
name(), space_type,
662 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
664 auto native_output_data = std::dynamic_pointer_cast<ElementDataCache<double>>(native_output_data_base);
665 field_fe_ptr->native_data_to_cache(*native_output_data);
667 WarningOut().fmt(
"Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->
name());
678 template<
int spacedim,
class Value>
681 ASSERT(!this->
shared_->bc_).error(
"FieldFE output of native data is supported only for bulk fields!");
683 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
693 field_fe_ptr = std::dynamic_pointer_cast< FieldFE<spacedim, Value> >(
region_fields_[1] );