Line data Source code
1 : /*
2 : * Copyright (c) 2012-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__STD_USER_DATA__
34 : #define __H__UG__LIB_DISC__SPATIAL_DISC__STD_USER_DATA__
35 :
36 : #include "user_data.h"
37 :
38 : namespace ug{
39 :
40 : ///////////////////////////////////////////////////////////////////////////////
41 : // Wrapper Class for UserData
42 : ///////////////////////////////////////////////////////////////////////////////
43 :
44 : /**
45 : * This class is used as a wrapper class for user data in order to ease the
46 : * implementation of the virtual evaluation operators through templated
47 : * methods evaluate.
48 : *
49 : * template \<int refDim\>
50 : * inline TRet evaluate(TData vValue[],
51 : const MathVector\<dim\> vGlobIP[],
52 : number time, int si,
53 : GridObject* elem,
54 : const MathVector\<dim\> vCornerCoords[],
55 : const MathVector\<refDim\> vLocIP[],
56 : const size_t nip,
57 : LocalVector* u,
58 : const MathMatrix\<refDim, dim\>* vJT = NULL) const
59 : *
60 : */
61 : template <typename TImpl, typename TData, int dim, typename TRet = void, typename TBase = CplUserData<TData, dim, TRet> >
62 0 : class StdUserData : public TBase
63 : {
64 : public:
65 : /// returns value for a global position
66 : virtual TRet operator() (TData& value,
67 : const MathVector<dim>& globIP,
68 : number time, int si) const = 0;
69 :
70 : /// returns value for global positions
71 : virtual void operator()(TData vValue[],
72 : const MathVector<dim> vGlobIP[],
73 : number time, int si, const size_t nip) const = 0;
74 :
75 : /// returns values for local and global positions
76 : /// \{
77 0 : virtual void operator()(TData vValue[],
78 : const MathVector<dim> vGlobIP[],
79 : number time, int si,
80 : GridObject* elem,
81 : const MathVector<dim> vCornerCoords[],
82 : const MathVector<1> vLocIP[],
83 : const size_t nip,
84 : LocalVector* u,
85 : const MathMatrix<1, dim>* vJT = NULL) const
86 : {
87 0 : getImpl().template evaluate<1>(vValue,vGlobIP,time,si,elem,
88 : vCornerCoords,vLocIP,nip,u,vJT);
89 0 : }
90 :
91 0 : virtual void operator()(TData vValue[],
92 : const MathVector<dim> vGlobIP[],
93 : number time, int si,
94 : GridObject* elem,
95 : const MathVector<dim> vCornerCoords[],
96 : const MathVector<2> vLocIP[],
97 : const size_t nip,
98 : LocalVector* u,
99 : const MathMatrix<2, dim>* vJT = NULL) const
100 : {
101 0 : getImpl().template evaluate<2>(vValue,vGlobIP,time,si,elem,
102 : vCornerCoords,vLocIP,nip,u,vJT);
103 0 : }
104 :
105 0 : virtual void operator()(TData vValue[],
106 : const MathVector<dim> vGlobIP[],
107 : number time, int si,
108 : GridObject* elem,
109 : const MathVector<dim> vCornerCoords[],
110 : const MathVector<3> vLocIP[],
111 : const size_t nip,
112 : LocalVector* u,
113 : const MathMatrix<3, dim>* vJT = NULL) const
114 : {
115 0 : getImpl().template evaluate<3>(vValue,vGlobIP,time,si,elem,
116 : vCornerCoords,vLocIP,nip,u,vJT);
117 0 : }
118 :
119 : /// \}
120 : protected:
121 : /// access to implementation
122 : TImpl& getImpl() {return static_cast<TImpl&>(*this);}
123 :
124 : /// const access to implementation
125 : const TImpl& getImpl() const {return static_cast<const TImpl&>(*this);}
126 : };
127 :
128 : template <typename TImpl, typename TData, int dim>
129 : class StdDependentUserData
130 : : public StdUserData< StdDependentUserData<TImpl, TData, dim>,
131 : TData, dim, void,
132 : DependentUserData<TData, dim> >
133 : {
134 : public:
135 0 : StdDependentUserData(){}
136 :
137 0 : StdDependentUserData(const char* symbFct) {this->set_functions(symbFct);}
138 : StdDependentUserData(const std::string& symbFct) {this->set_functions(symbFct);}
139 : StdDependentUserData(const std::vector<std::string>& symbFct) {this->set_functions(symbFct);}
140 :
141 : public:
142 0 : virtual void operator() (TData& value,
143 : const MathVector<dim>& globIP,
144 : number time, int si) const
145 : {
146 0 : UG_THROW("StdDependentUserData: Solution, element and local ips required "
147 : "for evaluation, but not passed. Cannot evaluate.");
148 : }
149 :
150 0 : virtual void operator()(TData vValue[],
151 : const MathVector<dim> vGlobIP[],
152 : number time, int si, const size_t nip) const
153 : {
154 0 : UG_THROW("StdDependentUserData: Solution, element and local ips required "
155 : "for evaluation, but not passed. Cannot evaluate.");
156 : }
157 :
158 : template <int refDim>
159 : inline void evaluate(TData vValue[],
160 : const MathVector<dim> vGlobIP[],
161 : number time, int si,
162 : GridObject* elem,
163 : const MathVector<dim> vCornerCoords[],
164 : const MathVector<refDim> vLocIP[],
165 : const size_t nip,
166 : LocalVector* u,
167 : const MathMatrix<refDim, dim>* vJT = NULL) const
168 : {
169 : const_cast<TImpl*>(static_cast<const TImpl*>(this))->
170 0 : template eval_and_deriv<refDim>(vValue,vGlobIP,time,si,elem,
171 : vCornerCoords,vLocIP,nip,u,
172 : false,0,NULL,vJT);
173 : }
174 :
175 : template <int refDim>
176 0 : void eval_deriv(LocalVector* u, GridObject* elem,
177 : const MathVector<dim> vCornerCoords[], bool bDeriv = false) {
178 :
179 : const int si = this->subset();
180 :
181 : std::vector<std::vector<TData> >* vvvDeriv = NULL;
182 :
183 0 : for(size_t s = 0; s < this->num_series(); ++s){
184 :
185 0 : if(bDeriv && this->m_vvvvDeriv[s].size() > 0)
186 : vvvDeriv = &this->m_vvvvDeriv[s][0];
187 : else
188 : vvvDeriv = NULL;
189 :
190 0 : getImpl().template eval_and_deriv<refDim>(this->values(s), this->ips(s), this->time(s), si,
191 : elem, vCornerCoords,
192 : this->template local_ips<refDim>(s), this->num_ip(s),
193 : u, bDeriv, s, vvvDeriv);
194 : }
195 0 : }
196 :
197 : template <int refDim>
198 0 : void eval_deriv(LocalVectorTimeSeries* u, GridObject* elem,
199 : const MathVector<dim> vCornerCoords[], bool bDeriv = false) {
200 :
201 : const int si = this->subset();
202 :
203 : std::vector<std::vector<TData> >* vvvDeriv = NULL;
204 :
205 0 : for(size_t s = 0; s < this->num_series(); ++s){
206 :
207 0 : bool bDoDeriv = bDeriv && this->at_current_time (s); // derivatives only for the 'current' time point!
208 :
209 0 : if(bDoDeriv && this->m_vvvvDeriv[s].size() > 0)
210 : vvvDeriv = &this->m_vvvvDeriv[s][0];
211 : else
212 : vvvDeriv = NULL;
213 :
214 0 : getImpl().template eval_and_deriv<refDim>(this->values(s), this->ips(s), this->time(s), si,
215 : elem, vCornerCoords,
216 : this->template local_ips<refDim>(s), this->num_ip(s),
217 : &(u->solution(this->time_point(s))), bDoDeriv, s, vvvDeriv);
218 : }
219 0 : }
220 :
221 0 : virtual void compute(LocalVector* u, GridObject* elem,
222 : const MathVector<dim> vCornerCoords[], bool bDeriv = false){
223 :
224 : UG_ASSERT(elem->base_object_id() == this->dim_local_ips(),
225 : "local ip dimension (" << this->dim_local_ips()
226 : << ") and reference element dimension ("
227 : << elem->base_object_id() << ") mismatch.");
228 :
229 0 : switch(this->dim_local_ips()){
230 0 : case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
231 0 : case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
232 0 : case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
233 0 : default: UG_THROW("StdDependentUserData: Dimension not supported.");
234 : }
235 0 : }
236 :
237 0 : virtual void compute(LocalVectorTimeSeries* u, GridObject* elem,
238 : const MathVector<dim> vCornerCoords[], bool bDeriv = false){
239 :
240 : UG_ASSERT(elem->base_object_id() == this->dim_local_ips(),
241 : "local ip dimension and reference element dimension mismatch.");
242 :
243 0 : switch(this->dim_local_ips()){
244 0 : case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
245 0 : case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
246 0 : case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
247 0 : default: UG_THROW("StdDependentUserData: Dimension not supported.");
248 : }
249 0 : }
250 :
251 : protected:
252 : /// access to implementation
253 : TImpl& getImpl() {return static_cast<TImpl&>(*this);}
254 :
255 : /// const access to implementation
256 : const TImpl& getImpl() const {return static_cast<const TImpl&>(*this);}
257 :
258 : };
259 :
260 : } // namespace ug
261 :
262 : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__STD_USER_DATA__ */
|