00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __deal2__data_out_h
00013 #define __deal2__data_out_h
00014
00015
00016
00017 #include <deal.II/base/config.h>
00018 #include <deal.II/base/smartpointer.h>
00019 #include <deal.II/base/data_out_base.h>
00020 #include <deal.II/dofs/dof_handler.h>
00021 #include <deal.II/fe/mapping.h>
00022 #include <deal.II/hp/q_collection.h>
00023 #include <deal.II/hp/fe_collection.h>
00024 #include <deal.II/hp/mapping_collection.h>
00025 #include <deal.II/hp/fe_values.h>
00026 #include <deal.II/numerics/data_postprocessor.h>
00027 #include <deal.II/numerics/data_component_interpretation.h>
00028
00029 #include <deal.II/base/std_cxx1x/shared_ptr.h>
00030
00031 DEAL_II_NAMESPACE_OPEN
00032
00033 template <int, int> class FEValuesBase;
00034
00035 namespace internal
00036 {
00037 namespace DataOut
00038 {
00061 template <class DH>
00062 class DataEntryBase
00063 {
00064 public:
00074 DataEntryBase (const std::vector<std::string> &names,
00075 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
00076
00084 DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor);
00085
00089 virtual ~DataEntryBase ();
00090
00096 virtual
00097 double
00098 get_cell_data_value (const unsigned int cell_number) const = 0;
00099
00106 virtual
00107 void
00108 get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00109 std::vector<double> &patch_values) const = 0;
00110
00119 virtual
00120 void
00121 get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00122 std::vector<::Vector<double> > &patch_values_system) const = 0;
00123
00130 virtual
00131 void
00132 get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00133 std::vector<Tensor<1,DH::space_dimension> > &patch_gradients) const = 0;
00134
00143 virtual
00144 void
00145 get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00146 std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const = 0;
00147
00154 virtual
00155 void
00156 get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00157 std::vector<Tensor<2,DH::space_dimension> > &patch_hessians) const = 0;
00158
00167 virtual
00168 void
00169 get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
00170 std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const = 0;
00171
00176 virtual void clear () = 0;
00177
00183 virtual std::size_t memory_consumption () const = 0;
00184
00189 const std::vector<std::string> names;
00190
00199 const std::vector<DataComponentInterpretation::DataComponentInterpretation>
00200 data_component_interpretation;
00201
00207 SmartPointer<const ::DataPostprocessor<DH::space_dimension> > postprocessor;
00208
00219 unsigned int n_output_variables;
00220 };
00221
00222
00255 template <int dim, int spacedim>
00256 struct ParallelDataBase
00257 {
00258 template <class FE>
00259 ParallelDataBase (const unsigned int n_components,
00260 const unsigned int n_datasets,
00261 const unsigned int n_subdivisions,
00262 const unsigned int n_q_points,
00263 const std::vector<unsigned int> &n_postprocessor_outputs,
00264 const FE &finite_elements);
00265
00266 const unsigned int n_components;
00267 const unsigned int n_datasets;
00268 const unsigned int n_subdivisions;
00269
00270 std::vector<double> patch_values;
00271 std::vector<::Vector<double> > patch_values_system;
00272 std::vector<Tensor<1,spacedim> > patch_gradients;
00273 std::vector<std::vector<Tensor<1,spacedim> > > patch_gradients_system;
00274 std::vector<Tensor<2,spacedim> > patch_hessians;
00275 std::vector<std::vector<Tensor<2,spacedim> > > patch_hessians_system;
00276 std::vector<std::vector<::Vector<double> > > postprocessed_values;
00277
00278 const ::hp::FECollection<dim,spacedim> fe_collection;
00279 };
00280
00281
00291 template <int dim, int spacedim>
00292 struct ParallelData : public ParallelDataBase<dim,spacedim>
00293 {
00294 template <class FE>
00295 ParallelData (const Quadrature<dim> &quadrature,
00296 const unsigned int n_components,
00297 const unsigned int n_datasets,
00298 const unsigned int n_subdivisions,
00299 const std::vector<unsigned int> &n_postprocessor_outputs,
00300 const Mapping<dim,spacedim> &mapping,
00301 const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map,
00302 const FE &finite_elements,
00303 const UpdateFlags update_flags);
00304
00305 const ::hp::QCollection<dim> q_collection;
00306 const ::hp::MappingCollection<dim,spacedim> mapping_collection;
00307 ::hp::FEValues<dim,spacedim> x_fe_values;
00308
00309 std::vector<Point<spacedim> > patch_evaluation_points;
00310
00311 const std::vector<std::vector<unsigned int> > *cell_to_patch_index_map;
00312 };
00313 }
00314 }
00315
00316
00317
00318
00461 template <class DH, int patch_dim, int patch_space_dim=patch_dim>
00462 class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
00463 {
00464 public:
00465
00471 typedef typename DH::cell_iterator cell_iterator;
00472 typedef typename DH::active_cell_iterator active_cell_iterator;
00473
00474 public:
00475
00495 enum DataVectorType
00496 {
00501 type_dof_data,
00502
00507 type_cell_data,
00508
00512 type_automatic
00513 };
00514
00518 DataOut_DoFData ();
00519
00523 virtual ~DataOut_DoFData ();
00524
00531 void attach_dof_handler (const DH &);
00532
00661 template <class VECTOR>
00662 void add_data_vector (const VECTOR &data,
00663 const std::vector<std::string> &names,
00664 const DataVectorType type = type_automatic,
00665 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
00666 = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
00667
00696 template <class VECTOR>
00697 void add_data_vector (const VECTOR &data,
00698 const std::string &name,
00699 const DataVectorType type = type_automatic,
00700 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
00701 = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
00702
00734 template <class VECTOR>
00735 void add_data_vector (const VECTOR &data,
00736 const DataPostprocessor<DH::space_dimension> &data_postprocessor);
00737
00750 void clear_data_vectors ();
00751
00772 void clear_input_data_references ();
00773
00822 template <class DH2>
00823 void merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
00824 const Point<patch_space_dim> &shift = Point<patch_space_dim>());
00825
00839 virtual void clear ();
00840
00846 std::size_t memory_consumption () const;
00847
00851 DeclException0 (ExcNoDoFHandlerSelected);
00855 DeclException0 (ExcDataPostprocessingIsNotPossibleForCellData);
00859 DeclException3 (ExcInvalidVectorSize,
00860 int, int, int,
00861 << "The vector has size " << arg1
00862 << " but the DoFHandler objects says there are " << arg2
00863 << " degrees of freedom and there are " << arg3
00864 << " active cells.");
00868 DeclException2 (ExcInvalidCharacter,
00869 std::string, size_t,
00870 << "Please use only the characters [a-zA-Z0-9_<>()] for" << std::endl
00871 << "description strings since some graphics formats will only accept these."
00872 << std::endl
00873 << "The string you gave was <" << arg1
00874 << ">, the invalid character is <" << arg1[arg2]
00875 << ">." << std::endl);
00879 DeclException0 (ExcOldDataStillPresent);
00883 DeclException2 (ExcInvalidNumberOfNames,
00884 int, int,
00885 << "You have to give one name per component in your "
00886 << "data vector. The number you gave was " << arg1
00887 << ", but the number of components is " << arg2);
00891 DeclException0 (ExcNoPatches);
00895 DeclException0 (ExcIncompatibleDatasetNames);
00899 DeclException0 (ExcIncompatiblePatchLists);
00900
00901 DeclException2 (ExcInvalidVectorDeclaration,
00902 int, std::string,
00903 << "When declaring that a number of components in a data\n"
00904 << "set to be output logically form a vector instead of\n"
00905 << "simply a set of scalar fields, you need to specify\n"
00906 << "this for all relevant components. Furthermore,\n"
00907 << "vectors must always consist of exactly <dim>\n"
00908 << "components. However, the vector component at\n"
00909 << "position " << arg1 << " with name <" << arg2
00910 << "> does not satisfy these conditions.");
00911
00912 protected:
00917 typedef ::DataOutBase::Patch<patch_dim,patch_space_dim> Patch;
00918
00922 SmartPointer<const DH, DataOut_DoFData<DH,patch_dim,patch_space_dim> > dofs;
00923
00928 std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > > dof_data;
00929
00934 std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > > cell_data;
00935
00943 std::vector<Patch> patches;
00944
00951 virtual
00952 const std::vector<Patch> & get_patches () const;
00953
00960 virtual
00961 std::vector<std::string> get_dataset_names () const;
00962
00969 virtual
00970 std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
00971 get_vector_data_ranges () const;
00972
00978 template <class, int, int>
00979 friend class DataOut_DoFData;
00980 };
00981
00982
00983
01059 template <int dim, class DH=DoFHandler<dim> >
01060 class DataOut : public DataOut_DoFData<DH, DH::dimension, DH::space_dimension>
01061 {
01062 public:
01068 typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
01069 typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
01070
01076 enum CurvedCellRegion
01077 {
01078 no_curved_cells,
01079 curved_boundary,
01080 curved_inner_cells
01081 };
01082
01100 virtual void build_patches (const unsigned int n_subdivisions = 0);
01101
01152 virtual void build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
01153 const unsigned int n_subdivisions = 0,
01154 const CurvedCellRegion curved_region = curved_boundary);
01155
01164 virtual cell_iterator first_cell ();
01165
01187 virtual cell_iterator next_cell (const cell_iterator &cell);
01188
01192 DeclException1 (ExcInvalidNumberOfSubdivisions,
01193 int,
01194 << "The number of subdivisions per patch, " << arg1
01195 << ", is not valid.");
01196
01197 private:
01198
01210 cell_iterator first_locally_owned_cell ();
01211
01221 cell_iterator next_locally_owned_cell (const cell_iterator &cell);
01222
01231 void build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
01232 internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data,
01233 DataOutBase::Patch<DH::dimension, DH::space_dimension> &patch,
01234 const CurvedCellRegion curved_cell_region);
01235 };
01236
01237
01238
01239
01240
01241
01242 namespace internal
01243 {
01244 namespace DataOut
01245 {
01246 template <int dim, int spacedim>
01247 template <class FE>
01248 ParallelDataBase<dim,spacedim>::
01249 ParallelDataBase (const unsigned int n_components,
01250 const unsigned int n_datasets,
01251 const unsigned int n_subdivisions,
01252 const unsigned int n_q_points,
01253 const std::vector<unsigned int> &n_postprocessor_outputs,
01254 const FE &finite_elements)
01255 :
01256 n_components (n_components),
01257 n_datasets (n_datasets),
01258 n_subdivisions (n_subdivisions),
01259 patch_values (n_q_points),
01260 patch_values_system (n_q_points),
01261 patch_gradients (n_q_points),
01262 patch_gradients_system (n_q_points),
01263 patch_hessians (n_q_points),
01264 patch_hessians_system (n_q_points),
01265 postprocessed_values (n_postprocessor_outputs.size()),
01266 fe_collection (finite_elements)
01267 {
01268 for (unsigned int k=0; k<n_q_points; ++k)
01269 {
01270 patch_values_system[k].reinit(n_components);
01271 patch_gradients_system[k].resize(n_components);
01272 patch_hessians_system[k].resize(n_components);
01273 }
01274
01275 for (unsigned int dataset=0; dataset<n_postprocessor_outputs.size(); ++dataset)
01276 if (n_postprocessor_outputs[dataset] != 0)
01277 postprocessed_values[dataset]
01278 .resize(n_q_points,
01279 ::Vector<double>(n_postprocessor_outputs[dataset]));
01280 }
01281 }
01282 }
01283
01284
01285 template <class DH, int patch_dim, int patch_space_dim>
01286 template <class DH2>
01287 void
01288 DataOut_DoFData<DH,patch_dim,patch_space_dim>::
01289 merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
01290 const Point<patch_space_dim> &shift)
01291 {
01292 const std::vector<Patch> source_patches = source.get_patches ();
01293 Assert (patches.size () != 0, ExcNoPatches ());
01294 Assert (source_patches.size () != 0, ExcNoPatches ());
01295
01296
01297 Assert (get_dataset_names() == source.get_dataset_names(),
01298 ExcIncompatibleDatasetNames());
01299
01300
01301
01302
01303 Assert (patches[0].n_subdivisions == source_patches[0].n_subdivisions,
01304 ExcIncompatiblePatchLists());
01305 Assert (patches[0].data.n_rows() == source_patches[0].data.n_rows(),
01306 ExcIncompatiblePatchLists());
01307 Assert (patches[0].data.n_cols() == source_patches[0].data.n_cols(),
01308 ExcIncompatiblePatchLists());
01309
01310
01311
01312 Assert (get_vector_data_ranges().size() ==
01313 source.get_vector_data_ranges().size(),
01314 ExcMessage ("Both sources need to declare the same components "
01315 "as vectors."));
01316 for (unsigned int i=0; i<get_vector_data_ranges().size(); ++i)
01317 {
01318 Assert (std_cxx1x::get<0>(get_vector_data_ranges()[i]) ==
01319 std_cxx1x::get<0>(source.get_vector_data_ranges()[i]),
01320 ExcMessage ("Both sources need to declare the same components "
01321 "as vectors."));
01322 Assert (std_cxx1x::get<1>(get_vector_data_ranges()[i]) ==
01323 std_cxx1x::get<1>(source.get_vector_data_ranges()[i]),
01324 ExcMessage ("Both sources need to declare the same components "
01325 "as vectors."));
01326 Assert (std_cxx1x::get<2>(get_vector_data_ranges()[i]) ==
01327 std_cxx1x::get<2>(source.get_vector_data_ranges()[i]),
01328 ExcMessage ("Both sources need to declare the same components "
01329 "as vectors."));
01330 }
01331
01332
01333
01334
01335
01336 const unsigned int old_n_patches = patches.size();
01337 patches.insert (patches.end(),
01338 source_patches.begin(),
01339 source_patches.end());
01340
01341
01342 if (shift != Point<patch_space_dim>())
01343 for (unsigned int i=old_n_patches; i<patches.size(); ++i)
01344 for (unsigned int v=0; v<GeometryInfo<patch_dim>::vertices_per_cell; ++v)
01345 patches[i].vertices[v] += shift;
01346
01347
01348 for (unsigned int i=old_n_patches; i<patches.size(); ++i)
01349 patches[i].patch_index += old_n_patches;
01350
01351
01352 for (unsigned int i=old_n_patches; i<patches.size(); ++i)
01353 for (unsigned int n=0; n<GeometryInfo<patch_dim>::faces_per_cell; ++n)
01354 if (patches[i].neighbors[n] != Patch::no_neighbor)
01355 patches[i].neighbors[n] += old_n_patches;
01356 }
01357
01358
01359 DEAL_II_NAMESPACE_CLOSE
01360
01361 #endif
01362