Line data Source code
1 : /*
2 : * Copyright (c) 2016: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
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_raster_layers_projector
34 : #define __H__UG_raster_layers_projector
35 :
36 : #include "lib_grid/global_attachments.h"
37 : #include "refinement_projector.h"
38 : #include "lib_grid/algorithms/raster_layer_util.h"
39 :
40 : namespace ug{
41 :
42 : class RasterLayersProjector : public RefinementProjector {
43 : public:
44 : typedef ANumber rel_z_attachment_t;
45 : typedef Grid::VertexAttachmentAccessor<ANumber> rel_z_attachment_accessor_t;
46 :
47 0 : RasterLayersProjector () {}
48 :
49 : RasterLayersProjector (SPIGeometry3d geometry) :
50 : RefinementProjector (geometry)
51 : {add_attachments();}
52 :
53 : RasterLayersProjector (SPIGeometry3d geometry, SPRasterLayers layers) :
54 : RefinementProjector (geometry)
55 : {add_attachments();
56 : set_layers(layers);}
57 :
58 0 : void set_geometry(SPIGeometry3d g)
59 : {
60 0 : if(g == geometry())
61 : return;
62 :
63 0 : remove_attachments();
64 0 : RefinementProjector::set_geometry(g);
65 0 : add_attachments();
66 : }
67 :
68 : void set_layers(SPRasterLayers layers)
69 : {m_layers = layers;}
70 :
71 : rel_z_attachment_t rel_z_attachment () const {return m_aRelZ;}
72 : rel_z_attachment_accessor_t rel_z_attachment_accessor () const {return m_aaRelZ;}
73 :
74 : number average_rel_z(Vertex* e) const {return m_aaRelZ[e];}
75 :
76 : template <class TElem>
77 0 : number average_rel_z(TElem* e) const
78 : {
79 0 : typename TElem::ConstVertexArray vrts = e->vertices();
80 0 : const size_t numVrts = e->num_vertices();
81 0 : if(numVrts == 0)
82 : return 0;
83 :
84 : number relZ = 0;
85 0 : for(size_t i = 0; i < numVrts; ++i){
86 0 : relZ += m_aaRelZ[vrts[i]];
87 : }
88 :
89 0 : return relZ / (number)numVrts;
90 : }
91 :
92 0 : virtual number new_vertex(Vertex* vrt, Vertex* parent)
93 : {
94 0 : m_aaRelZ[vrt] = m_aaRelZ[parent];
95 0 : set_pos(vrt, pos(parent));
96 0 : return 1;
97 : }
98 :
99 0 : virtual number new_vertex(Vertex* vrt, Edge* parent)
100 : {
101 0 : return new_vertex_impl(vrt, parent);
102 : }
103 :
104 0 : virtual number new_vertex(Vertex* vrt, Face* parent)
105 : {
106 0 : return new_vertex_impl(vrt, parent);
107 : }
108 :
109 0 : virtual number new_vertex(Vertex* vrt, Volume* parent)
110 : {
111 0 : return new_vertex_impl(vrt, parent);
112 : }
113 :
114 : private:
115 : template <class TParent>
116 0 : number new_vertex_impl(Vertex* vrt, TParent* parent)
117 : {
118 0 : const number relZ = average_rel_z(parent);
119 0 : m_aaRelZ[vrt] = relZ;
120 0 : vector3 p = geom().element_center(parent);
121 0 : p.z() = m_layers->relative_to_global_height(vector2(p.x(), p.y()), relZ);
122 : set_pos(vrt, p);
123 0 : return 1;
124 : }
125 :
126 0 : void add_attachments ()
127 : {
128 0 : static const std::string attName("RasterLayersProjector_ARelZ");
129 0 : if(!GlobalAttachments::is_declared(attName)){
130 0 : GlobalAttachments::declare_attachment<rel_z_attachment_t>(attName);
131 : }
132 :
133 0 : m_aRelZ = GlobalAttachments::attachment<rel_z_attachment_t>(attName);
134 :
135 : IGeometry3d& g = geom();
136 0 : if(!g.grid().has_attachment<Vertex>(m_aRelZ)){
137 0 : g.grid().attach_to_vertices(m_aRelZ);
138 : }
139 0 : m_aaRelZ.access(g.grid(), m_aRelZ);
140 0 : }
141 :
142 0 : void remove_attachments ()
143 : {
144 0 : SPIGeometry3d geom = geometry();
145 0 : if(geom.valid() && geom->grid().has_vertex_attachment(m_aRelZ)){
146 0 : geom->grid().detach_from_vertices(m_aRelZ);
147 : m_aaRelZ.invalidate();
148 : }
149 0 : }
150 :
151 : friend class boost::serialization::access;
152 :
153 : template <class Archive>
154 0 : void serialize( Archive& ar, const unsigned int version)
155 : {
156 : using namespace ug;
157 : if(ArchiveInfo<Archive>::TYPE == AT_DATA){
158 0 : if(m_layers.invalid())
159 0 : m_layers = make_sp(new RasterLayers());
160 : ar & *m_layers;
161 : }
162 : else if (ArchiveInfo<Archive>::TYPE == AT_GUI){
163 : }
164 :
165 : UG_EMPTY_BASE_CLASS_SERIALIZATION(RasterLayersProjector, RefinementProjector);
166 0 : }
167 :
168 : SPRasterLayers m_layers;
169 : rel_z_attachment_t m_aRelZ;
170 : rel_z_attachment_accessor_t m_aaRelZ;
171 : };
172 :
173 : typedef SmartPtr<RasterLayersProjector> SPRasterLayersProjector;
174 :
175 : }// end of namespace
176 :
177 : #endif //__H__UG_raster_layers_projector
|