Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Authors: Sebastian Reiter, Andreas Vogel
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 "bridge/bridge.h"
34 : #include "lib_algebra/algebra_type.h"
35 : #include "common/util/path_provider.h"
36 : #include "common/profiler/profiler.h"
37 : #include "bridge/util.h"
38 : #include "bridge/standard_bridges.h"
39 :
40 : #ifdef UG_PARALLEL
41 : #include "pcl/pcl.h"
42 : #endif
43 :
44 :
45 : using namespace std;
46 :
47 : namespace ug
48 : {
49 : namespace bridge
50 : {
51 :
52 : const char* UG4_GRP = "/ug4";
53 :
54 : /// the dimension to which ug was initialized through InitUG
55 : /** This dimension can be accessed through GetUGDim()*/
56 : static int UG4_DIM = -1;
57 :
58 4 : Registry & GetUGRegistry()
59 : {
60 4 : static Registry ugReg;
61 4 : return ugReg;
62 : }
63 :
64 : /// calls RegisterStandardInterfaces
65 1 : void InitBridge()
66 : {
67 : PROFILE_FUNC();
68 : // initialize ug-interfaces
69 1 : RegisterStandardBridges(bridge::GetUGRegistry());
70 1 : }
71 :
72 :
73 : /// Sets the default classes of class-groups based on a tags
74 : /** If a class has a tag (e.g. "dim=1d", "dim=2d" or "dim=3d") then it will be set
75 : * as default - depending on the given tags.
76 : */
77 0 : void InitUG(int dim, const AlgebraType& algType, bool verbose)
78 : {
79 : PROFILE_FUNC();
80 0 : UG4_DIM = dim;
81 :
82 : // get tag of algebra type
83 0 : const std::string& algTag = GetAlgebraTag(algType);
84 : int blocksize = algType.blocksize();
85 0 : if( (blocksize < 0 || blocksize > 6) && blocksize != AlgebraType::VariableBlockSize)
86 0 : UG_THROW("ERROR in InitUG: Only Algebra Blocksizes '1x1', '2x2', '3x3', '4x4', '5x5', '6x6' and 'variable' are supported.");
87 :
88 : #ifdef UG_ALGEBRA
89 0 : if(algType.type() == AlgebraType::CPU)
90 : {
91 : #ifndef UG_CPU_1
92 : if(blocksize == 1)
93 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '1x1' is not compiled into binary.");
94 : #endif
95 : #ifndef UG_CPU_2
96 : if(blocksize == 2)
97 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '2x2' is not compiled into binary.");
98 : #endif
99 : #ifndef UG_CPU_3
100 : if(blocksize == 3)
101 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '3x3' is not compiled into binary.");
102 : #endif
103 : #ifndef UG_CPU_4
104 0 : if(blocksize == 4)
105 0 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '4x4' is not compiled into binary.");
106 : #endif
107 : #ifndef UG_CPU_5
108 0 : if(blocksize == 5)
109 0 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '5x5' is not compiled into binary.");
110 : #endif
111 : #ifndef UG_CPU_6
112 0 : if(blocksize == 6)
113 0 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize '6x6' is not compiled into binary.");
114 : #endif
115 : #ifndef UG_CPU_VAR
116 0 : if(blocksize == AlgebraType::VariableBlockSize)
117 0 : UG_THROW("ERROR in InitUG: Requested Algebra CPU, Blocksize 'variable' is not compiled into binary.");
118 : #endif
119 : }
120 0 : else if(algType.type() == AlgebraType::GPU)
121 : {
122 0 : if(blocksize != 1)
123 0 : UG_THROW("ERROR in InitUG: Requested Algebra GPU, Blocksize '" << blocksize << "x" << blocksize << "' is not compiled into binary.");
124 : }
125 : #endif
126 :
127 : // get dim tag
128 0 : std::string dimTag = GetDimensionTag(dim);
129 0 : if(dim < 0 || dim > 3)
130 0 : UG_THROW("ERROR in InitUG: Only dimensions 1, 2, 3 are supported.");
131 : #ifndef UG_DIM_1
132 : if(dim == 1)
133 : UG_THROW("ERROR in InitUG: Requested Dimension '1d' is not compiled into binary.");
134 : #endif
135 : #ifndef UG_DIM_2
136 : if(dim == 2)
137 : UG_THROW("ERROR in InitUG: Requested Dimension '2d' is not compiled into binary.");
138 : #endif
139 : #ifndef UG_DIM_3
140 : if(dim == 3)
141 : UG_THROW("ERROR in InitUG: Requested Dimension '3d' is not compiled into binary.");
142 : #endif
143 :
144 0 : bridge::Registry& reg = bridge::GetUGRegistry();
145 :
146 : // iterate over all groups in the registry and check how many tags they contain
147 : // then find out if a class matches exactly this number of tags for the given
148 : // tag set.
149 0 : for(size_t i_grp = 0; i_grp < reg.num_class_groups(); ++i_grp)
150 : {
151 : // get class group
152 0 : ClassGroupDesc* grp = reg.get_class_group(i_grp);
153 :
154 : // count how many tags are contained in tag string
155 : int numTag = -1;
156 0 : for(size_t i = 0; i < grp->num_classes(); ++i)
157 : {
158 : const std::string& tag = grp->get_class_tag(i);
159 0 : int num = (int) count (tag.begin(), tag.end(), ';');
160 0 : if(numTag == -1) numTag = num;
161 0 : else if(numTag != num)
162 0 : UG_THROW("Class Group with classes of different number"
163 : " of tags found.");
164 : }
165 :
166 : // find the class with numTag matches
167 0 : for(size_t i = 0; i < grp->num_classes(); ++i)
168 : {
169 : // get tag of class
170 : const std::string& tag = grp->get_class_tag(i);
171 :
172 : // count matches
173 : int found = 0;
174 0 : if(tag.find(dimTag) != string::npos) ++found;
175 0 : if(tag.find(algTag) != string::npos) ++found;
176 :
177 : // if exactly as many matches as tags, set this class
178 0 : if(found == numTag)
179 : {
180 : grp->set_default_class(i); break;
181 : }
182 : }
183 : }
184 :
185 0 : if(verbose){
186 : UG_LOG("INFO: InitUG successful. Setting is: ");
187 : UG_LOG(dimTag << " " << algTag << "\n");
188 : #ifdef UG_PARALLEL
189 : UG_LOG(" Parallel Environment: Num Procs="<<pcl::NumProcs()<<"\n");
190 : #endif
191 : }
192 :
193 : #ifdef UG_ALGEBRA
194 : DefaultAlgebra::set(algType);
195 : #endif
196 0 : }
197 :
198 : // forward for default case
199 0 : void InitUG(int dim, const AlgebraType& algType)
200 : {
201 0 : InitUG(dim, algType, false);
202 0 : }
203 :
204 :
205 0 : int GetUGDim()
206 : {
207 0 : return UG4_DIM;
208 : }
209 :
210 1 : void RegisterStandardBridges(Registry& reg, string parentGroup)
211 : {
212 : try
213 : {
214 : // uncomment this to register test-methods
215 : //RegisterBridge_Test(reg, parentGroup);
216 :
217 2 : RegisterBridge_VecMath(reg, parentGroup);
218 2 : RegisterBridge_Util(reg, parentGroup);
219 2 : RegisterBridge_PCL(reg, parentGroup);
220 :
221 2 : RegisterBridge_Profiler(reg, parentGroup);
222 2 : RegisterBridge_Misc(reg, parentGroup);
223 2 : RegisterBridge_Raster(reg, parentGroup);
224 2 : RegisterBridge_OrthoPoly(reg, parentGroup);
225 :
226 : #ifdef UG_GRID
227 2 : RegisterBridge_Grid(reg, parentGroup);
228 : #endif
229 :
230 : #ifdef UG_ALGEBRA
231 2 : RegisterBridge_Selection(reg, parentGroup);
232 2 : RegisterBridge_Domain(reg, parentGroup);
233 2 : RegisterBridge_PeriodicBoundary(reg, parentGroup);
234 2 : RegisterBridge_Refinement(reg, parentGroup);
235 2 : RegisterBridge_DomainRayTracing(reg, parentGroup);
236 2 : RegisterBridge_Transform(reg, parentGroup);
237 2 : RegisterBridge_LoadBalancing(reg, parentGroup);
238 :
239 : // depends on lib_disc
240 2 : RegisterBridge_DiscCommon(reg, parentGroup);
241 2 : RegisterBridge_ElemDiscs(reg, parentGroup);
242 :
243 : // depends on lib_algebra
244 2 : RegisterBridge_AlgebraCommon(reg, parentGroup);
245 2 : RegisterBridge_Preconditioner(reg, parentGroup);
246 2 : RegisterBridge_Schur(reg, parentGroup);
247 2 : RegisterBridge_Obstacle(reg, parentGroup);
248 2 : RegisterBridge_PILUT(reg, parentGroup);
249 2 : RegisterBridge_AlgebraOrdering(reg, parentGroup);
250 2 : RegisterBridge_Solver(reg, parentGroup);
251 2 : RegisterBridge_Eigensolver(reg, parentGroup);
252 2 : RegisterBridge_DomainDependentPreconditioner(reg, parentGroup);
253 : //RegisterBridge_ConstrainedLinearIterator(reg, parentGroup);
254 :
255 2 : RegisterBridge_Restart(reg, parentGroup);
256 :
257 : // depends on lib_disc
258 2 : RegisterBridge_DiscAlgebra(reg, parentGroup);
259 2 : RegisterBridge_DomainDisc(reg, parentGroup);
260 2 : RegisterBridge_GridFunction(reg, parentGroup);
261 2 : RegisterBridge_Interpolate(reg, parentGroup);
262 2 : RegisterBridge_Evaluate(reg, parentGroup);
263 2 : RegisterBridge_MaxError(reg, parentGroup);
264 2 : RegisterBridge_Ordering(reg, parentGroup);
265 2 : RegisterBridge_UserData(reg, parentGroup);
266 2 : RegisterBridge_Constraints(reg, parentGroup);
267 2 : RegisterBridge_MultiGrid(reg, parentGroup);
268 2 : RegisterBridge_Output(reg, parentGroup);
269 2 : RegisterBridge_AdaptiveTools(reg, parentGroup);
270 2 : RegisterBridge_FiniteVolume(reg, parentGroup);
271 2 : RegisterBridge_Integrate(reg, parentGroup);
272 2 : RegisterBridge_ManifoldUtil(reg, parentGroup);
273 1 : RegisterBridge_ReferenceMappingTest(reg, parentGroup);
274 : #endif
275 :
276 :
277 : // build a string with all compiled dimensions
278 1 : stringstream availDims; bool first = true;
279 : #ifdef UG_DIM_1
280 1 : if(!first) {availDims << ",";}; availDims << "1";
281 : first = false;
282 : #endif
283 : #ifdef UG_DIM_2
284 1 : if(!first) {availDims << ",";}; availDims << "2";
285 : first = false;
286 : #endif
287 : #ifdef UG_DIM_3
288 1 : if(!first) {availDims << ",";}; availDims << "3";
289 : #endif
290 :
291 : #ifdef UG_ALGEBRA
292 4 : reg.add_function("InitUG", static_cast<void (*)(int, const AlgebraType&, bool)>(&InitUG), "/ug4/Init",
293 2 : "", string("Dimension|selection|value=[").append(availDims.str()).
294 1 : append("]#AlgebraType#verbose"));
295 4 : reg.add_function("InitUG", static_cast<void (*)(int, const AlgebraType&)>(&InitUG), "/ug4/Init",
296 2 : "", string("Dimension|selection|value=[").append(availDims.str()).
297 1 : append("]#AlgebraType"));
298 2 : reg.add_function("GetUGDim", &GetUGDim, "/ug4", "dimension", "", "Returns the dimension to which UG was initialized.");
299 :
300 : // AlgebraType Interface
301 2 : reg.add_class_<AlgebraType>("AlgebraType", "/ug4/Init")
302 2 : .add_constructor<void (*)(const char*, int)>("Type|selection|value=[\"CPU\"]#Blocksize|selection|value=[1,2,3,4]")
303 2 : .add_constructor<void (*)(const char*)>("Type|selection|value=[\"CPU\"]", "Variable Blocksize")
304 1 : .set_construct_as_smart_pointer(true);
305 : #endif
306 :
307 1 : }
308 0 : UG_REGISTRY_CATCH_THROW("RegisterStandardInterfaces")
309 0 : UG_CATCH_THROW("RegisterStandardInterfaces failed.")
310 :
311 1 : reg.registry_changed();
312 1 : }
313 :
314 : }// end of namespace
315 : }// end of namespace
|