Flow123d  release_2.2.0-914-gf1a3a4f
field_set.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file field_set.cc
15  * @brief
16  */
17 
18 #include "fields/field_set.hh"
19 #include "system/sys_profiler.hh"
21 #include <boost/algorithm/string/replace.hpp>
22 
23 
24 
25 FieldSet &FieldSet::operator +=(FieldCommon &add_field) {
26  FieldCommon *found_field = field(add_field.name());
27  if (found_field) {
28  OLD_ASSERT(&add_field==found_field, "Another field of the same name exists when adding field: %s\n",
29  add_field.name().c_str());
30  } else {
31  field_list.push_back(&add_field);
32  }
33  return *this;
34 }
35 
36 
37 
38 FieldSet &FieldSet::operator +=(const FieldSet &other) {
39  for(auto field_ptr : other.field_list) this->operator +=(*field_ptr);
40  return *this;
41 }
42 
43 
44 
45 FieldSet FieldSet::subset(std::vector<std::string> names) const {
46  FieldSet set;
47  for(auto name : names) set += (*this)[name];
48  return set;
49 }
50 
51 
52 
53 FieldSet FieldSet::subset( FieldFlag::Flags::Mask mask) const {
54  FieldSet set;
55  for(auto field : field_list)
56  if (field->flags().match(mask)) set += *field;
57  return set;
58 }
59 
60 
61 
62 Input::Type::Record FieldSet::make_field_descriptor_type(const std::string &equation_name) const {
63  string rec_name = equation_name + ":Data";
65  Input::Type::Record rec = Input::Type::Record(rec_name, desc)
67 
68  for(auto field : field_list) {
69  if ( field->flags().match(FieldFlag::declare_input) ) {
70  string description = field->description() + " (($[" + field->units().format_latex() + "]$))";
71 
72  // Adding units is not so simple.
73  // 1) It must be correct for Latex.
74  // 2) It should be consistent with rest of documentation.
75  // 3) Should be specified for all fields.
76  //if (units != "") description+= " [" +field->units() + "]";
77 
78  // TODO: temporary solution, see FieldCommon::multifield_
79 
80  std::shared_ptr<Input::Type::TypeBase> field_type_ptr;
81  if (field->is_multifield()) {
82  field_type_ptr = std::make_shared<Input::Type::Array>(field->get_multifield_input_type());
83  } else {
84  field_type_ptr = std::make_shared<Input::Type::Instance>(field->get_input_type());
85  }
86  ASSERT( field->units().is_def() )(field->input_name()).error("units not def.");
88  { {FlowAttribute::field_unit(), field->units().json() },
90  );
91  string default_val = field->input_default();
92  if (default_val != "") {
93  boost::replace_all(default_val, "\"", "\\\"");
94  key_attributes[FlowAttribute::field_default_value()] = "\"" + default_val + "\"";
95  }
96  rec.declare_key(field->input_name(), field_type_ptr, Input::Type::Default::optional(), description, key_attributes);
97  }
98 
99  }
100  return rec.close();
101 }
102 
103 
104 /*
105 Input::Type::Selection FieldSet::make_output_field_selection(const string &name, const string &desc)
106 {
107  namespace IT=Input::Type;
108  IT::Selection sel(name, desc);
109  int i=0;
110  // add value for each field excluding boundary fields
111  for( auto field : field_list)
112  {
113  if ( !field->is_bc() && field->flags().match( FieldFlag::allow_output) )
114  {
115  string desc = "Output of the field " + field->name() + " (($[" + field->units().format_latex()+"]$))";
116  if (field->description().length() > 0)
117  desc += " (" + field->description() + ").";
118  else
119  desc += ".";
120  DebugOut() << field->get_value_attribute();
121 
122  sel.add_value(i, field->name(), desc, { {FlowAttribute::field_value_shape(), field->get_value_attribute()} } );
123  i++;
124  }
125  }
126 
127  return sel;
128 }
129 */
130 
131 
132 void FieldSet::set_field(const std::string &dest_field_name, FieldCommon &source)
133 {
134  auto &field = (*this)[dest_field_name];
135  field.copy_from(source);
136 }
137 
138 
139 
140 FieldCommon *FieldSet::field(const std::string &field_name) const {
141  for(auto field : field_list)
142  if (field->name() ==field_name) return field;
143  return nullptr;
144 }
145 
146 
147 
148 FieldCommon &FieldSet::operator[](const std::string &field_name) const {
149  FieldCommon *found_field=field(field_name);
150  if (found_field) return *found_field;
151 
152  THROW(ExcUnknownField() << FieldCommon::EI_Field(field_name));
153  return *field_list[0]; // formal to prevent compiler warning
154 }
155 
156 
157 bool FieldSet::set_time(const TimeStep &time, LimitSide limit_side) {
158  bool changed_all=false;
159  for(auto field : field_list) changed_all = field->set_time(time, limit_side) || changed_all;
160  return changed_all;
161 }
162 
163 
164 
165 bool FieldSet::changed() const {
166  bool changed_all=false;
167  for(auto field : field_list) changed_all = changed_all || field->changed();
168  return changed_all;
169 }
170 
171 
172 
173 bool FieldSet::is_constant(Region reg) const {
174  bool const_all=true;
175  for(auto field : field_list) const_all = const_all && field->is_constant(reg);
176  return const_all;
177 }
178 
179 
181  bool is_jump = false;
182  for(auto field : field_list) is_jump = is_jump || field->is_jump_time();
183  return is_jump;
184 }
185 
186 
187 
188 // OBSOLETE method
190  const string &desc, const string & d_val) {
191  *this += field->name(name).description(desc).input_default(d_val);
192  return *field;
193 }
194 
195 
196 
197 std::ostream &operator<<(std::ostream &stream, const FieldSet &set) {
198  for(FieldCommon * field : set.field_list) {
199  stream << *field
200  << std::endl;
201  }
202  return stream;
203 }
std::vector< FieldCommon * > field_list
List of all fields.
Definition: field_set.hh:243
bool is_jump_time() const
Definition: field_set.cc:180
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:60
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:61
virtual void copy_from(const FieldCommon &other)=0
FieldCommon & operator[](const std::string &field_name) const
Definition: field_set.cc:148
virtual bool is_constant(Region reg)=0
virtual std::string get_value_attribute() const =0
virtual IT::Instance get_input_type()=0
virtual bool set_time(const TimeStep &time, LimitSide limit_side)=0
static string field_default_value()
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
static const std::string field_descriptor_record_description(const string &record_name)
Definition: field_common.cc:68
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
#define OLD_ASSERT(...)
Definition: global_defs.h:131
FieldCommon * field(const std::string &field_name) const
Definition: field_set.cc:140
FieldCommon & add_field(FieldCommon *field, const string &name, const string &desc, const string &d_val="")
Definition: field_set.cc:189
FieldCommon & input_default(const string &input_default)
static IT::Record field_descriptor_record(const string &record_name)
Definition: field_common.cc:55
std::map< std::string, json_string > attribute_map
Defines map of Input::Type attributes.
Definition: type_base.hh:107
void set_field(const std::string &dest_field_name, FieldCommon &source)
Definition: field_set.cc:132
static string field_value_shape()
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:490
bool is_multifield() const
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:215
bool is_jump_time()
FieldCommon & description(const string &description)
virtual IT::Array get_multifield_input_type()=0
bool set_time(const TimeStep &time, LimitSide limit_side)
Definition: field_set.cc:157
bool is_constant(Region reg) const
Definition: field_set.cc:173
FieldCommon & name(const string &name)
Definition: field_common.hh:97
static string field_unit()
bool changed() const
friend std::ostream & operator<<(std::ostream &stream, const FieldSet &set)
Definition: field_set.cc:197
Record type proxy class.
Definition: type_record.hh:182
FieldCommon & flags(FieldFlag::Flags::Mask mask)
const std::string & input_name() const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Representation of one time step..
bool changed() const
Definition: field_set.cc:165
LimitSide
Definition: field_common.hh:47
Input::Type::Record make_field_descriptor_type(const std::string &equation_name) const
Definition: field_set.cc:62
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
Definition: field_flag.hh:35