18 #ifndef FIELD_IMPL_HH_
19 #define FIELD_IMPL_HH_
40 template<
int spacedim,
class Value>
47 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
48 this->
add_factory( std::make_shared<FactoryBase>() );
55 this->
set_shape( Value::NRows_, Value::NCols_ );
59 template<
int spacedim,
class Value>
66 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
68 this->
add_factory( std::make_shared<FactoryBase>() );
74 this->
set_shape( Value::NRows_, Value::NCols_ );
79 template<
int spacedim,
class Value>
86 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
96 this->
set_shape( Value::NRows_, Value::NCols_ );
100 template<
int spacedim,
class Value>
104 region_fields_(other.region_fields_),
105 factories_(other.factories_),
106 value_cache_(other.value_cache_)
112 this->
set_shape( Value::NRows_, Value::NCols_ );
116 template<
int spacedim,
class Value>
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");
124 if (&other ==
this)
return *
this;
128 shared_->is_fully_initialized_ =
false;
134 this->multifield_ =
false;
141 this->shape_ = other.
shape_;
152 template<
int spacedim,
class Value>
159 template<
int spacedim,
class Value>
166 template<
int spacedim,
class Value>
167 typename Value::return_type
170 return Value::get_from_array( this->value_cache_, i_cache_point );
175 template<
int spacedim,
class Value>
177 return FieldBaseType::get_input_type_instance(shared_->input_element_selection_);
182 template<
int spacedim,
class Value>
192 template<
int spacedim,
class Value>
197 no_check_control_field_=std::make_shared<ControlField>(control_field);
198 shared_->no_check_values_=value_list;
202 template<
int spacedim,
class Value>
206 if (shared_->mesh_ && shared_->mesh_ != &in_mesh) {
207 THROW(ExcFieldMeshDifference() << EI_Field(name()) );
210 shared_->mesh_ = &in_mesh;
213 region_fields_.resize( mesh()->region_db().size() );
214 RegionHistory init_history(history_length_limit_);
215 data_->region_history_.resize( mesh()->region_db().size(), init_history );
217 if (no_check_control_field_) no_check_control_field_->set_mesh(in_mesh);
232 template <
int spacedim,
class Value>
234 ASSERT(this->set_time_result_ != TimeStatus::unknown).error(
"Unknown time status.\n");
237 return ( region_field && region_field->is_constant_in_space() );
241 template<
int spacedim,
class Value>
247 ASSERT_PTR(field).error(
"Null field pointer.\n");
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() );
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;
258 for(
const Region ®: domain) {
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);
266 set_history_changed();
271 template<
int spacedim,
class Value>
278 set(FieldBaseType::function_factory(a_rec, init_data), time, region_set_names);
283 template<
int spacedim,
class Value>
286 ASSERT_PTR( mesh() )( name() ).error(
"NULL mesh pointer of field with given name. set_mesh must be called before.\n");
290 if (time_step.
end() == last_time_) {
291 if ( ! is_jump_time() ||
292 limit_side == last_limit_side_) {
293 last_limit_side_ = limit_side;
298 last_time_=time_step.
end();
299 last_limit_side_ = limit_side;
302 if (no_check_control_field_) {
303 no_check_control_field_->set_time(time_step, limit_side);
306 if(set_time_result_ == TimeStatus::changed_forced)
307 set_time_result_ = TimeStatus::changed;
309 set_time_result_ = TimeStatus::constant;
312 update_history(time_step);
313 check_initialized_region_fields_();
319 for(
const Region ®: mesh()->region_db().get_region_set(
"ALL") ) {
320 auto rh = data_->region_history_[reg.
idx()];
323 if ( rh.empty())
continue;
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!");
331 if ( time_step.
gt(last_time_in_history) ) {
343 i_history=min(i_history, history_size - 1);
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;
355 if ( new_ptr->set_time(time_step) ) set_time_result_ = TimeStatus::changed;
363 template<
int spacedim,
class Value>
366 .error(
"Can not copy to the non-input field.");
370 && this->shared_->input_list_.size() != 0 )
return;
372 if (
typeid(other) ==
typeid(*this)) {
374 this->operator=(other_field);
380 template<
int spacedim,
class Value>
385 this->compute_field_data( type, stream);
390 template<
int spacedim,
class Value>
394 for(
Region ® : region_set) {
395 auto f = region_fields_[reg.
idx()];
400 else if (fr != result_all)
413 template<
int spacedim,
class Value>
416 int nrows = Value::NRows_;
417 int ncols = Value::NCols_;
418 string type =
"Integer";
422 return fmt::format(
"{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
423 nrows, ncols, type, this->limits().first, this->limits().second);
427 template<
int spacedim,
class Value>
429 ASSERT_PTR( mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before.\n");
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") ) ) ) {
437 const Input::Record & actual_list_item = shared_->input_list_[shared_->list_idx_];
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);
446 }
else if (actual_list_item.
opt_val(
"rid",
id)) {
449 region = mesh()->region_db().find_id(
id);
450 }
catch (RegionDB::ExcUniqueRegionId &e) {
455 domain.push_back(region);
457 THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(
id) );
459 THROW(ExcMissingDomain()
464 for(
auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
465 FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *
this);
469 ASSERT_EQ( field_instance->n_comp() , shared_->n_comp_);
470 field_instance->set_mesh( mesh() );
471 for(
const Region ®: domain) {
476 if( data_->region_history_[reg.
idx()].size() == 0
477 || data_->region_history_[reg.
idx()].back().first < input_time)
479 data_->region_history_[reg.
idx()].push_front(
485 data_->region_history_[reg.
idx()].back() =
493 ++shared_->list_idx_;
498 template<
int spacedim,
class Value>
500 ASSERT_PTR(mesh()).error(
"Null mesh pointer.");
506 for(
const Region ® : mesh()->region_db().get_region_set(
"ALL") ) {
508 if ( rh.empty() || ! rh[0].second)
520 if (shared_->input_default_ !=
"") {
521 regions_to_init.push_back( reg );
523 THROW( ExcMissingFieldValue() << EI_FieldInputName(input_name()) << EI_FieldName(name())
524 << EI_RegId(reg.
id()) << EI_RegLabel(reg.
label()) );
530 if ( regions_to_init.size() ) {
531 std::string region_list;
533 string default_input=input_default();
534 auto input_type = get_input_type().make_instance().first;
539 auto field_ptr = FieldBaseType::function_factory( a_rec , init_data );
540 field_ptr->set_mesh( mesh() );
541 for(
const Region ®: regions_to_init) {
542 data_->region_history_[reg.
idx()]
544 region_list+=
" "+reg.
label();
553 template<
int spacedim,
class Value>
555 factories_.push_back( factory );
559 template<
int spacedim,
class Value>
571 template<
int spacedim,
class Value>
579 template<
int spacedim,
class Value>
584 double time,last_time=0.0;
590 if ( (*rit)->is_active_field_descriptor( (*
it), this->input_name() ) ) {
593 if (
time < last_time) {
594 THROW( ExcNonascendingTime()
597 <<
it->ei_address());
610 template<
int spacedim,
class Value>
612 typedef typename Value::element_type ElemType;
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);
620 template<
int spacedim,
class Value>
622 std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
628 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->
get_field_fe();
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(),
635 field_fe_ptr->get_dofhandler()->max_elem_dofs());
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);
640 WarningOut().fmt(
"Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->
name());
644 stream->update_time(this->
time());
649 template<
int spacedim,
class Value>
652 for (
unsigned int i=0; i<offsets.size(); ++i) {
653 if (offsets[i] == -1)
continue;
654 auto ret_value = Value::get_from_array(this->value_cache_, i);
661 template<
int spacedim,
class Value>
664 typedef typename Value::element_type ElemType;
666 std::shared_ptr<ElementDataCache<ElemType>> observe_data_cache =
667 std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_cache_base);
669 for (
unsigned int i=0; i<offsets.size(); ++i) {
670 if (offsets[i] == -1)
continue;
671 auto ret_value = Value::get_from_array(this->value_cache_, i);
673 observe_data_cache->store_value(offsets[i], ele_value.mem_ptr() );
678 template<
int spacedim,
class Value>
683 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
693 field_fe_ptr = std::dynamic_pointer_cast< FieldFE<spacedim, Value> >(
region_fields_[1] );
700 template<
int spacedim,
class Value>
708 template<
int spacedim,
class Value>
716 template<
int spacedim,
class Value>
723 template<
int spacedim,
class Value>
740 template<
int spacedim,
class Value>
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
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.
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_
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()
void set_shape(uint n_rows, uint n_cols)
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)
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
virtual bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name)
virtual FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
Class template representing a field with values dependent on: point, element, and region.
FieldValueCache< typename Value::element_type > value_cache_
void set_input_list(const Input::Array &list, const TimeGovernor &tg) override
std::string get_value_attribute() const override
pair< double, FieldBasePtr > HistoryPoint
Pair: time, pointer to FieldBase instance.
auto disable_where(const Field< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> Field &
bool is_constant(Region reg) override
boost::circular_buffer< HistoryPoint > RegionHistory
Nearest history of one region.
void fill_data_value(const std::vector< int > &offsets) override
Implements FieldCommon::fill_data_value.
void cache_reallocate(const ElementCacheMap &cache_map, unsigned int region_idx) const override
Implements FieldCommon::cache_allocate.
void cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const override
Implements FieldCommon::cache_update.
bool set_time(const TimeStep &time, LimitSide limit_side) override
void fill_observe_value(std::shared_ptr< ElementDataCacheBase > output_cache_base, const std::vector< int > &offsets) override
Implements FieldCommon::fill_observe_value.
Value::return_type operator()(BulkPoint &p)
Return appropriate value to BulkPoint in FieldValueCache.
Value::return_type operator[](unsigned int i_cache_point) const
Return item of value_cache_ given by i_cache_point.
void copy_from(const FieldCommon &other) override
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
void set(FieldBasePtr field, double time, std::vector< std::string > region_set_names={"ALL"})
void update_history(const TimeStep &time)
IT::Instance get_input_type() override
void field_output(std::shared_ptr< OutputTime > stream, OutputTime::DiscreteSpace type) override
std::vector< const FieldCommon * > set_dependency(unsigned int i_reg) const override
std::shared_ptr< ElementDataCache< typename Value::element_type > > output_data_cache_
ElementDataCache used during field output, object is shared with OutputTime.
std::shared_ptr< SharedData > data_
void check_initialized_region_fields_()
void add_factory(std::shared_ptr< FactoryBase > factory)
std::shared_ptr< ControlField > no_check_control_field_
Field & operator=(const Field &other)
IT::Array get_multifield_input_type() override
std::vector< std::shared_ptr< FactoryBase > > factories_
std::shared_ptr< FieldBaseType > FieldBasePtr
std::shared_ptr< FieldFE< spacedim, Value > > get_field_fe()
FieldValueCache< double > * value_cache() override
Implements FieldCommon::value_cache.
void compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream)
void set_mesh(const Mesh &mesh) override
std::vector< FieldBasePtr > region_fields_
void set_output_data_cache(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream) override
const RegionDB & region_db() const
static const unsigned int N_DISCRETE_SPACES
unsigned int bulk_size() const
unsigned int idx() const
Returns a global index of the region.
bool is_valid() const
Returns false if the region has undefined/invalid value.
unsigned int id() const
Returns id of the region (using RegionDB)
std::string label() const
Returns label of the region (using RegionDB)
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
bool ge(double other_time) const
bool gt(double other_time) const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
static constexpr bool value
#define WarningOut()
Macro defining 'warning' record of log.
std::string format(CStringRef format_str, ArgList args)
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.