18 #ifndef MULTI_FIELD_IMPL_HH_
19 #define MULTI_FIELD_IMPL_HH_
27 namespace it = Input::Type;
33 template<
int spacedim,
class Value>
36 no_check_control_field_(nullptr)
38 static_assert(Value::NRows_ == 1 && Value::NCols_ == 1,
"");
45 template<
int spacedim,
class Value>
48 sub_fields_(other.sub_fields_),
49 full_input_list_(other.full_input_list_),
50 no_check_control_field_(other.no_check_control_field_)
57 template<
int spacedim,
class Value>
61 OLD_ASSERT(other.
shared_->mesh_,
"Must call set_mesh before assign to other field.\n");
63 "Assignment between multi fields with different meshes.\n");
64 OLD_ASSERT( shared_->comp_names_.size(),
"Vector of component names can't be empty!\n");
66 "Both multi fields must have same size of vectors of component names.\n");
69 if (&other ==
this)
return *
this;
74 shared_->comp_names_ = comp_names;
75 shared_->is_fully_initialized_ =
false;
81 this->multifield_ =
true;
87 sub_fields_.reserve( other.
size() );
88 for (
unsigned int i=0; i<other.
size(); ++i) {
90 if (this->shared_->comp_names_[i].length() == 0)
91 THROW( Input::ExcInputMessage() << EI_Message(
"The field " + this->input_name()
92 +
" has set empty name of component.") );
94 sub_fields_[i].name_ = this->shared_->comp_names_[i] +
"_" + name();
98 THROW( ExcMessage() << EI_Message(
"Internal error. Assignment operator can't be used after call setup_component() method.") );
108 template<
int spacedim,
class Value>
110 OLD_ASSERT(
false,
"This method can't be used for MultiField");
118 template<
int spacedim,
class Value>
120 it::Array type =
it::Array( SubFieldBaseType::get_input_type_instance(shared_->input_element_selection_), 1);
125 template<
int spacedim,
class Value>
130 no_check_control_field_=&control_field;
131 shared_->no_check_values_=value_list;
136 template<
int spacedim,
class Value>
141 if (sub_fields_.size() == 0) {
146 set_time_result_ = TimeStatus::constant;
149 if (field.set_time(time, limit_side))
150 set_time_result_ = TimeStatus::changed;
151 is_jump_time_ = is_jump_time_ || field.is_jump_time();
153 return (set_time_result_ == TimeStatus::changed);
158 template<
int spacedim,
class Value>
161 if (shared_->mesh_ && shared_->mesh_ != &mesh) {
162 THROW(ExcFieldMeshDifference() << EI_Field(name()) );
165 shared_->mesh_ = &mesh;
169 template<
int spacedim,
class Value>
172 .error(
"Can not copy to the non-copy field.");
176 && this->shared_->input_list_.size() != 0 )
return;
178 if (
typeid(other) ==
typeid(*this)) {
180 this->operator=(other_field);
182 auto const &other_field =
dynamic_cast< SubFieldType const &
>(other);
183 sub_fields_.resize(1);
184 sub_fields_[0] = other_field;
190 template<
int spacedim,
class Value>
195 stream->register_data(this->output_type(), *
this);
200 template<
int spacedim,
class Value>
203 for(
auto &field : sub_fields_) observe->compute_field_values(field);
209 template<
int spacedim,
class Value>
212 for(
auto &field : sub_fields_) const_all = const_all && field.is_constant(reg);
216 template<
int spacedim,
class Value>
219 ASSERT_DBG(
true).error(
"Not used yet. Test it.");
222 for(
auto &field : sub_fields_) {
223 FieldResult sub_result = field.field_result(region_set);
227 result_all = sub_result;
230 else if (sub_result != result_all)
240 template<
int spacedim,
class Value>
242 unsigned int comp_size = this->shared_->comp_names_.size();
244 OLD_ASSERT(comp_size,
"Vector of component names is empty!\n");
245 OLD_ASSERT(this->shared_->mesh_,
"Mesh is not set!\n");
247 sub_fields_.reserve( comp_size );
248 for(
unsigned int i_comp=0; i_comp < comp_size; i_comp++)
250 if (this->shared_->comp_names_[i_comp].length() == 0)
253 full_name = this->shared_->comp_names_[i_comp] +
"_" + name();
256 sub_fields_.push_back(
SubFieldType(i_comp, name(), full_name, is_bc()) );
257 sub_fields_[i_comp].units( units() );
258 if (no_check_control_field_ !=
nullptr && no_check_control_field_->size() == sub_fields_.size())
259 sub_fields_[i_comp].disable_where((*no_check_control_field_)[i_comp], shared_->no_check_values_);
260 sub_fields_[i_comp].set_mesh( *(shared_->mesh_) );
262 sub_fields_[i_comp].input_selection(shared_->input_element_selection_);
263 sub_fields_[i_comp].add_factory( std::make_shared<MultiFieldFactory>(i_comp) );
265 if (this->shared_->input_default_!=
"") {
266 sub_fields_[i_comp].shared_->input_default_ = this->shared_->input_default_;
269 sub_fields_[i_comp].flags_ = this->flags_;
270 sub_fields_[i_comp].set_input_list(this->full_input_list_);
276 template<
int spacedim,
class Value>
285 if ( it->opt_val(this->input_name(), mf_array) ) {
286 unsigned int comp_size = this->shared_->comp_names_.
size();
287 if (mf_array.
size() != 1 && mf_array.
size() != comp_size)
288 THROW( Exc_InvalidMultiFieldSize() << EI_MultiFieldName(this->input_name())
289 << EI_Size(mf_array.
size()) << EI_ExpectedSize(comp_size) << list.
ei_address() );
293 this->full_input_list_ = list;
296 list.
copy_to(shared_->input_list_);
300 template<
int spacedim,
class Value>
303 for (
unsigned int i_comp=0; i_comp < size(); i_comp++) {
304 ret(i_comp, 0) = sub_fields_[i_comp].value(p,elm);
312 template<
int spacedim,
class Value>
316 for(
unsigned int i=0; i< point_list.size(); i++) {
317 value_list[i]=this->value(point_list[i], elm);
323 template<
int spacedim,
class Value>
330 unsigned int position = 0;
332 if (multifield_arr.
size() > 1)
333 while (
index_ != position) {
338 field_algo_base->set_component_idx(
index_);
339 return field_algo_base;
347 template<
int spacedim,
class Value>
void set_input_list(const Input::Array &list) override
IT::Instance get_input_type() override
Common abstract parent of all Field<...> classes.
auto disable_where(const MultiField< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> MultiField &
unsigned int size() const
Number of subfields that compose the multi-field.
bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name) override
void copy_from(const FieldCommon &other) override
Class template representing a field with values dependent on: point, element, and region...
unsigned int component_index_
const MultiField< spacedim, typename FieldValue< spacedim >::Enum > * no_check_control_field_
internal::ReturnType< NRows, NCols, ET >::return_type return_type
void output(std::shared_ptr< OutputTime > stream) override
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
MultiField & operator=(const MultiField &other)
Input::Array full_input_list_
Full list of input field descriptors from which the subfields of MultiField are set.
std::shared_ptr< SharedData > shared_
std::vector< SubFieldType > sub_fields_
Subfields (items) of MultiField.
virtual Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
static std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > function_factory(const Input::AbstractRecord &rec, unsigned int n_comp=0)
bool set_time(const TimeStep &time, LimitSide limit_side) override
LimitSide last_limit_side_
FieldResult field_result(RegionSet region_set) const override
Indicates special field states.
MultiField(bool bc=false)
FieldAlgorithmBase< spacedim, Value >::Point Point
std::shared_ptr< FieldBaseType > FieldBasePtr
bool is_constant(Region reg) override
virtual MultiFieldValue::return_type value(const Point &p, const ElementAccessor< spacedim > &elm) const
IT::Array get_multifield_input_type() override
FieldCommon & name(const string &name)
unsigned int n_comp() const
#define OLD_ASSERT_EQUAL(a, b)
Class for representation of a vector of fields of the same physical quantity.
const std::string & input_name() const
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Representation of one time step.
TimeStatus set_time_result_
void observe_output(std::shared_ptr< Observe > observe) override
void set_mesh(const Mesh &mesh) override
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename MultiFieldValue::return_type > &value_list) const