Reference documentation for deal.II version 9.3.2
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
data_out.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2021 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
18 
19 // We use some exceptions declared in this header
21 
23 
24 namespace Particles
25 {
26  template <int dim, int spacedim>
27  void
30  const std::vector<std::string> & data_component_names,
31  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
32  &data_component_interpretations_)
33  {
34  Assert(
35  data_component_names.size() == data_component_interpretations_.size(),
36  ExcMessage(
37  "When calling Particles::DataOut::build_patches with data component "
38  "names and interpretations you need to provide as many data component "
39  "names as interpretations. Provide the same name for components that "
40  "belong to a single vector or tensor."));
41 
42  if ((data_component_names.size() > 0) &&
43  (particles.n_locally_owned_particles() > 0))
44  {
45  Assert(
46  particles.begin()->has_properties(),
47  ExcMessage(
48  "You called Particles::DataOut::build_patches with data component "
49  "names and interpretations, but the particles do not seem to own "
50  "any properties."));
51 
52  Assert(
53  data_component_names.size() ==
54  particles.begin()->get_properties().size(),
55  ExcMessage(
56  "When calling Particles::DataOut::build_patches with data component "
57  "names and interpretations you need to provide as many data component "
58  "names as the particles have properties."));
59  }
60 
61  dataset_names.clear();
62  dataset_names.emplace_back("id");
63  dataset_names.insert(dataset_names.end(),
64  data_component_names.begin(),
65  data_component_names.end());
66 
67  data_component_interpretations.clear();
68  data_component_interpretations.emplace_back(
70  data_component_interpretations.insert(
71  data_component_interpretations.end(),
72  data_component_interpretations_.begin(),
73  data_component_interpretations_.end());
74 
75  const unsigned int n_property_components = data_component_names.size();
76  const unsigned int n_data_components = dataset_names.size();
77 
78  patches.resize(particles.n_locally_owned_particles());
79 
80  auto particle = particles.begin();
81  for (unsigned int i = 0; particle != particles.end(); ++particle, ++i)
82  {
83  patches[i].vertices[0] = particle->get_location();
84  patches[i].patch_index = i;
85  patches[i].n_subdivisions = 1;
86 
87  // We have one more data components than dataset_names (the particle id)
88  patches[i].data.reinit(n_data_components, 1);
89 
90  patches[i].data(0, 0) = particle->get_id();
91 
92  if (n_data_components > 1)
93  {
94  const ArrayView<double> properties = particle->get_properties();
95  for (unsigned int property_index = 0;
96  property_index < n_property_components;
97  ++property_index)
98  patches[i].data(property_index + 1, 0) =
99  properties[property_index];
100  }
101  }
102  }
103 
104 
105 
106  template <int dim, int spacedim>
107  const std::vector<DataOutBase::Patch<0, spacedim>> &
109  {
110  return patches;
111  }
112 
113 
114 
115  template <int dim, int spacedim>
116  std::vector<std::string>
118  {
119  return dataset_names;
120  }
121 
122 
123 
124  template <int dim, int spacedim>
125  std::vector<
126  std::tuple<unsigned int,
127  unsigned int,
128  std::string,
131  {
132  std::vector<
133  std::tuple<unsigned int,
134  unsigned int,
135  std::string,
137  ranges;
138 
139  // Make sure the data structures were set up correctly. Since they
140  // can only be filled by build_patches() above, they should have
141  // been checked already.
142  Assert(dataset_names.size() == data_component_interpretations.size(),
143  ExcInternalError());
144 
145  // collect the ranges of particle data
146  const unsigned int n_output_components =
147  data_component_interpretations.size();
148  unsigned int output_component = 0;
149  for (unsigned int i = 0; i < n_output_components; /* i is updated below */)
150  // see what kind of data we have here. note that for the purpose of the
151  // current function all we care about is vector data
152  switch (data_component_interpretations[i])
153  {
155  {
156  // Just move component forward by one
157  ++i;
158  ++output_component;
159 
160  break;
161  }
163  {
164  // ensure that there is a continuous number of next space_dim
165  // components that all deal with vectors
166  Assert(
167  i + spacedim <= n_output_components,
169  i, dataset_names[i]));
170  for (unsigned int dd = 1; dd < spacedim; ++dd)
171  Assert(
172  data_component_interpretations[i + dd] ==
175  ExcInvalidVectorDeclaration(i, dataset_names[i]));
176 
177  // all seems right, so figure out whether there is a common
178  // name to these components. if not, leave the name empty and
179  // let the output format writer decide what to do here
180  std::string name = dataset_names[i];
181  for (unsigned int dd = 1; dd < spacedim; ++dd)
182  if (name != dataset_names[i + dd])
183  {
184  name = "";
185  break;
186  }
187 
188  // Finally add a corresponding range.
189  //
190  // This sort of logic is also explained in some detail in
191  // DataOut::build_one_patch().
192  ranges.emplace_back(std::forward_as_tuple(
193  output_component,
194  output_component + spacedim - 1,
195  name,
197 
198  // increase the 'component' counter by the appropriate amount,
199  // same for 'i', since we have already dealt with all these
200  // components
201  output_component += spacedim;
202  i += spacedim;
203 
204  break;
205  }
206 
208  {
209  const unsigned int size = spacedim * spacedim;
210  // ensure that there is a continuous number of next
211  // spacedim*spacedim components that all deal with tensors
212  Assert(
213  i + size <= n_output_components,
215  i, dataset_names[i]));
216  for (unsigned int dd = 1; dd < size; ++dd)
217  Assert(
218  data_component_interpretations[i + dd] ==
221  ExcInvalidTensorDeclaration(i, dataset_names[i]));
222 
223  // all seems right, so figure out whether there is a common
224  // name to these components. if not, leave the name empty and
225  // let the output format writer decide what to do here
226  std::string name = dataset_names[i];
227  for (unsigned int dd = 1; dd < size; ++dd)
228  if (name != dataset_names[i + dd])
229  {
230  name = "";
231  break;
232  }
233 
234  // Finally add a corresponding range.
235  ranges.emplace_back(std::forward_as_tuple(
236  output_component,
237  output_component + size - 1,
238  name,
240 
241  // increase the 'component' counter by the appropriate amount,
242  // same for 'i', since we have already dealt with all these
243  // components
244  output_component += size;
245  i += size;
246  break;
247  }
248 
249  default:
250  Assert(false, ExcNotImplemented());
251  }
252 
253  return ranges;
254  }
255 
256 } // namespace Particles
257 
258 #include "data_out.inst"
259 
virtual const std::vector< DataOutBase::Patch< 0, spacedim > > & get_patches() const override
Definition: data_out.cc:108
virtual std::vector< std::tuple< unsigned int, unsigned int, std::string, DataComponentInterpretation::DataComponentInterpretation > > get_nonscalar_data_ranges() const override
Definition: data_out.cc:130
void build_patches(const Particles::ParticleHandler< dim, spacedim > &particles, const std::vector< std::string > &data_component_names={}, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretations={})
Definition: data_out.cc:28
virtual std::vector< std::string > get_dataset_names() const override
Definition: data_out.cc:117
particle_iterator begin() const
particle_iterator end() const
types::particle_index n_locally_owned_particles() const
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:396
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:397
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcInvalidTensorDeclaration(int arg1, std::string arg2)
#define Assert(cond, exc)
Definition: exceptions.h:1465
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcInvalidVectorDeclaration(int arg1, std::string arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)