18 #ifndef FIELD_IMPL_HH_ 19 #define FIELD_IMPL_HH_ 21 #include <boost/foreach.hpp> 38 template<
int spacedim,
class Value>
44 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
45 this->
add_factory( std::make_shared<FactoryBase>() );
51 template<
int spacedim,
class Value>
58 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
61 this->
add_factory( std::make_shared<FactoryBase>() );
67 template<
int spacedim,
class Value>
73 shared_->n_comp_ = (Value::NRows_ ? 0 : 1);
75 this->
name_ = (name==
"") ? input_name : name;
83 template<
int spacedim,
class Value>
97 template<
int spacedim,
class Value>
101 ASSERT(other.
shared_->mesh_).error(
"Must call set_mesh before assign to other field.\n");
105 if (&other ==
this)
return *
this;
109 shared_->is_fully_initialized_ =
false;
131 template<
int spacedim,
class Value>
138 template<
int spacedim,
class Value>
140 ASSERT(
false).error(
"This method can't be used for Field");
148 template<
int spacedim,
class Value>
158 template<
int spacedim,
class Value>
163 THROW(ExcFieldMeshDifference() << EI_Field(
name()) );
171 data_->region_history_.resize(
mesh()->region_db().
size(), init_history );
188 template <
int spacedim,
class Value>
193 return ( region_field && region_field->is_constant_in_space() );
197 template<
int spacedim,
class Value>
203 ASSERT_PTR(field).error(
"Null field pointer.\n");
205 ASSERT_PTR(
mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before set_field().\n");
206 if (domain.size() == 0)
return;
212 for(
const Region ®: domain) {
215 ASSERT( region_history.size() == 0 || region_history[0].first < hp.first)(hp.first)(region_history[0].first)
216 .error(
"Can not insert smaller time then last time in field's history.\n");
217 region_history.push_front(hp);
224 template<
int spacedim,
class Value>
237 template<
int spacedim,
class Value>
240 ASSERT_PTR(
mesh() )(
name() ).error(
"NULL mesh pointer of field with given name. set_mesh must be called before.\n");
270 for(
const Region ®:
mesh()->region_db().get_region_set(
"ALL") ) {
271 auto rh =
data_->region_history_[reg.idx()];
274 if (reg.is_boundary() !=
is_bc())
continue;
277 if ( rh.empty())
continue;
279 double last_time_in_history = rh.front().first;
280 unsigned int history_size=rh.size();
281 unsigned int i_history;
282 ASSERT( time_step.
ge(last_time_in_history) ).error(
"Setting field time back in history not fully supported yet!");
285 if ( time_step.
gt(last_time_in_history) ) {
297 i_history=min(i_history, history_size - 1);
298 ASSERT(i_history >= 0).error(
"Empty field history.");
301 auto new_ptr = rh.at(i_history).second;
315 template<
int spacedim,
class Value>
318 .error(
"Can not copy to the non-input field.");
322 && this->
shared_->input_list_.size() != 0 )
return;
324 if (
typeid(other) ==
typeid(*this)) {
332 template<
int spacedim,
class Value>
345 template<
int spacedim,
class Value>
348 typedef typename Value::element_type ElemType;
350 if (observe->points().size() == 0)
return;
353 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
355 unsigned int i_data=0;
357 unsigned int ele_index = o_point.element_idx();
358 const Value &obs_value =
359 Value( const_cast<typename Value::return_type &>(
360 this->
value(o_point.global_coords(),
362 ASSERT_EQ(output_data.
n_comp(), obs_value.n_rows()*obs_value.n_cols()).error();
363 output_data.
store_value(i_data, obs_value.mem_ptr());
370 template<
int spacedim,
class Value>
374 for(
Region ® : region_set) {
380 else if (fr != result_all)
393 template<
int spacedim,
class Value>
396 int nrows = Value::NRows_;
397 int ncols = Value::NCols_;
398 string type =
"Integer";
402 return fmt::format(
"{{ \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
403 nrows, ncols, type, this->
limits().first, this->
limits().second);
407 template<
int spacedim,
class Value>
409 ASSERT_PTR(
mesh() ).error(
"Null mesh pointer, set_mesh() has to be called before.\n");
413 if (
shared_->input_list_.size() != 0) {
422 if (actual_list_item.
opt_val(
"region", domain_name_array)) {
426 }
else if (actual_list_item.
opt_val(
"rid",
id)) {
430 }
catch (RegionDB::ExcUniqueRegionId &e) {
435 domain.push_back(region);
437 THROW(RegionDB::ExcUnknownRegion() << RegionDB::EI_ID(
id) );
439 THROW(ExcMissingDomain()
445 FieldBasePtr field_instance = (*rit)->create_field(actual_list_item, *
this);
450 field_instance->set_mesh(
mesh() ,
is_bc() );
451 for(
const Region ®: domain) {
456 if(
data_->region_history_[reg.idx()].size() == 0
457 ||
data_->region_history_[reg.idx()].back().first < input_time)
459 data_->region_history_[reg.idx()].push_front(
465 data_->region_history_[reg.idx()].back() =
478 template<
int spacedim,
class Value>
486 for(
const Region ® :
mesh()->region_db().get_region_set(
"ALL") )
487 if (reg.is_boundary() ==
is_bc()) {
489 if ( rh.empty() || ! rh[0].second)
498 !=
shared_->no_check_values_.end() )
501 if (
shared_->input_default_ !=
"") {
502 regions_to_init.push_back( reg );
504 xprintf(
UsrErr,
"Missing value of the input field '%s' ('%s') on region ID: %d label: %s.\n",
505 input_name().c_str(),
name().c_str(), reg.id(), reg.label().c_str() );
511 if ( regions_to_init.size() ) {
512 std::string region_list;
522 for(
const Region ®: regions_to_init) {
523 data_->region_history_[reg.idx()]
525 region_list+=
" "+reg.label();
534 template<
int spacedim,
class Value>
540 template<
int spacedim,
class Value>
552 template<
int spacedim,
class Value>
560 template<
int spacedim,
class Value>
565 double time,last_time=0.0;
571 if ( (*rit)->is_active_field_descriptor( (*
it), this->input_name() ) ) {
574 if (time < last_time) {
575 THROW( ExcNonascendingTime()
578 <<
it->ei_address());
591 template<
int spacedim,
class Value>
593 typedef typename Value::element_type ElemType;
595 std::shared_ptr<OutputMeshBase> output_mesh = stream->get_output_mesh_ptr();
600 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
606 unsigned int node_index = 0;
607 for(
const auto & ele : *output_mesh )
610 for(
unsigned int i=0; i < ele.n_nodes(); i++)
612 const Value &node_value =
613 Value( const_cast<typename Value::return_type &>(
614 this->
value(vertices[i],
617 ASSERT_EQ(output_data.
n_comp(), node_value.n_rows()*node_value.n_cols()).error();
618 output_data.
store_value(node_index, node_value.mem_ptr() );
625 for(
const auto & ele : *output_mesh )
627 unsigned int ele_index = ele.idx();
628 const Value &ele_value =
629 Value( const_cast<typename Value::return_type &>(
630 this->
value(ele.centre(),
634 ASSERT_EQ(output_data.
n_comp(), ele_value.n_rows()*ele_value.n_cols()).error();
635 output_data.
store_value(ele_index, ele_value.mem_ptr() );
640 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr = this->
get_field_fe();
644 (
unsigned int)Value::NRows_, (
unsigned int)Value::NCols_);
645 field_fe_ptr->native_data_to_cache(native_output_data);
647 WarningOut().fmt(
"Field '{}' of native data space type is not of type FieldFE. Output will be skipped.\n", this->
name());
658 stream->update_time(this->
time());
663 template<
int spacedim,
class Value>
666 ASSERT(!this->
shared_->bc_).error(
"FieldFE output of native data is supported only for bulk fields!");
668 std::shared_ptr< FieldFE<spacedim, Value> > field_fe_ptr;
void check_initialized_region_fields_()
Classes for auxiliary output mesh.
Common abstract parent of all Field<...> classes.
virtual bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name)
pair< double, FieldBasePtr > HistoryPoint
Pair: time, pointer to FieldBase instance.
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
unsigned int size() const
Number of subfields that compose the multi-field.
FieldFlag::Flags get_flags() const
static const Input::Type::Instance & get_input_type_instance(Input::Type::Selection value_selection=Input::Type::Selection())
unsigned int bulk_size() const
std::string get_value_attribute() const override
OutputTime::DiscreteSpace get_output_type() const
Class template representing a field with values dependent on: point, element, and region...
std::string format(CStringRef format_str, ArgList args)
unsigned int component_index_
std::pair< double, double > limits() const
Store data of one initialization message.
void store_value(unsigned int idx, const T *value)
void update_history(const TimeStep &time)
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
void observe_output(std::shared_ptr< Observe > observe) override
RegionSet union_set(std::vector< std::string > set_names) const
const std::string & input_default() const
bool set_time(const TimeStep &time, LimitSide limit_side) override
const RegionDB & region_db() const
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
void field_output(std::shared_ptr< OutputTime > stream) override
Basic time management functionality for unsteady (and steady) solvers (class Equation).
virtual FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
IT::Instance get_input_type() override
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
std::shared_ptr< SharedData > data_
static constexpr bool value
constexpr bool match(Mask mask) const
std::shared_ptr< SharedData > shared_
std::shared_ptr< FieldFE< spacedim, Value > > get_field_fe()
const std::string & name() const
bool ge(double other_time) const
FieldFlag::Flags & flags()
Region find_id(unsigned int id, unsigned int dim) const
const UnitSI & units() const
std::vector< std::string > get_and_check_operands(const Input::Array &operands) const
IT::Array get_multifield_input_type() override
std::shared_ptr< ControlField > no_check_control_field_
static const unsigned int N_DISCRETE_SPACES
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
LimitSide last_limit_side_
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
std::vector< FieldBasePtr > region_fields_
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
static std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > function_factory(const Input::AbstractRecord &rec, const struct FieldAlgoBaseInitData &init_data)
std::shared_ptr< FieldBaseType > FieldBasePtr
std::vector< std::shared_ptr< FactoryBase > > factories_
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
auto disable_where(const Field< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> Field &
static std::vector< MessageData > messages_data_
Vector of data of initialization messages.
boost::circular_buffer< HistoryPoint > RegionHistory
Nearest history of one region.
void set_component_index(unsigned int idx)
bool is_constant(Region reg) override
void add_factory(std::shared_ptr< FactoryBase > factory)
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Class OutputElement and its iterator OutputElementIterator on the output mesh.
bool gt(double other_time) const
const Mesh * mesh() const
#define WarningOut()
Macro defining 'warning' record of log.
FieldCommon & name(const string &name)
unsigned int n_comp() const
void set_mesh(const Mesh &mesh) override
void set_history_changed()
bool is_valid() const
Returns false if the region has undefined/invalid value.
const std::string & input_name() const
void copy_from(const FieldCommon &other) override
unsigned int n_comp() const
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
void compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr< OutputTime > stream)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Representation of one time step..
TimeStatus set_time_result_
Field & operator=(const Field &other)
static const unsigned int history_length_limit_
void set_input_list(const Input::Array &list, const TimeGovernor &tg) override
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
unsigned int idx() const
Returns a global index of the region.