Reference documentation for deal.II version 9.1.0-pre
data_out_dof_data.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2018 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 
16 #ifndef dealii_data_out_dof_data_h
17 #define dealii_data_out_dof_data_h
18 
19 
20 
21 #include <deal.II/base/config.h>
22 
23 #include <deal.II/base/data_out_base.h>
24 #include <deal.II/base/smartpointer.h>
25 
26 #include <deal.II/dofs/dof_handler.h>
27 
28 #include <deal.II/fe/mapping.h>
29 
30 #include <deal.II/grid/tria.h>
31 
32 #include <deal.II/hp/fe_collection.h>
33 #include <deal.II/hp/fe_values.h>
34 #include <deal.II/hp/mapping_collection.h>
35 #include <deal.II/hp/q_collection.h>
36 
37 #include <deal.II/numerics/data_component_interpretation.h>
38 #include <deal.II/numerics/data_postprocessor.h>
39 
40 #include <memory>
41 
42 DEAL_II_NAMESPACE_OPEN
43 
44 namespace Exceptions
45 {
50  namespace DataOutImplementation
51  {
56  int,
57  << "The number of subdivisions per patch, " << arg1
58  << ", is not valid. It needs to be greater or equal to "
59  "one, or zero if you want it to be determined "
60  "automatically.");
61 
66  "For the operation you are attempting, you first need to "
67  "tell the DataOut or related object which DoFHandler or "
68  "triangulation you would like to work on.");
69 
74  "For the operation you are attempting, you first need to "
75  "tell the DataOut or related object which DoFHandler "
76  "you would like to work on.");
77 
82  int,
83  int,
84  int,
85  << "The vector has size " << arg1
86  << " but the DoFHandler object says that there are " << arg2
87  << " degrees of freedom and there are " << arg3
88  << " active cells. The size of your vector needs to be"
89  << " either equal to the number of degrees of freedom, or"
90  << " equal to the number of active cells.");
96  std::string,
97  size_t,
98  << "Please use only the characters [a-zA-Z0-9_<>()] for" << std::endl
99  << "description strings since some graphics formats will only accept these."
100  << std::endl
101  << "The string you gave was <" << arg1
102  << ">, within which the invalid character is <" << arg1[arg2] << ">."
103  << std::endl);
109  "When attaching a triangulation or DoFHandler object, it is "
110  "not allowed if old data vectors are still referenced. If "
111  "you want to reuse an object of the current type, you first "
112  "need to call the 'clear_data_vector()' function.");
117  int,
118  int,
119  << "You have to give one name per component in your "
120  << "data vector. The number you gave was " << arg1
121  << ", but the number of components is " << arg2 << ".");
126  "While merging sets of patches, the two sets to be merged "
127  "need to refer to data that agrees on the names of the "
128  "various variables represented. In other words, you "
129  "cannot merge sets of patches that originate from "
130  "entirely unrelated simulations.");
135  "While merging sets of patches, the two sets to be merged "
136  "need to refer to data that agrees on the number of "
137  "subdivisions and other properties. In other words, you "
138  "cannot merge sets of patches that originate from "
139  "entirely unrelated simulations.");
140 
142  int,
143  std::string,
144  << "When declaring that a number of components in a data "
145  << "set to be output logically form a vector instead of "
146  << "simply a set of scalar fields, you need to specify "
147  << "this for all relevant components. Furthermore, "
148  << "vectors must always consist of exactly <dim> "
149  << "components. However, the vector component at "
150  << "position " << arg1 << " with name <" << arg2
151  << "> does not satisfy these conditions.");
152 
154  int,
155  std::string,
156  << "When declaring that a number of components in a data "
157  << "set to be output logically form a tensor instead of "
158  << "simply a set of scalar fields, you need to specify "
159  << "this for all relevant components. Furthermore, "
160  << "tensors must always consist of exactly <dim*dim> "
161  << "components. However, the tensor component at "
162  << "position " << arg1 << " with name <" << arg2
163  << "> does not satisfy these conditions.");
164 
165  } // namespace DataOutImplementation
166 } // namespace Exceptions
167 
168 
169 namespace internal
170 {
171  namespace DataOutImplementation
172  {
196  enum class ComponentExtractor
197  {
198  real_part,
199  imaginary_part
200  };
201 
202 
216  template <typename DoFHandlerType>
218  {
219  public:
225  DataEntryBase(const DoFHandlerType * dofs,
226  const std::vector<std::string> &names,
227  const std::vector<
229  &data_component_interpretation);
230 
236  DataEntryBase(const DoFHandlerType *dofs,
238  *data_postprocessor);
239 
243  virtual ~DataEntryBase() = default;
244 
249  virtual double
250  get_cell_data_value(const unsigned int cell_number,
251  const ComponentExtractor extract_component) const = 0;
252 
257  virtual void
258  get_function_values(
259  const FEValuesBase<DoFHandlerType::dimension,
260  DoFHandlerType::space_dimension> &fe_patch_values,
261  const ComponentExtractor extract_component,
262  std::vector<double> &patch_values) const = 0;
263 
269  virtual void
270  get_function_values(
271  const FEValuesBase<DoFHandlerType::dimension,
272  DoFHandlerType::space_dimension> &fe_patch_values,
273  const ComponentExtractor extract_component,
274  std::vector<::Vector<double>> &patch_values_system) const = 0;
275 
280  virtual void
281  get_function_gradients(
282  const FEValuesBase<DoFHandlerType::dimension,
283  DoFHandlerType::space_dimension> &fe_patch_values,
284  const ComponentExtractor extract_component,
286  &patch_gradients) const = 0;
287 
293  virtual void
294  get_function_gradients(
295  const FEValuesBase<DoFHandlerType::dimension,
296  DoFHandlerType::space_dimension> &fe_patch_values,
297  const ComponentExtractor extract_component,
298  std::vector<std::vector<Tensor<1, DoFHandlerType::space_dimension>>>
299  &patch_gradients_system) const = 0;
300 
305  virtual void
306  get_function_hessians(
307  const FEValuesBase<DoFHandlerType::dimension,
308  DoFHandlerType::space_dimension> &fe_patch_values,
309  const ComponentExtractor extract_component,
310  std::vector<Tensor<2, DoFHandlerType::space_dimension>> &patch_hessians)
311  const = 0;
312 
318  virtual void
319  get_function_hessians(
320  const FEValuesBase<DoFHandlerType::dimension,
321  DoFHandlerType::space_dimension> &fe_patch_values,
322  const ComponentExtractor extract_component,
323  std::vector<std::vector<Tensor<2, DoFHandlerType::space_dimension>>>
324  &patch_hessians_system) const = 0;
325 
330  virtual bool
331  is_complex_valued() const = 0;
332 
336  virtual void
337  clear() = 0;
338 
343  virtual std::size_t
344  memory_consumption() const = 0;
345 
350 
354  const std::vector<std::string> names;
355 
361  const std::vector<
364 
369  SmartPointer<
370  const ::DataPostprocessor<DoFHandlerType::space_dimension>>
372 
379  unsigned int n_output_variables;
380  };
381 
382 
399  template <int dim, int spacedim>
401  {
403  const unsigned int n_datasets,
404  const unsigned int n_subdivisions,
405  const std::vector<unsigned int> &n_postprocessor_outputs,
406  const Mapping<dim, spacedim> & mapping,
407  const std::vector<
408  std::shared_ptr<::hp::FECollection<dim, spacedim>>>
409  & finite_elements,
410  const UpdateFlags update_flags,
411  const bool use_face_values);
412 
413  ParallelDataBase(const ParallelDataBase &data);
414 
415  template <typename DoFHandlerType>
416  void
417  reinit_all_fe_values(
418  std::vector<std::shared_ptr<DataEntryBase<DoFHandlerType>>> &dof_data,
419  const typename ::Triangulation<dim, spacedim>::cell_iterator
420  & cell,
421  const unsigned int face = numbers::invalid_unsigned_int);
422 
424  get_present_fe_values(const unsigned int dataset) const;
425 
426  void
427  resize_system_vectors(const unsigned int n_components);
428 
429  const unsigned int n_datasets;
430  const unsigned int n_subdivisions;
431 
432  DataPostprocessorInputs::Scalar<spacedim> patch_values_scalar;
433  DataPostprocessorInputs::Vector<spacedim> patch_values_system;
434  std::vector<std::vector<::Vector<double>>> postprocessed_values;
435 
436  const ::hp::MappingCollection<dim, spacedim> mapping_collection;
437  const std::vector<
438  std::shared_ptr<::hp::FECollection<dim, spacedim>>>
439  finite_elements;
440  const UpdateFlags update_flags;
441 
442  std::vector<std::shared_ptr<::hp::FEValues<dim, spacedim>>>
443  x_fe_values;
444  std::vector<std::shared_ptr<::hp::FEFaceValues<dim, spacedim>>>
445  x_fe_face_values;
446  };
447  } // namespace DataOutImplementation
448 } // namespace internal
449 
450 
451 // TODO: Most of the documentation of DataOut_DoFData applies to DataOut.
452 
594 template <typename DoFHandlerType,
595  int patch_dim,
596  int patch_space_dim = patch_dim>
597 class DataOut_DoFData : public DataOutInterface<patch_dim, patch_space_dim>
598 {
599 public:
604  using cell_iterator =
605  typename Triangulation<DoFHandlerType::dimension,
606  DoFHandlerType::space_dimension>::cell_iterator;
607  using active_cell_iterator = typename Triangulation<
608  DoFHandlerType::dimension,
609  DoFHandlerType::space_dimension>::active_cell_iterator;
610 
611 public:
621  {
626 
631 
635  type_automatic
636  };
637 
641  DataOut_DoFData();
642 
646  virtual ~DataOut_DoFData() override;
647 
656  void
657  attach_dof_handler(const DoFHandlerType &);
658 
668  void
669  attach_triangulation(const Triangulation<DoFHandlerType::dimension,
670  DoFHandlerType::space_dimension> &);
671 
737  template <class VectorType>
738  void
739  add_data_vector(
740  const VectorType & data,
741  const std::vector<std::string> &names,
742  const DataVectorType type = type_automatic,
743  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
744  &data_component_interpretation = std::vector<
746 
763  template <class VectorType>
764  void
765  add_data_vector(
766  const VectorType & data,
767  const std::string & name,
768  const DataVectorType type = type_automatic,
769  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
770  &data_component_interpretation = std::vector<
772 
787  template <class VectorType>
788  void
789  add_data_vector(
790  const DoFHandlerType & dof_handler,
791  const VectorType & data,
792  const std::vector<std::string> &names,
793  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
794  &data_component_interpretation = std::vector<
796 
797 
802  template <class VectorType>
803  void
804  add_data_vector(
805  const DoFHandlerType &dof_handler,
806  const VectorType & data,
807  const std::string & name,
808  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
809  &data_component_interpretation = std::vector<
811 
840  template <class VectorType>
841  void
842  add_data_vector(const VectorType &data,
844  &data_postprocessor);
845 
852  template <class VectorType>
853  void
854  add_data_vector(const DoFHandlerType &dof_handler,
855  const VectorType & data,
857  &data_postprocessor);
858 
865  void
866  clear_data_vectors();
867 
878  void
879  clear_input_data_references();
880 
904  template <typename DoFHandlerType2>
905  void
906  merge_patches(
909 
916  virtual void
917  clear();
918 
923  std::size_t
924  memory_consumption() const;
925 
926 protected:
931 
935  SmartPointer<const Triangulation<DoFHandlerType::dimension,
936  DoFHandlerType::space_dimension>>
938 
943 
947  std::vector<std::shared_ptr<
950 
954  std::vector<std::shared_ptr<
957 
963  std::vector<Patch> patches;
964 
969  virtual const std::vector<Patch> &
970  get_patches() const override;
971 
976  virtual std::vector<std::string>
977  get_dataset_names() const override;
978 
983  std::vector<
984  std::shared_ptr<::hp::FECollection<DoFHandlerType::dimension,
985  DoFHandlerType::space_dimension>>>
986  get_fes() const;
987 
992  virtual std::vector<
993  std::tuple<unsigned int,
994  unsigned int,
995  std::string,
997  get_nonscalar_data_ranges() const override;
998 
1003  template <class, int, int>
1004  friend class DataOut_DoFData;
1005 
1006 private:
1010  template <class VectorType>
1011  void
1013  const DoFHandlerType * dof_handler,
1014  const VectorType & data,
1015  const std::vector<std::string> &names,
1016  const DataVectorType type,
1017  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
1018  & data_component_interpretation,
1019  const bool deduce_output_names);
1020 };
1021 
1022 
1023 
1024 // -------------------- template and inline functions ------------------------
1025 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1026 template <typename VectorType>
1027 void
1029  const VectorType & vec,
1030  const std::string & name,
1031  const DataVectorType type,
1032  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
1033  &data_component_interpretation)
1034 {
1035  Assert(triangulation != nullptr,
1037  std::vector<std::string> names(1, name);
1039  dofs, vec, names, type, data_component_interpretation, true);
1040 }
1041 
1042 
1043 
1044 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1045 template <typename VectorType>
1046 void
1048  const VectorType & vec,
1049  const std::vector<std::string> &names,
1050  const DataVectorType type,
1051  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
1052  &data_component_interpretation)
1053 {
1054  Assert(triangulation != nullptr,
1057  dofs, vec, names, type, data_component_interpretation, false);
1058 }
1059 
1060 
1061 
1062 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1063 template <typename VectorType>
1064 void
1066  const DoFHandlerType &dof_handler,
1067  const VectorType & data,
1068  const std::string & name,
1069  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
1070  &data_component_interpretation)
1071 {
1072  std::vector<std::string> names(1, name);
1073  add_data_vector_internal(&dof_handler,
1074  data,
1075  names,
1076  type_dof_data,
1077  data_component_interpretation,
1078  true);
1079 }
1080 
1081 
1082 
1083 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1084 template <typename VectorType>
1085 void
1087  const DoFHandlerType & dof_handler,
1088  const VectorType & data,
1089  const std::vector<std::string> &names,
1090  const std::vector<DataComponentInterpretation::DataComponentInterpretation>
1091  &data_component_interpretation)
1092 {
1093  add_data_vector_internal(&dof_handler,
1094  data,
1095  names,
1096  type_dof_data,
1097  data_component_interpretation,
1098  false);
1099 }
1100 
1101 
1102 
1103 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1104 template <typename VectorType>
1105 void
1107  const VectorType & vec,
1108  const DataPostprocessor<DoFHandlerType::space_dimension> &data_postprocessor)
1109 {
1110  Assert(dofs != nullptr,
1112  add_data_vector(*dofs, vec, data_postprocessor);
1113 }
1114 
1115 
1116 
1117 template <typename DoFHandlerType, int patch_dim, int patch_space_dim>
1118 template <typename DoFHandlerType2>
1119 void
1122  const Point<patch_space_dim> & shift)
1123 {
1124  const std::vector<Patch> &source_patches = source.get_patches();
1125  Assert((patches.size() != 0) && (source_patches.size() != 0),
1126  ExcMessage("When calling this function, both the current "
1127  "object and the one being merged need to have a "
1128  "nonzero number of patches associated with it. "
1129  "Either you called this function on objects that "
1130  "are empty, or you may have forgotten to call "
1131  "the 'build_patches()' function."));
1132  // check equality of component
1133  // names
1136  // make sure patches are compatible. we'll
1137  // assume that if the first respective
1138  // patches are ok that all the other ones
1139  // are ok as well
1140  Assert(patches[0].n_subdivisions == source_patches[0].n_subdivisions,
1142  Assert(patches[0].data.n_rows() == source_patches[0].data.n_rows(),
1144  Assert(patches[0].data.n_cols() == source_patches[0].data.n_cols(),
1146 
1147  // check equality of the vector data
1148  // specifications
1149  Assert(get_nonscalar_data_ranges().size() ==
1150  source.get_nonscalar_data_ranges().size(),
1151  ExcMessage("Both sources need to declare the same components "
1152  "as vectors."));
1153  for (unsigned int i = 0; i < get_nonscalar_data_ranges().size(); ++i)
1154  {
1155  Assert(std::get<0>(get_nonscalar_data_ranges()[i]) ==
1156  std::get<0>(source.get_nonscalar_data_ranges()[i]),
1157  ExcMessage("Both sources need to declare the same components "
1158  "as vectors."));
1159  Assert(std::get<1>(get_nonscalar_data_ranges()[i]) ==
1160  std::get<1>(source.get_nonscalar_data_ranges()[i]),
1161  ExcMessage("Both sources need to declare the same components "
1162  "as vectors."));
1163  Assert(std::get<2>(get_nonscalar_data_ranges()[i]) ==
1164  std::get<2>(source.get_nonscalar_data_ranges()[i]),
1165  ExcMessage("Both sources need to declare the same components "
1166  "as vectors."));
1167  }
1168 
1169  // merge patches. store old number
1170  // of elements, since we need to
1171  // adjust patch numbers, etc
1172  // afterwards
1173  const unsigned int old_n_patches = patches.size();
1174  patches.insert(patches.end(), source_patches.begin(), source_patches.end());
1175 
1176  // perform shift, if so desired
1177  if (shift != Point<patch_space_dim>())
1178  for (unsigned int i = old_n_patches; i < patches.size(); ++i)
1179  for (unsigned int v = 0; v < GeometryInfo<patch_dim>::vertices_per_cell;
1180  ++v)
1181  patches[i].vertices[v] += shift;
1182 
1183  // adjust patch numbers
1184  for (unsigned int i = old_n_patches; i < patches.size(); ++i)
1185  patches[i].patch_index += old_n_patches;
1186 
1187  // adjust patch neighbors
1188  for (unsigned int i = old_n_patches; i < patches.size(); ++i)
1189  for (unsigned int n = 0; n < GeometryInfo<patch_dim>::faces_per_cell; ++n)
1190  if (patches[i].neighbors[n] != Patch::no_neighbor)
1191  patches[i].neighbors[n] += old_n_patches;
1192 }
1193 
1194 
1195 DEAL_II_NAMESPACE_CLOSE
1196 
1197 #endif
void merge_patches(const DataOut_DoFData< DoFHandlerType2, patch_dim, patch_space_dim > &source, const Point< patch_space_dim > &shift=Point< patch_space_dim >())
static const unsigned int invalid_unsigned_int
Definition: types.h:173
static::ExceptionBase & ExcNoTriangulationSelected()
static::ExceptionBase & ExcIncompatiblePatchLists()
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
virtual std::vector< std::string > get_dataset_names() const override
static::ExceptionBase & ExcOldDataStillPresent()
static::ExceptionBase & ExcInvalidVectorSize(int arg1, int arg2, int arg3)
static::ExceptionBase & ExcInvalidNumberOfSubdivisions(int arg1)
Definition: point.h:106
typename Triangulation< DoFHandlerType::dimension, DoFHandlerType::space_dimension >::cell_iterator cell_iterator
static::ExceptionBase & ExcIncompatibleDatasetNames()
std::vector< std::shared_ptr< internal::DataOutImplementation::DataEntryBase< DoFHandlerType > > > dof_data
static::ExceptionBase & ExcMessage(std::string arg1)
static::ExceptionBase & ExcNoDoFHandlerSelected()
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
#define Assert(cond, exc)
Definition: exceptions.h:1227
UpdateFlags
Abstract base class for mapping classes.
Definition: dof_tools.h:57
static::ExceptionBase & ExcInvalidNumberOfNames(int arg1, int arg2)
static::ExceptionBase & ExcInvalidVectorDeclaration(int arg1, std::string arg2)
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:397
static::ExceptionBase & ExcInvalidCharacter(std::string arg1, size_t arg2)
std::vector< Patch > patches
void add_data_vector(const VectorType &data, const std::vector< std::string > &names, const DataVectorType type=type_automatic, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretation=std::vector< DataComponentInterpretation::DataComponentInterpretation >())
SmartPointer< const ::DataPostprocessor< DoFHandlerType::space_dimension > > postprocessor
virtual const std::vector< Patch > & get_patches() const override
static::ExceptionBase & ExcInvalidTensorDeclaration(int arg1, std::string arg2)
virtual std::vector< std::tuple< unsigned int, unsigned int, std::string, DataComponentInterpretation::DataComponentInterpretation > > get_nonscalar_data_ranges() const override
static const unsigned int no_neighbor
SmartPointer< const DoFHandlerType > dof_handler
Definition: mpi.h:55
void add_data_vector_internal(const DoFHandlerType *dof_handler, const VectorType &data, const std::vector< std::string > &names, const DataVectorType type, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretation, const bool deduce_output_names)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:432
SmartPointer< const Triangulation< DoFHandlerType::dimension, DoFHandlerType::space_dimension > > triangulation
std::vector< std::shared_ptr< internal::DataOutImplementation::DataEntryBase< DoFHandlerType > > > cell_data
const std::vector< DataComponentInterpretation::DataComponentInterpretation > data_component_interpretation
SmartPointer< const DoFHandlerType > dofs