Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: 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 : #include <vector>
34 : #include <string>
35 : #include <sstream>
36 : #include <algorithm>
37 :
38 : // include bridge
39 : #include "bridge/bridge.h"
40 : #include "bridge/util.h"
41 : #include "bridge/util_domain_dependent.h"
42 :
43 : #include "lib_disc/domain.h"
44 : #include "lib_grid/lib_grid.h"
45 :
46 : using namespace std;
47 :
48 : namespace ug{
49 :
50 : /**
51 : * \defgroup transform_bridge Transformation Bridge
52 : * \ingroup domain_bridge
53 : * \{
54 : */
55 :
56 : ////////////////////////////////////////////////////////////////////////////////
57 : /// Translates (moves) selected elements by the given offset
58 : template <class TDomain>
59 0 : void TranslateDomain(TDomain& dom, ISelector& sel, const vector3& offset)
60 :
61 : {
62 : typedef typename TDomain::position_type pos_t;
63 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
64 :
65 : pos_t o;
66 : VecCopy(o, offset, 0);
67 :
68 : // perform the translation
69 : vector<Vertex*> vrts;
70 0 : CollectVerticesTouchingSelection(vrts, sel);
71 :
72 0 : for(size_t i = 0; i < vrts.size(); ++i){
73 0 : pos_t& v = aaPos[vrts[i]];
74 : VecAdd(v, v, o);
75 : }
76 0 : }
77 :
78 :
79 : ////////////////////////////////////////////////////////////////////////////////
80 : /// Scales selected elements around the given center.
81 : template <class TDomain>
82 0 : void ScaleDomain(TDomain& dom, const vector3& center, const vector3& scale)
83 :
84 : {
85 : typedef typename TDomain::position_type pos_t;
86 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
87 : typedef typename TDomain::grid_type grid_t;
88 : typedef typename grid_t::template traits<Vertex>::iterator vrt_iterator_t;
89 :
90 0 : grid_t& g = *dom.grid();
91 : pos_t c, s;
92 : VecCopy(c, center, 0);
93 : VecCopy(s, scale, 1);
94 :
95 : // perform the scaling
96 : for(vrt_iterator_t iter = g.template begin<Vertex>();
97 0 : iter != g.template end<Vertex>(); ++iter)
98 : {
99 : pos_t& v = aaPos[*iter];
100 0 : for(size_t j = 0; j < pos_t::Size; ++j)
101 0 : v[j] = c[j] + (v[j] - c[j]) * s[j];
102 : }
103 0 : }
104 :
105 :
106 : ////////////////////////////////////////////////////////////////////////////////
107 : /// Scales selected elements around the given center.
108 : template <class TDomain>
109 0 : void ScaleDomain(TDomain& dom, ISelector& sel, const vector3& center,
110 : const vector3& scale)
111 :
112 : {
113 : typedef typename TDomain::position_type pos_t;
114 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
115 :
116 : pos_t c, s;
117 : VecCopy(c, center, 0);
118 : VecCopy(s, scale, 1);
119 :
120 : // perform the scaling
121 : vector<Vertex*> vrts;
122 0 : CollectVerticesTouchingSelection(vrts, sel);
123 :
124 0 : if(vrts.empty()){
125 : return;
126 : }
127 :
128 0 : for(size_t i = 0; i < vrts.size(); ++i){
129 0 : pos_t& v = aaPos[vrts[i]];
130 :
131 0 : for(size_t j = 0; j < pos_t::Size; ++j)
132 0 : v[j] = c[j] + (v[j] - c[j]) * s[j];
133 : }
134 0 : }
135 :
136 : template <class TDomain>
137 0 : void ScaleDomainSquaredWeighting(TDomain& dom, ISelector& sel, const vector3& center,
138 : const vector3& scale)
139 :
140 : {
141 : typedef typename TDomain::position_type pos_t;
142 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
143 :
144 : pos_t c, s;
145 : VecCopy(c, center, 0);
146 : VecCopy(s, scale, 1);
147 :
148 : // prepare data
149 : vector<Vertex*> vrts;
150 0 : CollectVerticesTouchingSelection(vrts, sel);
151 0 : if(vrts.empty())
152 : return;
153 :
154 : number dMaxSq = -1;
155 0 : for(size_t i = 0; i < vrts.size(); ++i){
156 0 : number distSq = VecDistanceSq(c, aaPos[vrts[i]]);
157 0 : if( distSq > dMaxSq )
158 : dMaxSq = distSq;
159 : }
160 0 : number dMax = sqrt(dMaxSq);
161 :
162 : // perform the scaling
163 0 : for(size_t i = 0; i < vrts.size(); ++i){
164 0 : pos_t& v = aaPos[vrts[i]];
165 0 : number dist = VecDistance(c, v);
166 0 : number sqrdWeight = (dist/dMax)*(dist/dMax);
167 :
168 0 : for(size_t j = 0; j < pos_t::Size; ++j)
169 0 : v[j] = c[j] + (v[j] - c[j]) * ((s[j]-1.0)*sqrdWeight + 1.0);
170 : }
171 :
172 0 : }
173 :
174 : template <class TDomain>
175 0 : void ScaleDomainWeighting(TDomain& dom, ISelector& sel, const vector3& center,
176 : const vector3& scale)
177 :
178 : {
179 : typedef typename TDomain::position_type pos_t;
180 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
181 :
182 : pos_t c, s;
183 : VecCopy(c, center, 0);
184 : VecCopy(s, scale, 1);
185 :
186 : // prepare data
187 : vector<Vertex*> vrts;
188 0 : CollectVerticesTouchingSelection(vrts, sel);
189 0 : if(vrts.empty())
190 : return;
191 :
192 : number dMaxSq = -1;
193 0 : for(size_t i = 0; i < vrts.size(); ++i){
194 0 : number distSq = VecDistanceSq(c, aaPos[vrts[i]]);
195 0 : if( distSq > dMaxSq )
196 : dMaxSq = distSq;
197 : }
198 0 : number dMax = sqrt(dMaxSq);
199 :
200 : // perform the scaling
201 0 : for(size_t i = 0; i < vrts.size(); ++i){
202 0 : pos_t& v = aaPos[vrts[i]];
203 0 : number dist = VecDistance(c, v);
204 0 : number weight = dist/dMax;
205 :
206 0 : for(size_t j = 0; j < pos_t::Size; ++j)
207 0 : v[j] = c[j] + (v[j] - c[j]) * ((s[j]-1.0)*weight + 1.0);
208 : }
209 0 : }
210 :
211 :
212 : template <class TDomain>
213 0 : void ScaleDomainSqrtWeighting(TDomain& dom, ISelector& sel, const vector3& center,
214 : const vector3& scale)
215 :
216 : {
217 : typedef typename TDomain::position_type pos_t;
218 : typename TDomain::position_accessor_type& aaPos = dom.position_accessor();
219 :
220 : pos_t c, s;
221 : VecCopy(c, center, 0);
222 : VecCopy(s, scale, 1);
223 :
224 : // prepare data
225 : vector<Vertex*> vrts;
226 0 : CollectVerticesTouchingSelection(vrts, sel);
227 0 : if(vrts.empty())
228 : return;
229 :
230 : number dMaxSq = -1;
231 0 : for(size_t i = 0; i < vrts.size(); ++i){
232 0 : number distSq = VecDistanceSq(c, aaPos[vrts[i]]);
233 0 : if( distSq > dMaxSq )
234 : dMaxSq = distSq;
235 : }
236 0 : number dMax = sqrt(dMaxSq);
237 :
238 : // perform the scaling
239 0 : for(size_t i = 0; i < vrts.size(); ++i){
240 0 : pos_t& v = aaPos[vrts[i]];
241 0 : number dist = VecDistance(c, v);
242 0 : number weight = sqrt(dist/dMax);
243 :
244 0 : for(size_t j = 0; j < pos_t::Size; ++j)
245 0 : v[j] = c[j] + (v[j] - c[j]) * ((s[j]-1.0)*weight + 1.0);
246 : }
247 :
248 0 : }
249 :
250 : // end group transform_bridge
251 : /// \}
252 :
253 : ////////////////////////////////////////////////////////////////////////////////
254 : ////////////////////////////////////////////////////////////////////////////////
255 : namespace bridge{
256 : namespace Transform{
257 :
258 : /// \addtogroup transform_bridge
259 : /// \{
260 :
261 : /**
262 : * Class exporting the functionality. All functionality that is to
263 : * be used in scripts or visualization must be registered here.
264 : */
265 : struct Functionality
266 : {
267 :
268 : /**
269 : * Function called for the registration of Domain dependent parts.
270 : * All Functions and Classes depending on the Domain
271 : * are to be placed here when registering. The method is called for all
272 : * available Domain types, based on the current build options.
273 : *
274 : * @param reg registry
275 : * @param parentGroup group for sorting of functionality
276 : */
277 : template <typename TDomain>
278 3 : static void Domain(Registry& reg, string grp)
279 : {
280 : typedef TDomain domain_type;
281 :
282 9 : reg.add_function("TranslateDomain", &TranslateDomain<domain_type>, grp, "", "dom#sel#offset");
283 9 : reg.add_function("ScaleDomain",
284 : static_cast<void (*)(domain_type&, const vector3&, const vector3&)>
285 : (&ScaleDomain<domain_type>), grp, "", "dom#center#scale");
286 9 : reg.add_function("ScaleDomain",
287 : static_cast<void (*)(domain_type&, ISelector&, const vector3&, const vector3&)>
288 : (&ScaleDomain<domain_type>), grp, "", "dom#sel#center#scale");
289 9 : reg.add_function("ScaleDomainSqrtWeighting", &ScaleDomainSqrtWeighting<domain_type>, grp, "", "dom#sel#center#scale");
290 9 : reg.add_function("ScaleDomainWeighting", &ScaleDomainWeighting<domain_type>, grp, "", "dom#sel#center#scale");
291 9 : reg.add_function("ScaleDomainSquaredWeighting", &ScaleDomainSquaredWeighting<domain_type>, grp, "", "dom#sel#center#scale");
292 :
293 3 : }
294 :
295 : }; // end Functionality
296 :
297 : // end group transform_bridge
298 : /// \}
299 :
300 : }// end Refinement
301 :
302 : /// \addtogroup transform_bridge
303 1 : void RegisterBridge_Transform(Registry& reg, string grp)
304 : {
305 1 : grp.append("/Transform");
306 : typedef Transform::Functionality Functionality;
307 :
308 : try{
309 1 : RegisterDomainDependent<Functionality>(reg, grp);
310 : }
311 0 : UG_REGISTRY_CATCH_THROW(grp);
312 1 : }
313 :
314 : }// end of namespace bridge
315 : }// end of namespace ug
|