Flow123d  release_2.1.0-84-g6a13a75
output_time.impl.hh
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 output.h
15  * @brief Header: The functions for all outputs.
16  * @todo
17  * - remove Output, keep OutputTime only (done)
18  * - remove parameter mesh from static method OutputTime::output_stream (done)
19  * - move initialization of streams from hc_expolicit_sequantial to
20  * Aplication::Aplication() constructor (done)
21  * - OutputTime::register_XXX_data - should accept iterator to output record of particular equation, ask for presence of the key
22  * that has same name as the name of the quantity to output, extract the string with stream name from this key, find the stream
23  * and perform output.
24  *
25  * on input:
26  *
27  * { // darcy flow
28  * output = {
29  * pressure_nodes="nodal_data",
30  * pressure_elements="el_data"
31  * }
32  * }
33  *
34  * output_streams=[
35  * {name="nodal_data", ... },
36  * {name="el_data", ... }
37  * ]
38  *
39  * in code:
40  *
41  * Input::Record out_rec = in_rec.val<Input::Record>("output");
42  * OutputTime::register_node_data(mesh_, "pressure_nodes", "L", out_rec, node_pressure);
43  * OutputTime::register_elem_data(mesh_, "pressure_elements", "L", out_rec, ele_pressure);
44  * ...
45  *
46  * - use exceptions instead of returning result, see declaration of exceptions through DECLARE_EXCEPTION macro
47  * - move write_data from equations into coupling, write all streams
48  *
49  * =======================
50  * - Is it still necessary to split output into registration and write the data?
51  * Could we perform it at once? ... No, it doesn't make any sense.
52  * - Support for output of corner data into GMSH format (ElementNodeData section)
53  *
54  */
55 
56 #ifndef OUTPUT_H
57 #define OUTPUT_H
58 
59 #include <vector>
60 #include <string>
61 #include <ostream>
62 
63 #include "system/system.hh"
64 #include "mesh/mesh.h"
65 
66 #include "fields/field.hh"
67 #include "fields/multi_field.hh"
68 #include "system/exceptions.hh"
69 #include "io/output_time.hh"
70 
71 #include "io/output_data_base.hh"
72 #include "output_mesh.hh"
73 #include "io/output_data.hh"
74 #include "output_element.hh"
75 
76 
77 
78 
79 /**************************************************************************************************************
80  * OutputTime implementation
81  */
82 
83 template<int spacedim, class Value>
85  MultiField<spacedim, Value> &multi_field)
86 {
87  ASSERT_LT(type, N_DISCRETE_SPACES).error();
88 
89  DiscreteSpaceFlags flags = 1 << type;
90  for (unsigned long index=0; index < multi_field.size(); index++)
91  for(unsigned int ids=0; ids < N_DISCRETE_SPACES; ids++)
92  if (flags & (1 << ids))
93  this->compute_field_data( DiscreteSpace(ids), multi_field[index] );
94 
95 }
96 
97 
98 template<int spacedim, class Value>
100  Field<spacedim, Value> &field_ref)
101 {
102  ASSERT_LT(type, N_DISCRETE_SPACES).error();
103 
104  DiscreteSpaceFlags flags = 1 << type;
105  for(unsigned int ids=0; ids < N_DISCRETE_SPACES; ids++)
106  if (flags & (1 << ids))
107  this->compute_field_data( DiscreteSpace(ids), field_ref);
108 }
109 
110 
111 template<int spacedim, class Value>
113 {
114  /* It's possible now to do output to the file only in the first process */
115  if( this->rank != 0) {
116  /* TODO: do something, when support for Parallel VTK is added */
117  return;
118  }
119 
120  if(space_type == CORNER_DATA)
122 
123  // get possibly existing data for the same field, check both name and type
125  size[NODE_DATA] = output_mesh_->n_nodes();
126  size[ELEM_DATA] = output_mesh_->n_elements();
127  size[CORNER_DATA] = output_mesh_discont_->n_nodes();
128 
129  auto &od_vec=this->output_data_vec_[space_type];
130  auto it=std::find_if(od_vec.begin(), od_vec.end(),
131  [&field](OutputDataPtr ptr) { return (ptr->field_name == field.name()); });
132  if ( it == od_vec.end() ) {
133  od_vec.push_back( std::make_shared< OutputData<Value> >(field, size[space_type]) );
134  it=--od_vec.end();
135  }
136  OutputData<Value> &output_data = dynamic_cast<OutputData<Value> &>(*(*it));
137 
138 
139  /* Copy data to array */
140  switch(space_type) {
141  case NODE_DATA: {
142  // set output data to zero
143  vector<unsigned int> count(output_data.n_values, 0);
144  for(unsigned int idx=0; idx < output_data.n_values; idx++)
145  output_data.zero(idx);
146 
147  for(const auto & ele : *output_mesh_)
148  {
149  std::vector<Space<3>::Point> vertices = ele.vertex_list();
150  for(unsigned int i=0; i < ele.n_nodes(); i++)
151  {
152  unsigned int node_index = ele.node_index(i);
153  const Value &node_value =
154  Value( const_cast<typename Value::return_type &>(
155  field.value(vertices[i],
156  ElementAccessor<spacedim>(ele.orig_mesh(), ele.orig_element_idx(),false) ))
157  );
158  output_data.add(node_index, node_value);
159  count[node_index]++;
160  }
161  }
162 
163  // Compute mean values at nodes
164  for(unsigned int idx=0; idx < output_data.n_values; idx++)
165  output_data.normalize(idx, count[idx]);
166  }
167  break;
168  case CORNER_DATA: {
169  for(const auto & ele : *output_mesh_discont_)
170  {
171  std::vector<Space<3>::Point> vertices = ele.vertex_list();
172  for(unsigned int i=0; i < ele.n_nodes(); i++)
173  {
174  unsigned int node_index = ele.node_index(i);
175  const Value &node_value =
176  Value( const_cast<typename Value::return_type &>(
177  field.value(vertices[i],
178  ElementAccessor<spacedim>(ele.orig_mesh(), ele.orig_element_idx(),false) ))
179  );
180  output_data.store_value(node_index, node_value);
181  }
182  }
183  }
184  break;
185  case ELEM_DATA: {
186  for(const auto & ele : *output_mesh_)
187  {
188  unsigned int ele_index = ele.idx();
189  const Value &ele_value =
190  Value( const_cast<typename Value::return_type &>(
191  field.value(ele.centre(),
192  ElementAccessor<spacedim>(ele.orig_mesh(), ele.orig_element_idx(),false))
193  )
194  );
195  output_data.store_value(ele_index, ele_value);
196  }
197  }
198  break;
199  }
200 
201  /* Set the last time */
202  if(this->time < field.time()) {
203  this->time = field.time();
204  }
205 }
206 
207 
208 #endif
Classes for auxiliary output mesh.
double time
Definition: output_time.hh:208
std::shared_ptr< OutputMesh > output_mesh_
Output mesh.
Definition: output_time.hh:248
std::shared_ptr< OutputMeshDiscontinuous > output_mesh_discont_
Discontinuous (non-conforming) mesh. Used for CORNER_DATA.
Definition: output_time.hh:250
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: multi_field.hh:174
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
void register_data(const DiscreteSpace type, MultiField< spacedim, Value > &multi_field)
Generic method for registering output data stored in MultiField.
unsigned int n_values
This class is used for storing data that are copied from field.
Definition: output_data.hh:24
void zero(unsigned int idx)
Definition: output_data.cc:165
unsigned int DiscreteSpaceFlags
Definition: output_time.hh:219
double time() const
void add(unsigned int idx, const Value &value)
Definition: output_data.cc:157
void normalize(unsigned int idx, unsigned int divisor)
Definition: output_data.cc:173
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:89
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:350
void compute_field_data(DiscreteSpace type, Field< spacedim, Value > &field)
void compute_discontinuous_output_mesh()
Definition: output_time.cc:149
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:296
Class OutputElement and its iterator OutputElementIterator on the output mesh.
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:198
FieldCommon & name(const string &name)
Definition: field_common.hh:86
std::shared_ptr< OutputDataBase > OutputDataPtr
Definition: output_time.hh:191
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:55
void store_value(unsigned int idx, const Value &value)
Definition: output_data.cc:149