ug4
vtk_export_ho.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3  * Author: Markus Breit
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG__LIB_DISC__IO__VTK_EXPORT_HO__
34 #define __H__UG__LIB_DISC__IO__VTK_EXPORT_HO__
35 
36 #include <cmath> // for ceil, log2
37 #include <cstddef> // for size_t
38 #include <limits> // for numeric_limits
39 #include <ostream> // for string, operator<<, basic_ostream, endl
40 #include <string> // for char_traits, allocator, operator+, basic_string
41 #include <vector> // for vector
42 
43 #include "common/assert.h" // for UG_ASSERT
44 #include "common/error.h" // for UG_CATCH_THROW, UG_COND_THROW
45 #include "common/types.h" // for number
46 #include "common/math/math_vector_matrix/math_vector.h" // for MathVector
47 #include "common/util/smart_pointer.h" // for SmartPtr, ConstSmartPtr, make_sp
48 #include "lib_disc/common/function_group.h" // for FunctionGroup
49 #include "lib_disc/common/multi_index.h" // for DoFIndex, DoFRef
50 #include "lib_disc/dof_manager/dof_distribution.h" // for DoFDistribution, DoFDistribution::traits
51 #include "lib_disc/function_spaces/dof_position_util.h" // for InnerDoFPosition
52 #include "lib_disc/function_spaces/grid_function_global_user_data.h" // for GlobalGridFunctionNumberData
53 #include "lib_disc/io/vtkoutput.h" // for VTKOutput
55 #include "lib_grid/algorithms/debug_util.h" // for ElementDebugInfo
56 #include "lib_grid/algorithms/selection_util.h" // for SelectAssociatedGridObjects
57 #include "lib_grid/attachments/attachment_pipe.h" // for AttachmentAccessor
58 #include "lib_grid/common_attachments.h" // for AVertex
59 #include "lib_grid/grid/grid.h" // for Grid::VertexAttachmentAccessor::VertexAttachmentAccessor<TAt...
60 #include "lib_grid/grid/grid_base_object_traits.h" // for VertexIterator
61 #include "lib_grid/grid/grid_base_objects.h" // for CustomVertexGroup, Vertex, Edge (ptr only), Face (ptr only)
62 #ifdef UG_PARALLEL
63  #include "lib_grid/parallelization/parallel_refinement/parallel_refinement.h" // for ParallelGlobalRefiner_MultiGrid
64 #else
65  #include "lib_grid/refinement/global_multi_grid_refiner.h" // for GlobalMultiGridRefiner
66 #endif
67 #include "lib_grid/multi_grid.h" // for MultiGrid
68 #include "lib_grid/tools/selector_grid.h" // for Selector
69 #include "lib_grid/tools/subset_group.h" // for SubsetGroup
70 
71 
72 namespace ug {
73 
74 
75 template <typename TDomain, class TElem>
77 (
78  SmartPtr<TDomain> destDom,
79  SmartPtr<TDomain> srcDom,
80  Selector& sel,
81  AVertex& aNewVrt
82 )
83 {
84  typedef typename TDomain::subset_handler_type SH_type;
85 
86  MultiGrid& srcGrid = *srcDom->grid();
87  MultiGrid& destGrid = *destDom->grid();
88 
89  ConstSmartPtr<SH_type> srcSH = srcDom->subset_handler();
90  SmartPtr<SH_type> destSH = destDom->subset_handler();
91 
92  Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcGrid, aNewVrt);
93 
94  CustomVertexGroup vrts;
95  typedef typename Grid::traits<TElem>::iterator iter_t;
96 
97  for (iter_t eiter = sel.begin<TElem>(); eiter != sel.end<TElem>(); ++eiter)
98  {
99  TElem* e = *eiter;
100  vrts.resize(e->num_vertices());
101  for (size_t iv = 0; iv < e->num_vertices(); ++iv)
102  vrts.set_vertex(iv, aaNewVrt[e->vertex(iv)]);
103 
104  TElem* ne;
105  try {ne = *destGrid.create_by_cloning(e, vrts);}
106  UG_CATCH_THROW("New element could not be created.");
107  destSH->assign_subset(ne, srcSH->get_subset_index(e));
108  }
109 }
110 
111 template <typename TDomain>
112 inline void CopySelected
113 (
114  SmartPtr<TDomain> destDom,
115  SmartPtr<TDomain> srcDom,
116  Selector& sel
117 )
118 {
119  typedef typename TDomain::position_attachment_type APos_type;
120  typedef typename TDomain::subset_handler_type SH_type;
121 
122  MultiGrid& srcGrid = *srcDom->grid();
123  MultiGrid& destGrid = *destDom->grid();
124 
125  ConstSmartPtr<SH_type> srcSH = srcDom->subset_handler();
126  SmartPtr<SH_type> destSH = destDom->subset_handler();
127 
128  APos_type& aPos = srcDom->position_attachment();
129  UG_COND_THROW(!srcGrid.has_vertex_attachment(aPos), "Position attachment required.");
130  Grid::VertexAttachmentAccessor<APos_type> aaPosSrc(srcGrid, aPos);
131  if (!destGrid.has_vertex_attachment(aPos))
132  destGrid.attach_to_vertices(aPos);
133  Grid::VertexAttachmentAccessor<APos_type> aaPosDest(destGrid, aPos);
134 
135  AVertex aNewVrt;
136  srcGrid.attach_to_vertices(aNewVrt);
137  Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcGrid, aNewVrt);
138 
139  for (int si = destSH->num_subsets(); si < srcSH->num_subsets(); ++si)
140  destSH->subset_info(si) = srcSH->subset_info(si);
141 
143 
144  // create new vertices in destGrid
145  for (VertexIterator viter = sel.begin<Vertex>(); viter != sel.end<Vertex>(); ++viter)
146  {
147  Vertex* v = *viter;
148  Vertex* nv;
149  try {nv = *destGrid.create_by_cloning(v);}
150  UG_CATCH_THROW("New vertex could not be created.");
151  aaNewVrt[v] = nv;
152  aaPosDest[nv] = aaPosSrc[v];
153  destSH->assign_subset(nv, srcSH->get_subset_index(v));
154  }
155 
156  CopySelectedElements<TDomain,Edge>(destDom, srcDom, sel, aNewVrt);
157  CopySelectedElements<TDomain,Face>(destDom, srcDom, sel, aNewVrt);
158  CopySelectedElements<TDomain,Volume>(destDom, srcDom, sel, aNewVrt);
159 
160  srcGrid.detach_from_vertices(aNewVrt);
161 }
162 
163 
164 template <typename TElem, typename TGridFunction, typename TGGFND>
166 (
168  const TGGFND& u_orig,
169  size_t fct,
170  const LFEID& lfeid
171 )
172 {
173  typedef typename TGridFunction::domain_type dom_type;
174  static const int dim = dom_type::dim;
175  typedef typename DoFDistribution::traits<TElem>::const_iterator const_iter_type;
176 
177  // interpolate subset-wise
178  size_t numSubsets = u_new->num_subsets();
179  for (size_t si = 0; si < numSubsets; ++si)
180  {
181  if (!u_new->is_def_in_subset(fct, si)) continue;
182 
183  const_iter_type elem_iter = u_new->template begin<TElem>(si);
184  const_iter_type iterEnd = u_new->template end<TElem>(si);
185 
186  std::vector<DoFIndex> ind;
187  for (; elem_iter != iterEnd; ++elem_iter)
188  {
189  u_new->inner_dof_indices(*elem_iter, fct, ind);
190 
191  // get dof positions
192  std::vector<MathVector<dim> > globPos;
193  InnerDoFPosition<dom_type>(globPos, *elem_iter, *u_new->domain(), lfeid);
194 
195  UG_ASSERT(globPos.size() == ind.size(),
196  "#DoF mismatch: InnerDoFPosition() found " << globPos.size()
197  << ", but grid function has " << ind.size() << std::endl
198  << "on " << ElementDebugInfo(*u_new->domain()->grid(), *elem_iter) << ".");
199 
200  // write values in new grid function
201  for (size_t dof = 0; dof < ind.size(); ++dof)
202  {
203  if (!u_orig.evaluate(DoFRef(*u_new, ind[dof]), globPos[dof]))
204  {
205  DoFRef(*u_new, ind[dof]) = std::numeric_limits<number>::quiet_NaN();
206  //UG_THROW("Interpolation onto new grid did not succeed.\n"
207  // "DoF with coords " << globPos[dof] << " is out of range.");
208  }
209  }
210  }
211  }
212 }
213 
214 
215 template <typename TGridFunction, int trueDim>
217 (
219  const std::vector<std::string>& vFct,
220  size_t order,
222  const char* filename,
223  size_t step,
224  number time,
225  const SubsetGroup& ssg
226 )
227 {
228  // for order 1, use the given grid function as is
229  if (order == 1)
230  {
231  // print out new grid function on desired subsets
232  bool printAll = ssg.size() == (size_t) u->subset_handler()->num_subsets();
233  if (printAll)
234  vtkOutput->print(filename, *u, step, time);
235  else
236  {
237  for (size_t s = 0; s < ssg.size(); ++s)
238  vtkOutput->print_subset(filename, *u, ssg[s], step, time);
239  }
240 
241  return;
242  }
243 
244  typedef typename TGridFunction::domain_type dom_type;
245  typedef typename TGridFunction::algebra_type algebra_type;
246  typedef typename dom_type::position_attachment_type position_attachment_type;
247  typedef typename TGridFunction::approximation_space_type approx_space_type;
248  typedef typename TGridFunction::template dim_traits<trueDim>::grid_base_object elem_type;
249 
250  SmartPtr<approx_space_type> srcApproxSpace = u->approx_space();
251  SmartPtr<dom_type> srcDom = srcApproxSpace->domain();
252 
253  // select surface elements in old grid
254  MultiGrid& srcGrid = *srcDom->grid();
255  Selector srcSel(srcGrid);
256  srcSel.select(u->template begin<elem_type>(), u->template end<elem_type>());
257 
258  // create new domain
259  dom_type* dom_ptr;
260  try {dom_ptr = new dom_type();}
261  UG_CATCH_THROW("Temporary domain could not be created.");
262  SmartPtr<dom_type> destDom = make_sp(dom_ptr);
263 
264  // copy grid from old domain to new domain (into a flat grid!)
265  try {CopySelected(destDom, srcDom, srcSel);}
266  UG_CATCH_THROW("Temporary grid could not be created.");
267 
268  // refine
269 #ifdef UG_PARALLEL
270  ParallelGlobalRefiner_MultiGrid refiner(*destDom->distributed_grid_manager());
271 #else
272  MultiGrid& destGrid = *destDom->grid();
273  GlobalMultiGridRefiner refiner(destGrid);
274 #endif
275  size_t numRefs = (size_t) ceil(log2(order));
276  for (size_t iref = 0; iref < numRefs; ++iref)
277  {
278  try {refiner.refine();}
279  UG_CATCH_THROW("Refinement step " << iref << " could not be carried out.");
280  }
281 
282  // retain function group for functions being exported
283  FunctionGroup fg(srcApproxSpace->dof_distribution_info(), vFct);
284 
285  // create approx space and add functions
286  approx_space_type* approx_ptr;
287  try {approx_ptr = new approx_space_type(destDom, algebra_type::get_type());}
288  UG_CATCH_THROW("Temporary approximation space could not be created.");
289  SmartPtr<approx_space_type> destApproxSpace = make_sp(approx_ptr);
290 
291  for (size_t fct = 0; fct < fg.size(); ++fct)
292  {
293  if (fg.function_pattern()->is_def_everywhere(fg.unique_id(fct)))
294  destApproxSpace->add(fg.name(fct), "Lagrange", 1);
295  else
296  {
297  int num_subsets = fg.function_pattern()->num_subsets();
298  std::string subsets;
299  for (int si = 0; si < num_subsets; ++si)
300  {
301  if (fg.function_pattern()->is_def_in_subset(fct, si))
302  subsets += std::string(",") + fg.function_pattern()->subset_name(si);
303  }
304  if (!subsets.empty())
305  subsets.erase(0,1); // delete leading ","
306 
307  destApproxSpace->add(fg.name(fct), "Lagrange", 1, subsets.c_str());
308  }
309  }
310  destApproxSpace->init_top_surface();
311 
312  TGridFunction* gridFct_ptr;
313  try {gridFct_ptr = new TGridFunction(destApproxSpace);}
314  UG_CATCH_THROW("Temporary grid function could not be created.");
315  SmartPtr<TGridFunction> u_new = make_sp(gridFct_ptr);
316 
317  // interpolate onto new grid
318  for (size_t fct = 0; fct < fg.size(); ++fct)
319  {
320  const LFEID lfeid = u_new->dof_distribution()->lfeid(fct);
321 
324 
325  // iterate over DoFs in new function and evaluate
326  // should be vertices only for Lagrange-1
327  if (u_new->max_dofs(VERTEX))
328  interpolate_from_original_fct<Vertex, TGridFunction, GlobalGridFunctionNumberData<TGridFunction, trueDim> >
329  (u_new, ggfnd, fct, lfeid);
330  /*
331  if (u_new->max_dofs(EDGE))
332  interpolate_from_original_fct<Edge, TGridFunction, GlobalGridFunctionNumberData<TGridFunction, trueDim> >
333  (u_new, ggfnd, fct, lfeid);
334  if (u_new->max_dofs(FACE))
335  interpolate_from_original_fct<Face, TGridFunction, GlobalGridFunctionNumberData<TGridFunction, trueDim> >
336  (u_new, ggfnd, fct, lfeid);
337  if (u_new->max_dofs(VOLUME))
338  interpolate_from_original_fct<Volume, TGridFunction, GlobalGridFunctionNumberData<TGridFunction, trueDim> >
339  (u_new, ggfnd, fct, lfeid);
340  */
341  }
342 
343 #ifdef UG_PARALLEL
344  // copy storage type and layouts
345  u_new->set_storage_type(u->get_storage_mask());
346  u_new->set_layouts(u->layouts());
347 #endif
348 
349  // print out new grid function on desired subsets
350  bool printAll = ssg.size() == (size_t) u->subset_handler()->num_subsets();
351  if (printAll)
352  vtkOutput->print(filename, *u_new, step, time);
353  else
354  {
355  for (size_t s = 0; s < ssg.size(); ++s)
356  vtkOutput->print_subset(filename, *u_new, ssg[s], step, time);
357  }
358 }
359 
360 
362 
382 template <typename TGridFunction>
384 (
386  const std::vector<std::string>& vFct,
387  size_t order,
389  const char* filename,
390  size_t step,
391  number time,
392  const std::vector<std::string>& vSubset
393 )
394 {
395  // construct subset group from given subsets
396  SubsetGroup ssg(u->subset_handler());
397  try
398  {
399  if (vSubset.empty())
400  ssg.add_all();
401  else
402  ssg.add(vSubset);
403  }
404  UG_CATCH_THROW("Subsets are faulty.");
405 
406  // find highest dim that contains any elements
407  MultiGrid& srcGrid = *u->approx_space()->domain()->grid();
408  if (srcGrid.num_volumes())
409  vtk_export_ho<TGridFunction, TGridFunction::dim >= 3 ? 3 : TGridFunction::dim>
410  (u, vFct, order, vtkOutput, filename, step, time, ssg);
411  else if (srcGrid.num_faces())
412  vtk_export_ho<TGridFunction, TGridFunction::dim >= 2 ? 2 : TGridFunction::dim>
413  (u, vFct, order, vtkOutput, filename, step, time, ssg);
414  else if (srcGrid.num_edges())
415  vtk_export_ho<TGridFunction, TGridFunction::dim >= 1 ? 1 : TGridFunction::dim>
416  (u, vFct, order, vtkOutput, filename, step, time, ssg);
417  else if (srcGrid.num_vertices())
418  vtk_export_ho<TGridFunction, TGridFunction::dim >= 0 ? 0 : TGridFunction::dim>
419  (u, vFct, order, vtkOutput, filename, step, time, ssg);
420  else
421  vtk_export_ho<TGridFunction, TGridFunction::dim>(u, vFct, order, vtkOutput, filename, step, time, ssg);
422 }
423 
424 
425 template <typename TGridFunction>
427 (
429  const std::vector<std::string>& vFct,
430  size_t order,
432  const char* filename,
433  const std::vector<std::string>& vSubset
434  )
435 {
436  vtk_export_ho(u, vFct, order, vtkOutput, filename, 0, 0.0, vSubset);
437 }
438 
439 
440 template <typename TGridFunction>
442 (
444  const std::vector<std::string>& vFct,
445  size_t order,
447  const char* filename,
448  size_t step,
449  number time
450 )
451 {
452  vtk_export_ho(u, vFct, order, vtkOutput, filename, step, time, std::vector<std::string>());
453 }
454 
455 
456 template <typename TGridFunction>
458 (
460  const std::vector<std::string>& vFct,
461  size_t order,
463  const char* filename
464  )
465 {
466  vtk_export_ho(u, vFct, order, vtkOutput, filename, 0, 0.0, std::vector<std::string>());
467 }
468 
469 
470 } // end namespace ug
471 
472 
473 #endif // __H__UG__LIB_DISC__IO__VTK_EXPORT_HO__
parameterString s
parameterNumber numRefs
Definition: smart_pointer.h:296
this class can be used if one wants to create a custom element from a set of vertices.
Definition: grid_base_objects.h:336
void set_vertex(size_t index, Vertex *vrt)
Definition: grid_base_objects.h:350
void resize(size_t newSize)
Definition: grid_base_objects.h:347
Definition: function_group.h:52
ConstSmartPtr< FunctionPattern > function_pattern() const
get underlying function pattern
Definition: function_group.h:73
const char * name(size_t i) const
returns the name of a function
Definition: function_group.cpp:205
size_t unique_id(size_t i) const
returns unique function id of a function
Definition: function_group.h:128
size_t size() const
number of functions in this group
Definition: function_group.h:116
Definition: grid_function_global_user_data.h:58
Definition: global_multi_grid_refiner.h:48
size_t num_volumes() const
Definition: grid.h:554
size_t num_faces() const
Definition: grid.h:553
size_t num_vertices() const
Definition: grid.h:551
void detach_from_vertices(IAttachment &attachment)
Definition: grid.h:787
bool has_vertex_attachment(IAttachment &attachment)
Definition: grid.h:798
size_t num_edges() const
Definition: grid.h:552
void attach_to_vertices(IAttachment &attachment, bool passOnValues)
Definition: grid.h:728
void select(GridObject *elem, byte status)
selects an element
Definition: selector_interface_impl.hpp:56
Identifier for Local Finite Elements.
Definition: local_finite_element_id.h:98
Definition: multi_grid.h:72
VertexIterator create_by_cloning(Vertex *pCloneMe, int level)
this method creates a new vertex, which has the same type as pCloneMe.
Definition: multi_grid.cpp:128
specialization of ISelector for a grid of class Grid.
Definition: selector_grid.h:96
geometry_traits< TElem >::iterator end()
Definition: selector_grid_impl.hpp:134
geometry_traits< TElem >::iterator begin()
Definition: selector_grid_impl.hpp:106
Group of subsets.
Definition: subset_group.h:51
size_t size() const
number of subsets in this group
Definition: subset_group.h:122
void add_all()
select all subsets of underlying subset handler
Definition: subset_group.cpp:133
void add(int si)
adds a subset by number to this group
Definition: subset_group.cpp:64
Const iterator to traverse the surface of a multi-grid hierarchy.
Definition: surface_view.h:237
Adds parallel support to a global refiner.
Definition: parallel_global_refiner_t.h:50
output writer to the VTK file format
Definition: vtkoutput.h:150
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
std::string ElementDebugInfo(const Grid &grid, GridObject *e)
Returns a string containing information on the given element.
Definition: debug_util.cpp:991
void SelectAssociatedGridObjects(TSelector &sel, ISelector::status_t status)
selects associated geometric objects of selected ones on each level.
Definition: selection_util.cpp:221
static const int dim
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_CATCH_THROW(msg)
Definition: error.h:64
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
the ug namespace
ElementStorage< Vertex >::SectionContainer::iterator VertexIterator
This Iterator will be used as base-class for iterators of specialized geometric objects.
Definition: grid_base_object_traits.h:73
void CopySelectedElements(SmartPtr< TDomain > destDom, SmartPtr< TDomain > srcDom, Selector &sel, AVertex &aNewVrt)
Definition: vtk_export_ho.h:77
number & DoFRef(TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
Definition: multi_index.h:276
@ VERTEX
Definition: grid_base_objects.h:60
void CopySelected(SmartPtr< TDomain > destDom, SmartPtr< TDomain > srcDom, Selector &sel)
Definition: vtk_export_ho.h:113
void vtk_export_ho(SmartPtr< TGridFunction > u, const std::vector< std::string > &vFct, size_t order, SmartPtr< VTKOutput< TGridFunction::domain_type::dim > > vtkOutput, const char *filename, size_t step, number time, const SubsetGroup &ssg)
Definition: vtk_export_ho.h:217
void interpolate_from_original_fct(SmartPtr< TGridFunction > u_new, const TGGFND &u_orig, size_t fct, const LFEID &lfeid)
Definition: vtk_export_ho.h:166
SmartPtr< T, FreePolicy > make_sp(T *inst)
returns a SmartPtr for the passed raw pointer
Definition: smart_pointer.h:836
geometry_traits< TElem >::iterator iterator
Definition: grid.h:143