Line data Source code
1 : /*
2 : * Copyright (c) 2013-2015: G-CSC, Goethe University Frankfurt
3 : * Author: 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 : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__DISC_UTIL__GEOM_PROVIDER__
34 : #define __H__UG__LIB_DISC__SPATIAL_DISC__DISC_UTIL__GEOM_PROVIDER__
35 :
36 : #include <map>
37 : #include "lib_disc/local_finite_element/local_finite_element_id.h"
38 :
39 : namespace ug{
40 :
41 :
42 : /// Geom Provider, holding a single instance of a geometry
43 : /**
44 : * This class is used to wrap an object into a singleton-like provider, such
45 : * that construction computations is avoided, if the object is used several times.
46 : *
47 : * In addition, the object can be shared between unrelated code parts, if the
48 : * same object is intended to be used, but no passing is possible or wanted.
49 : */
50 : template <typename TGeom>
51 : class GeomProvider
52 : {
53 : public:
54 : /// flag indicating if local data may change
55 : /**
56 : * If the local data may change due to run-time setting of trial space
57 : * or quadrature order, we must store one object for each type.
58 : * In such a case we must store each combination in some data structure
59 : * and return the correct one based on the identifier.
60 : */
61 : static const bool staticLocalData = TGeom::staticLocalData;
62 :
63 : protected:
64 : /// private constructor
65 : GeomProvider() {m_mLFEIDandOrder.clear();}
66 :
67 : /// destructor
68 0 : ~GeomProvider() {clear_geoms();}
69 :
70 : /// singleton provider
71 0 : static GeomProvider<TGeom>& inst() {
72 0 : static GeomProvider<TGeom> inst;
73 0 : return inst;
74 : }
75 :
76 : /// struct to sort keys
77 : struct LFEIDandQuadOrder{
78 0 : LFEIDandQuadOrder(const LFEID lfeID, const int order)
79 0 : : m_lfeID(lfeID), m_order(order) {}
80 :
81 : /// operator <
82 0 : bool operator<(const LFEIDandQuadOrder& v) const
83 : {
84 : if(m_lfeID != v.m_lfeID) return m_lfeID < v.m_lfeID;
85 0 : else return m_order < v.m_order;
86 : }
87 :
88 : const LFEID m_lfeID;
89 : const int m_order;
90 : };
91 :
92 : /// vector holding instances
93 : typedef std::map<LFEIDandQuadOrder, TGeom*> MapType;
94 : static MapType m_mLFEIDandOrder;
95 :
96 : /// returns class based on identifier
97 0 : static TGeom& get_class(const LFEID lfeID, const int quadOrder) {
98 :
99 : LFEIDandQuadOrder key(lfeID, quadOrder);
100 :
101 : typedef std::pair<typename MapType::iterator,bool> ret_type;
102 0 : ret_type ret = m_mLFEIDandOrder.insert(std::pair<LFEIDandQuadOrder,TGeom*>(key,NULL));
103 :
104 : // newly inserted, need construction of data
105 0 : if(ret.second == true){
106 0 : if(ret.first->second != NULL){
107 0 : UG_THROW("Newly inserted element must have Pointer = NULL");
108 : }
109 : else{
110 0 : ret.first->second = new TGeom();
111 : }
112 : }
113 :
114 0 : return *ret.first->second;
115 : }
116 :
117 : /// clears all instances
118 0 : static void clear_geoms(){
119 : typedef typename std::map<LFEIDandQuadOrder, TGeom*>::iterator MapIter;
120 0 : for(MapIter iter = m_mLFEIDandOrder.begin(); iter != m_mLFEIDandOrder.end(); ++iter)
121 0 : if(iter->second)
122 0 : delete iter->second;
123 :
124 : m_mLFEIDandOrder.clear();
125 0 : }
126 :
127 : public:
128 : /// type of provided object
129 : typedef TGeom Type;
130 :
131 : /// returns a singleton based on the identifier
132 : static inline TGeom& get(const LFEID lfeID, const int quadOrder){
133 : // in case of static data, use only one object
134 0 : if(staticLocalData) return get();
135 :
136 : // return the object based on identifier
137 0 : return inst().get_class(lfeID, quadOrder);
138 : }
139 :
140 : /// returns a singleton based on the identifier
141 0 : static inline TGeom& get(){
142 0 : static TGeom inst;
143 : if(!staticLocalData)
144 0 : UG_THROW("GeomProvider: accessing geometry without keys, but"
145 : " geometry may change local data. Use access by keys instead.");
146 0 : return inst;
147 : }
148 :
149 : /// clears all singletons
150 : static inline void clear(){
151 : inst().clear_geoms();
152 : }
153 : };
154 :
155 : template <typename TGeom>
156 : std::map<typename GeomProvider<TGeom>::LFEIDandQuadOrder, TGeom*> GeomProvider<TGeom>::m_mLFEIDandOrder
157 : = std::map<typename GeomProvider<TGeom>::LFEIDandQuadOrder, TGeom*>();
158 :
159 :
160 : } // end namespace ug
161 :
162 : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DISC_UTIL__GEOM_PROVIDER__ */
|