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
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 cache_reallocate(AssemblyInternals &asm_internals, unsigned int region_idx) const override
Implements FieldCommon::cache_allocate.
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.
Holds common data shared between GenericAssemblz and Assembly<dim> classes.
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Store data of one initialization message.