18 #ifndef FIELD_IMPL_HH_
19 #define FIELD_IMPL_HH_
41 template<
int spacedim,
class Value>
48 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
49 this->
add_factory( std::make_shared<FactoryBase>() );
56 this->
set_shape( Value::NRows_, Value::NCols_ );
60 template<
int spacedim,
class Value>
67 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
69 this->
add_factory( std::make_shared<FactoryBase>() );
75 this->
set_shape( Value::NRows_, Value::NCols_ );
80 template<
int spacedim,
class Value>
87 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
97 this->
set_shape( Value::NRows_, Value::NCols_ );
101 template<
int spacedim,
class Value>
105 region_fields_(other.region_fields_),
106 factories_(other.factories_),
107 value_cache_(other.value_cache_)
113 this->
set_shape( Value::NRows_, Value::NCols_ );
117 template<
int spacedim,
class Value>
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");
125 if (&other ==
this)
return *
this;
129 shared_->is_fully_initialized_ =
false;
135 this->multifield_ =
false;
142 this->shape_ = other.
shape_;
153 template<
int spacedim,
class Value>
160 template<
int spacedim,
class Value>
167 template<
int spacedim,
class Value>
168 typename Value::return_type
171 return Value::get_from_array( this->value_cache_, i_cache_point );
176 template<
int spacedim,
class Value>
178 return FieldBaseType::get_input_type_instance(shared_->input_element_selection_);
183 template<
int spacedim,
class Value>
193 template<
int spacedim,
class Value>
198 no_check_control_field_=std::make_shared<ControlField>(control_field);
199 shared_->no_check_values_=value_list;
203 template<
int spacedim,
class Value>
207 if (shared_->mesh_ && shared_->mesh_ != &in_mesh) {
208 THROW(ExcFieldMeshDifference() << EI_Field(name()) );
211 shared_->mesh_ = &in_mesh;
214 region_fields_.resize( mesh()->region_db().size() );
215 RegionHistory init_history(history_length_limit_);
216 data_->region_history_.resize( mesh()->region_db().size(), init_history );
218 if (no_check_control_field_) no_check_control_field_->set_mesh(in_mesh);
233 template <
int spacedim,
class Value>
235 ASSERT(this->set_time_result_ != TimeStatus::unknown).error(
"Unknown time status.\n");
238 return ( region_field && region_field->is_constant_in_space() );
242 template<
int spacedim,
class Value>
248 ASSERT_PTR(field).error(
"Null field pointer.\n");
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() );
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;
259 for(
const Region ®: domain) {
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);
267 set_history_changed();
272 template<
int spacedim,
class Value>
279 set(FieldBaseType::function_factory(a_rec, init_data), time, region_set_names);
284 template<
int spacedim,
class Value>
287 ASSERT_PTR( mesh() )( name() ).error(
"NULL mesh pointer of field with given name. set_mesh must be called before.\n");
291 if (time_step.
end() == last_time_) {
292 if ( ! is_jump_time() ||
293 limit_side == last_limit_side_) {
294 last_limit_side_ = limit_side;
299 last_time_=time_step.
end();
300 last_limit_side_ = limit_side;
303 if (no_check_control_field_) {
304 no_check_control_field_->set_time(time_step, limit_side);
307 if(set_time_result_ == TimeStatus::changed_forced)
308 set_time_result_ = TimeStatus::changed;
310 set_time_result_ = TimeStatus::constant;
313 update_history(time_step);
314 check_initialized_region_fields_();
320 for(
const Region ®: mesh()->region_db().get_region_set(
"ALL") ) {
321 auto rh = data_->region_history_[reg.
idx()];
324 if ( rh.empty())
continue;
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!");
332 if ( time_step.
gt(last_time_in_history) ) {
344 i_history=min(i_history, history_size - 1);
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;
356 if ( new_ptr->set_time(time_step) ) set_time_result_ = TimeStatus::changed;
364 template<
int spacedim,
class Value>
367 .error(
"Can not copy to the non-input field.");
371 && this->shared_->input_list_.size() != 0 )
return;
373 if (
typeid(other) ==
typeid(*this)) {
375 this->operator=(other_field);
381 template<
int spacedim,
class Value>
386 this->compute_field_data( type, stream);
391 template<
int spacedim,
class Value>
395 for(
Region ® : region_set) {
396 auto f = region_fields_[reg.
idx()];
401 else if (fr != result_all)
414 template<
int spacedim,
class Value>
417 int nrows = Value::NRows_;
418 int ncols = Value::NCols_;
419 string type =
"Integer";
423 return fmt::format(
"{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
424 nrows, ncols, type, this->limits().first, this->limits().second);
428 template<
int spacedim,
class Value>
430 ASSERT_PTR( mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before.\n");
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") ) ) ) {
438 const Input::Record & actual_list_item = shared_->input_list_[shared_->list_idx_];
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);
447 }
else if (actual_list_item.
opt_val(
"rid",
id)) {
450 region = mesh()->region_db().find_id(
id);
451 }
catch (RegionDB::ExcUniqueRegionId &e) {
456 domain.push_back(region);
458 THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(
id) );
460 THROW(ExcMissingDomain()
465 for(
auto rit = factories_.rbegin() ; rit != factories_.rend(); ++rit) {
466 FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *
this);
470 ASSERT_EQ( field_instance->n_comp() , shared_->n_comp_);
471 field_instance->set_mesh( mesh() );
472 for(
const Region ®: domain) {
477 if( data_->region_history_[reg.
idx()].size() == 0
478 || data_->region_history_[reg.
idx()].back().first < input_time)
480 data_->region_history_[reg.
idx()].push_front(
486 data_->region_history_[reg.
idx()].back() =
494 ++shared_->list_idx_;
499 template<
int spacedim,
class Value>
501 ASSERT_PTR(mesh()).error(
"Null mesh pointer.");
507 for(
const Region ® : mesh()->region_db().get_region_set(
"ALL") ) {
509 if ( rh.empty() || ! rh[0].second)
521 if (shared_->input_default_ !=
"") {
522 regions_to_init.push_back( reg );
524 THROW( ExcMissingFieldValue() << EI_FieldInputName(input_name()) << EI_FieldName(name())
525 << EI_RegId(reg.
id()) << EI_RegLabel(reg.
label()) );
531 if ( regions_to_init.size() ) {
532 std::string region_list;
534 string default_input=input_default();
535 auto input_type = get_input_type().make_instance().first;
540 auto field_ptr = FieldBaseType::function_factory( a_rec , init_data );
541 field_ptr->set_mesh( mesh() );
542 for(
const Region ®: regions_to_init) {
543 data_->region_history_[reg.
idx()]
545 region_list+=
" "+reg.
label();
554 template<
int spacedim,
class Value>
556 factories_.push_back( factory );
560 template<
int spacedim,
class Value>
572 template<
int spacedim,
class Value>
580 template<
int spacedim,
class Value>
585 double time,last_time=0.0;
591 if ( (*rit)->is_active_field_descriptor( (*
it), this->input_name() ) ) {
594 if (
time < last_time) {
595 THROW( ExcNonascendingTime()
598 <<
it->ei_address());
611 template<
int spacedim,
class Value>
613 typedef typename Value::element_type ElemType;
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);
621 template<
int spacedim,
class Value>
623 std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
629 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->
get_field_fe();
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(),
636 field_fe_ptr->get_dofhandler()->max_elem_dofs());
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);
641 WarningOut().fmt(
"Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->
name());
645 stream->update_time(this->
time());
650 template<
int spacedim,
class Value>
653 for (
unsigned int i=0; i<offsets.size(); ++i) {
654 if (offsets[i] == -1)
continue;
655 auto ret_value = Value::get_from_array(this->value_cache_, i);
662 template<
int spacedim,
class Value>
665 typedef typename Value::element_type ElemType;
667 std::shared_ptr<ElementDataCache<ElemType>> observe_data_cache =
668 std::dynamic_pointer_cast<ElementDataCache<ElemType>>(output_cache_base);
670 for (
unsigned int i=0; i<offsets.size(); ++i) {
671 if (offsets[i] == -1)
continue;
672 auto ret_value = Value::get_from_array(this->value_cache_, i);
674 observe_data_cache->store_value(offsets[i], ele_value.mem_ptr() );
679 template<
int spacedim,
class Value>
684 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
694 field_fe_ptr = std::dynamic_pointer_cast< FieldFE<spacedim, Value> >(
region_fields_[1] );
701 template<
int spacedim,
class Value>
709 template<
int spacedim,
class Value>
717 template<
int spacedim,
class Value>
724 template<
int spacedim,
class Value>
741 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_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
void cache_reallocate(PatchInternals &patch_internals, unsigned int region_idx) const override
Implements FieldCommon::cache_allocate.
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.
Holds common data shared between GenericAssemblz and Assembly<dim> classes.