Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
72namespace ug {
73
74
75template <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
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
111template <typename TDomain>
112inline 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
164template <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
215template <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
382template <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
425template <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
440template <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
456template <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
Definition smart_pointer.h:108
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
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
ConstSmartPtr< FunctionPattern > function_pattern() const
get underlying function pattern
Definition function_group.h:73
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
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
TParallelGlobalRefiner< GlobalMultiGridRefiner > ParallelGlobalRefiner_MultiGrid
Parallel global refinement for multi-grids.
Definition parallel_refinement.h:52
#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
@ 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
number & DoFRef(TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
Definition multi_index.h:276
SmartPtr< T, FreePolicy > make_sp(T *inst)
returns a SmartPtr for the passed raw pointer
Definition smart_pointer.h:836
SurfaceView::traits< TElem >::const_iterator const_iterator
Definition dof_distribution.h:82
geometry_traits< TElem >::iterator iterator
Definition grid.h:143