18 #ifndef MULTI_FIELD_IMPL_HH_
19 #define MULTI_FIELD_IMPL_HH_
39 template<
int spacedim,
class Value>
42 no_check_control_field_(nullptr)
46 this->
set_shape( Value::NRows_, Value::NCols_ );
51 template<
int spacedim,
class Value>
54 sub_fields_(other.sub_fields_),
55 full_input_list_(other.full_input_list_),
56 no_check_control_field_(other.no_check_control_field_)
59 this->
set_shape( Value::NRows_, Value::NCols_ );
64 template<
int spacedim,
class Value>
68 ASSERT_PTR(other.
shared_->mesh_).error(
"Must call set_mesh before assign to other field.\n");
69 ASSERT( !shared_->mesh_ || (shared_->mesh_==other.
shared_->mesh_))
70 .error(
"Assignment between multi fields with different meshes.\n");
71 ASSERT_GT( shared_->comp_names_.size(), 0).error(
"Vector of component names can't be empty!\n");
73 .error(
"Both multi fields must have same size of vectors of component names.\n");
76 if (&other ==
this)
return *
this;
81 shared_->comp_names_ = comp_names;
82 shared_->is_fully_initialized_ =
false;
88 this->multifield_ =
true;
89 this->shape_ = other.
shape_;
95 sub_fields_.reserve( other.
size() );
96 for (
unsigned int i=0; i<other.
size(); ++i) {
98 if (this->shared_->comp_names_[i].length() == 0)
99 THROW( Input::ExcInputMessage() << EI_Message(
"The field " + this->input_name()
100 +
" has set empty name of component.") );
102 sub_fields_[i].name_ = this->shared_->comp_names_[i] +
"_" + name();
106 THROW( ExcMessage() << EI_Message(
"Internal error. Assignment operator can't be used after call setup_component() method.") );
116 template<
int spacedim,
class Value>
126 template<
int spacedim,
class Value>
128 it::Array type =
it::Array( SubFieldBaseType::get_input_type_instance(shared_->input_element_selection_), 1);
133 template<
int spacedim,
class Value>
138 no_check_control_field_=&control_field;
139 shared_->no_check_values_=value_list;
144 template<
int spacedim,
class Value>
149 if (sub_fields_.size() == 0) {
154 set_time_result_ = TimeStatus::constant;
157 if (field.set_time(time, limit_side))
158 set_time_result_ = TimeStatus::changed;
159 is_jump_time_ = is_jump_time_ || field.is_jump_time();
161 return (set_time_result_ == TimeStatus::changed);
166 template<
int spacedim,
class Value>
169 if (shared_->mesh_ && shared_->mesh_ != &mesh) {
170 THROW(ExcFieldMeshDifference() << EI_Field(name()) );
173 shared_->mesh_ = &mesh;
177 template<
int spacedim,
class Value>
180 .error(
"Can not copy to the non-copy field.");
184 && this->shared_->input_list_.size() != 0 )
return;
186 if (
typeid(other) ==
typeid(*this)) {
188 this->operator=(other_field);
189 }
else if (
typeid(other) ==
typeid(SubFieldType)) {
190 auto const &other_field =
dynamic_cast< SubFieldType
const &
>(other);
191 sub_fields_.resize(1);
192 sub_fields_[0] = other_field;
198 template<
int spacedim,
class Value>
203 for (
unsigned long index=0; index < this->size(); index++) {
204 sub_fields_[index].compute_field_data( type, stream );
211 template<
int spacedim,
class Value>
214 for(
auto &field : sub_fields_) const_all = const_all && field.is_constant(reg);
218 template<
int spacedim,
class Value>
221 ASSERT(
true).error(
"Not used yet. Test it.");
224 for(
auto &field : sub_fields_) {
225 FieldResult sub_result = field.field_result(region_set);
229 result_all = sub_result;
232 else if (sub_result != result_all)
241 template<
int spacedim,
class Value>
244 int nrows = Value::NRows_;
245 int ncols = Value::NCols_;
246 string type =
"Integer";
250 return fmt::format(
"{{ \"subfields\": true, \"shape\": [ {}, {} ], \"type\": \"{}\", \"limit\": [ {}, {} ] }}",
251 nrows, ncols, type, this->limits().first, this->limits().second);
255 template<
int spacedim,
class Value>
257 unsigned int comp_size = this->shared_->comp_names_.size();
258 ASSERT_GT(comp_size, 0).error(
"Vector of component names is empty!\n");
259 ASSERT_PTR(this->shared_->mesh_).error(
"Mesh is not set!\n");
261 sub_fields_.reserve( comp_size );
262 for(
unsigned int i_comp=0; i_comp < comp_size; i_comp++)
264 sub_fields_.push_back(
SubFieldType(i_comp, name(), this->full_comp_name(i_comp)) );
265 sub_fields_[i_comp].units( units() );
266 if (no_check_control_field_ !=
nullptr && no_check_control_field_->size() == sub_fields_.size())
267 sub_fields_[i_comp].disable_where((*no_check_control_field_)[i_comp], shared_->no_check_values_);
268 sub_fields_[i_comp].set_mesh( *(shared_->mesh_) );
270 sub_fields_[i_comp].input_selection(shared_->input_element_selection_);
271 sub_fields_[i_comp].add_factory( std::make_shared<MultiFieldFactory>(i_comp) );
273 if (this->shared_->input_default_!=
"") {
274 sub_fields_[i_comp].shared_->input_default_ = this->shared_->input_default_;
277 sub_fields_[i_comp].flags_ = this->flags_;
278 sub_fields_[i_comp].set_input_list(this->full_input_list_, *tg_);
279 sub_fields_[i_comp].set_default_fieldset( *(this->shared_->default_fieldset_) );
285 template<
int spacedim,
class Value>
294 if (
it->opt_val(this->input_name(), mf_array) ) {
295 unsigned int comp_size = this->shared_->comp_names_.
size();
296 if (mf_array.
size() != 1 && mf_array.
size() != comp_size)
297 THROW( Exc_InvalidMultiFieldSize() << EI_MultiFieldName(this->input_name())
298 << EI_Size(mf_array.
size()) << EI_ExpectedSize(comp_size) <<
list.ei_address() );
302 this->full_input_list_ =
list;
306 list.copy_to(shared_->input_list_);
311 template<
int spacedim,
class Value>
318 unsigned int position = 0;
320 if (multifield_arr.
size() > 1)
321 while (
index_ != position) {
327 field_algo_base->set_component_idx(
index_);
328 return field_algo_base;
336 template<
int spacedim,
class Value>
342 template<
int spacedim,
class Value>
344 ASSERT_PERMANENT(
false).error(
"Set dependency of MultiField should be performed by individual components!\n");
350 template<
int spacedim,
class Value>
353 ASSERT_PERMANENT(
false).error(
"Cache reallocate of MultiField should be performed by individual components!\n");
357 template<
int spacedim,
class Value>
359 FMT_UNUSED unsigned int region_patch_idx)
const {
360 ASSERT_PERMANENT(
false).error(
"Cache update of MultiField should be performed by individual components!\n");
364 template<
int spacedim,
class Value>
370 unsigned int comp_size = this->
shared_->comp_names_.size();
371 ASSERT_GT(comp_size, 0).error(
"Vector of component names is empty!\n");
375 sub_fields_.reserve( comp_size );
376 for(
unsigned int i_comp=0; i_comp < comp_size; i_comp++)
381 sub_fields_[i_comp].set(field_vec[i_comp],
time, region_set_names);
386 template<
int spacedim,
class Value>
392 ASSERT_EQ(this->
shared_->comp_names_.size(), 1).error(
"Size of component names vector must be 1!\n");
395 sub_fields_.reserve(1);
399 sub_fields_[0].set(field,
time, region_set_names);
#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_GT(a, b)
Definition of comparative assert macro (Greater Than) only for debug mode.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Directing class of FieldValueCache.
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
FieldFlag::Flags flags_
Field flags. Default setting is "an equation input field, that can read from user input,...
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_shape(uint n_rows, uint n_cols)
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)
Class template representing a field with values dependent on: point, element, and region.
std::shared_ptr< FieldBaseType > FieldBasePtr
virtual Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name) override
Class for representation of a vector of fields of the same physical quantity.
std::string get_value_attribute() const override
Input::Array full_input_list_
Full list of input field descriptors from which the subfields of MultiField are set.
void copy_from(const FieldCommon &other) override
std::vector< const FieldCommon * > set_dependency(unsigned int i_reg) const override
void field_output(std::shared_ptr< OutputTime > stream, OutputTime::DiscreteSpace type) override
bool set_time(const TimeStep &time, LimitSide limit_side) override
void cache_reallocate(PatchInternals &patch_internals, unsigned int region_idx) const override
Implements FieldCommon::cache_reallocate.
MultiField & operator=(const MultiField &other)
void cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const override
Implements FieldCommon::cache_update.
unsigned int size() const
Number of subfields that compose the multi-field.
IT::Instance get_input_type() override
auto disable_where(const MultiField< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> MultiField &
std::vector< SubFieldType > sub_fields_
Subfields (items) of MultiField.
Field< spacedim, Value > SubFieldType
void set_input_list(const Input::Array &list, const TimeGovernor &tg) override
IT::Array get_multifield_input_type() override
void set_mesh(const Mesh &mesh) override
const MultiField< spacedim, typename FieldValue< spacedim >::Enum > * no_check_control_field_
void set(std::vector< typename Field< spacedim, Value >::FieldBasePtr > field_vec, double time, std::vector< std::string > region_set_names={"ALL"})
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
bool is_constant(Region reg) override
static const unsigned int N_DISCRETE_SPACES
Basic time management functionality for unsteady (and steady) solvers (class Equation).
Representation of one time step..
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
static constexpr bool value
std::string format(CStringRef format_str, ArgList args)
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Holds common data shared between GenericAssemblz and Assembly<dim> classes.