Flow123d  jenkins-Flow123d-linux-release-multijob-198
multi_field.impl.hh
Go to the documentation of this file.
1 /*
2  * multi_field.impl.hh
3  *
4  * Created on: Feb 13, 2014
5  * Author: jb
6  */
7 
8 #ifndef MULTI_FIELD_IMPL_HH_
9 #define MULTI_FIELD_IMPL_HH_
10 
11 
12 #include "multi_field.hh"
14 
15 namespace it = Input::Type;
16 
17 /******************************************************************************************
18  * Implementation of MultiField<...>
19  */
20 
21 template<int spacedim, class Value>
23 : FieldCommon()
24 {
25  this->multifield_ = true;
26 }
27 
28 
29 
30 template<int spacedim, class Value>
32  ASSERT(false, "This method can't be used for MultiField");
33 
34  static it::AbstractRecord a_rec = it::AbstractRecord();
35  return a_rec;
36 }
37 
38 
39 template<int spacedim, class Value>
41  static it::Record type= it::Record("MultiField", "Record for all time-space functions.")
43  .declare_key("component_names", it::Array( it::String() ), it::Default::read_time("Can be get from source of MultiField."),
44  "Names of MultiField components.")
45  .declare_key("common", transposed_field_.get_input_type(), it::Default::optional(),
46  "Supplied to components subtree.")
47  .declare_key("components", it::Array( sub_field_type_.get_input_type() ), it::Default::read_time("Converts from 'common' key."),
48  "Components of Multifield.");
49 
50  return type;
51 }
52 
53 
54 template<int spacedim, class Value>
56  const TimeStep &time)
57 {
58  // initialization of Multifield for first call
59  if (sub_fields_.size() == 0) {
60  set_up_components();
61  }
62 
63  // set time for sub fields
64  bool any=false;
65  for( SubFieldType &field : sub_fields_) {
66  if (field.set_time(time))
67  any = true;
68  }
69  return any;
70 }
71 
72 
73 
74 template<int spacedim, class Value>
76  // test if mesh is not set
77  if (shared_->mesh_ && shared_->mesh_ != &mesh) {
78  THROW(ExcFieldMeshDifference() << EI_Field(name()) );
79  }
80 
81  shared_->mesh_ = &mesh;
82 }
83 
84 
85 template<int spacedim, class Value>
87  if (typeid(other) == typeid(*this)) {
88  auto const &other_field = dynamic_cast< MultiField<spacedim, Value> const &>(other);
89  this->operator=(other_field);
90  } else if (typeid(other) == typeid(SubFieldType)) {
91  auto const &other_field = dynamic_cast< SubFieldType const &>(other);
92  sub_fields_.resize(1);
93  sub_fields_[0] = other_field;
94  }
95 }
96 
97 
98 
99 template<int spacedim, class Value>
101 {
102  // currently we cannot output boundary fields
103  if (!is_bc())
104  stream->register_data(this->output_type(), *this);
105 }
106 
107 
108 
109 
110 
111 template<int spacedim, class Value>
113  bool const_all=false;
114  for(auto field : sub_fields_) const_all = const_all || field.is_constant(reg);
115  return const_all;
116 }
117 
118 
119 
120 template<int spacedim, class Value>
122  ASSERT(this->shared_->comp_names_.size(), "Vector of component names is empty!\n");
123  ASSERT(this->shared_->mesh_, "Mesh is not set!\n");
124 
125  sub_fields_.resize( this->shared_->comp_names_.size() );
126  for(unsigned int i_comp=0; i_comp < size(); i_comp++)
127  {
128  sub_fields_[i_comp].units( units() );
129  sub_fields_[i_comp].set_mesh( *(shared_->mesh_) );
130  sub_fields_[i_comp].set_limit_side(this->limit_side_);
131  sub_fields_[i_comp].add_factory( std::make_shared<MultiFieldFactory>(i_comp) );
132  sub_fields_[i_comp].set_component_index(i_comp);
133 
134  if (this->shared_->comp_names_[i_comp].length() == 0)
135  sub_fields_[i_comp].name( name() );
136  else {
137  sub_fields_[i_comp].name_ = this->shared_->comp_names_[i_comp] + "_" + name();
138  sub_fields_[i_comp].shared_->input_name_ = name();
139  }
140 
141  sub_fields_[i_comp].set_input_list(this->shared_->input_list_);
142  }
143 }
144 
145 
146 
147 template<int spacedim, class Value>
149  Input::Record multifield_rec;
150  if (descriptor_rec.opt_val(field.input_name(), multifield_rec));
151  Input::Iterator<Input::AbstractRecord> it_common = multifield_rec.find<Input::AbstractRecord>("common");
152  Input::Iterator<Input::Array> it_components = multifield_rec.find<Input::Array>("components");
153  if (it_common && !it_components) {
154  it_common->transpose_to( multifield_rec, "components", spacedim );
155  it_components = multifield_rec.find<Input::Array>("components");
156  }
157 
158  ASSERT(it_components, "Failed to fill 'components' array of multifield: %s.", field.input_name().c_str());
159  ASSERT(index_ < it_components->size(), "Index of MultiField component is out of range.\n");
160 
161  unsigned int position = 0;
162  for (auto it = it_components->begin<Input::AbstractRecord>(); it != it_components->end(); ++it, ++position)
163  {
164  if (index_ == position) {
166  field_algo_base->set_component_idx(index_);
167  return field_algo_base;
168  }
169  }
170  return NULL;
171 }
172 
173 
174 
175 #endif /* MULTI_FIELD_IMPL_HH_ */
Common abstract parent of all Field&lt;...&gt; classes.
Definition: field_common.hh:47
Accessor to input data conforming to declared Array.
Definition: accessors.hh:558
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: multi_field.hh:116
IT::Record & get_multifield_input_type() override
void copy_from(const FieldCommon &other) override
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:52
bool set_time(const TimeStep &time) override
void register_data(const DiscreteSpace type, MultiField< spacedim, Value > &multi_field)
Generic method for registering output data stored in MultiField.
Definition: mesh.h:109
Iterator< Ret > find(const string &key) const
Class for declaration of inputs sequences.
Definition: type_base.hh:239
static Default optional()
Definition: type_record.hh:102
bool opt_val(const string &key, Ret &value) const
#define ASSERT(...)
Definition: global_defs.h:121
virtual Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &field)
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
static std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > function_factory(const Input::AbstractRecord &rec, unsigned int n_comp=0)
IT::AbstractRecord & get_input_type() override
void set_up_components()
The class for outputting data during time.
Definition: output_time.hh:32
Record & has_obligatory_type_key()
Definition: type_record.cc:367
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:448
static Default read_time(const std::string &description)
Definition: type_record.hh:77
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:56
bool is_constant(Region reg) override
unsigned int n_comp() const
Record type proxy class.
Definition: type_record.hh:169
void output(OutputTime *stream) override
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:45
const std::string & input_name() const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:34
Representation of one time step.
void set_mesh(const Mesh &mesh) override
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430