Flow123d  jenkins-Flow123d-windows32-release-multijob-51
output_impl.hh
Go to the documentation of this file.
1 #ifndef OUTPUT_IMPL_HH
2 #define OUTPUT_IMPL_HH
3 
4 
5 
6 
7 template<int spacedim, class Value>
9  const RefType type,
10  MultiField<spacedim, Value> &multi_field)
11 {
12  for (unsigned long index=0; index < multi_field.size(); index++) {
13  OutputTime::register_data(in_rec, type, multi_field[index] );
14  }
15 }
16 
17 
18 template<int spacedim, class Value>
20  const RefType ref_type,
21  Field<spacedim, Value> &field_ref)
22 {
23  Field<spacedim,Value> *field = &field_ref;
24  string name_ = field->name();
25  OutputDataBase *output_data;
26  unsigned int item_count = 0, comp_count = 0, node_id;
27 
28  // TODO: do not try to find empty string and raise exception
29 
30  // Try to find record with output stream (the key is name of data)
31  Input::Iterator<string> stream_name_iter = in_rec.find<string>(name_);
32 
33  // If record was not found, then throw exception
34  if(!stream_name_iter) {
35  return;
36  }
37 
38  // Try to find existing output stream
39  OutputTime *output_time = OutputTime::output_stream_by_name(*stream_name_iter);
40 
41  /* It's possible now to do output to the file only in the first process */
42  if(output_time == NULL || output_time->rank != 0) {
43  /* TODO: do something, when support for Parallel VTK is added */
44  return;
45  }
46 
47  // TODO: remove const_cast after resolving problems with const Mesh.
48  Mesh *mesh = const_cast<Mesh *>(field->mesh());
49 
50  if(output_time->get_mesh() == NULL) {
51  output_time->set_mesh(mesh);
52  }
53 
54  ElementFullIter ele = ELEMENT_FULL_ITER(mesh, NULL);
55  Node *node;
56  int corner_index = 0;
57  int node_index = 0;
58  int ele_index = 0;
59 
60  output_data = output_time->output_data_by_field((FieldCommon*)field,
61  ref_type);
62 
63  switch(ref_type) {
64  case NODE_DATA:
65  item_count = mesh->n_nodes();
66  break;
67  case CORNER_DATA:
68  // Compute number of all corners
69  item_count = 0;
70  FOR_ELEMENTS(mesh, ele) {
71  item_count += ele->n_nodes();
72  }
73  break;
74  case ELEM_DATA:
75  item_count = mesh->n_elements();
76  break;
77  }
78 
79  if(output_data == NULL) {
80  /* This is problematic part, because of templates :-( */
81  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
82  output_data = (OutputDataBase*)new OutputData<int>(field, item_count, 1);
83  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
84  output_data = (OutputDataBase*)new OutputData<int>(field, item_count, 3);
85  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
86  output_data = (OutputDataBase*)new OutputData<unsigned int>(field, item_count, 1);
87  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
88  output_data = (OutputDataBase*)new OutputData<unsigned int>(field, item_count, 3);
89  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
90  output_data = (OutputDataBase*)new OutputData<double>(field, item_count, 1);
91  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
92  output_data = (OutputDataBase*)new OutputData<double>(field, item_count, 3);
93  } else {
94  /* TODO: this will not be necessary */
95  throw "Try to register unsupported data type.";
96  }
97 
98  switch(ref_type) {
99  case NODE_DATA:
100  output_time->node_data.push_back(output_data);
101  break;
102  case CORNER_DATA:
103  output_time->corner_data.push_back(output_data);
104  break;
105  case ELEM_DATA:
106  output_time->elem_data.push_back(output_data);
107  break;
108  }
109  }
110 
111  unsigned int *count = new unsigned int[item_count];
112 
113  /* Copy data to array */
114  switch(ref_type) {
115  case NODE_DATA:
116 
117  // Initialize arrays
118  for(node_id=0; node_id<item_count; node_id++) {
119  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
120  (*(OutputData<int>*)output_data)[node_id] = 0;
121  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
122  (*(OutputData<int>*)output_data)[node_id] = 0;
123  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
124  (*(OutputData<unsigned int>*)output_data)[node_id] = 0;
125  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
126  (*(OutputData<unsigned int>*)output_data)[node_id] = 0;
127  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
128  (*(OutputData<double>*)output_data)[node_id] = 0;
129  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
130  (*(OutputData<double>*)output_data)[node_id] = 0;
131  }
132  count[node_id] = 0;
133  }
134 
135  /* Copy data to temporary array */
136  FOR_ELEMENTS(mesh, ele) {
137  FOR_ELEMENT_NODES(ele, node_id) {
138  node = ele->node[node_id];
139  node_index = mesh->node_vector.index(ele->node[node_id]);
140  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
141  (*(OutputData<int>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
142  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
143  (*(OutputData<int>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
144  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
145  (*(OutputData<unsigned int>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
146  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
147  (*(OutputData<unsigned int>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
148  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
149  (*(OutputData<double>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
150  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
151  (*(OutputData<double>*)output_data)[node_index] += field->value(node->point(), mesh->element_accessor(ele_index));
152  }
153  count[mesh->node_vector.index(ele->node[node_id])]++;
154  }
155  }
156 
157  // Compute mean values at nodes
158  for(node_id=0; node_id<item_count; node_id++) {
159  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
160  (*(OutputData<int>*)output_data)[node_id] /= count[node_id];
161  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
162  (*(OutputData<int>*)output_data)[node_id] /= count[node_id];
163  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
164  (*(OutputData<unsigned int>*)output_data)[node_id] /= count[node_id];
165  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
166  (*(OutputData<unsigned int>*)output_data)[node_id] /= count[node_id];
167  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
168  (*(OutputData<double>*)output_data)[node_id] /= count[node_id];
169  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
170  (*(OutputData<double>*)output_data)[node_id] /= count[node_id];
171  }
172  }
173 
174  break;
175  case CORNER_DATA:
176  FOR_ELEMENTS(mesh, ele) {
177  FOR_ELEMENT_NODES(ele, node_id) {
178  node = ele->node[node_id];
179  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
180  (*(OutputData<int>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
181  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
182  (*(OutputData<int>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
183  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
184  (*(OutputData<unsigned int>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
185  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
186  (*(OutputData<unsigned int>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
187  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
188  (*(OutputData<double>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
189  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
190  (*(OutputData<double>*)output_data)[corner_index] = field->value(node->point(), mesh->element_accessor(ele_index));
191  }
192  corner_index++;
193  }
194  ele_index++;
195  }
196  break;
197  case ELEM_DATA:
198  FOR_ELEMENTS(mesh, ele) {
199  if(typeid(Value) == typeid(FieldValue<1>::Integer)) {
200  (*(OutputData<int>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
201  } else if(typeid(Value) == typeid(FieldValue<1>::IntVector)) {
202  (*(OutputData<int>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
203  } else if(typeid(Value) == typeid(FieldValue<1>::Enum)) {
204  (*(OutputData<unsigned int>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
205  } else if(typeid(Value) == typeid(FieldValue<1>::EnumVector)) {
206  (*(OutputData<unsigned int>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
207  } else if(typeid(Value) == typeid(FieldValue<1>::Scalar)) {
208  (*(OutputData<double>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
209  } else if(typeid(Value) == typeid(FieldValue<1>::Vector)) {
210  (*(OutputData<double>*)output_data)[ele_index] = field->value(ele->centre(), mesh->element_accessor(ele_index));
211  }
212  ele_index++;
213  }
214  break;
215  }
216 
217  /* Set the last time */
218  if(output_time->time < field->time()) {
219  output_time->time = field->time();
220  }
221 }
222 
223 
224 #endif
double time
The newest time of registered data.
Definition: output_time.hh:274
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:45
Common parent class for templated OutputData.
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:150
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: field.hh:365
Definition: nodes.hh:44
#define FOR_ELEMENTS(_mesh_, __i)
Definition: mesh.h:357
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:48
void register_data(const DiscreteSpace type, MultiField< spacedim, Value > &multi_field)
Generic method for registering output data stored in MultiField.
Definition: output.h:243
#define ELEMENT_FULL_ITER(_mesh_, i)
Definition: mesh.h:365
Definition: mesh.h:108
Iterator< Ret > find(const string &key) const
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:638
This class is used for storing data that are copied from field.
Definition: output.h:98
vector< OutputDataBase * > node_data
Definition: output_time.hh:267
Mesh * get_mesh(void)
Definition: output_time.hh:231
double time() const
unsigned int n_elements() const
Definition: mesh.h:137
void set_mesh(Mesh *_mesh)
Definition: output_time.hh:248
Accessor to the data with type Type::Record.
Definition: accessors.hh:308
vector< OutputDataBase * > elem_data
Definition: output_time.hh:269
unsigned int index(const T *pointer) const
Definition: sys_vector.hh:383
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:399
int rank
MPI rank of process (is tested in methods)
Definition: output_time.hh:261
The class for outputing data during time.
Definition: output_time.hh:37
Mesh * mesh
Definition: output_time.hh:174
const Mesh * mesh() const
FieldCommon & name(const string &name)
Definition: field_common.hh:71
unsigned int n_nodes() const
Definition: mesh.h:133
Class for representation of a vector of fields of the same physical quantity.
Definition: field.hh:309
arma::vec3 & point()
Definition: nodes.hh:80
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:196
vector< OutputDataBase * > corner_data
Definition: output_time.hh:268