Line data Source code
1 : /*
2 : * Copyright (c) 2011-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__DATA_LINKER_IMPL__
34 : #define __H__UG__LIB_DISC__SPATIAL_DISC__DATA_LINKER_IMPL__
35 :
36 : #include "linker.h"
37 :
38 : namespace ug{
39 :
40 : ////////////////////////////////////////////////////////////////////////////////
41 : // Data Linker
42 : ////////////////////////////////////////////////////////////////////////////////
43 :
44 : template <typename TImpl, typename TData, int dim>
45 0 : void StdDataLinker<TImpl,TData,dim>::
46 : operator() (TData& value,
47 : const MathVector<dim>& globIP,
48 : number time, int si) const
49 : {
50 0 : getImpl().evaluate(value,globIP,time,si);
51 0 : }
52 :
53 : template <typename TImpl, typename TData, int dim>
54 0 : void StdDataLinker<TImpl,TData,dim>::
55 : operator()(TData vValue[],
56 : const MathVector<dim> vGlobIP[],
57 : number time, int si, const size_t nip) const
58 : {
59 0 : for(size_t ip = 0; ip < nip; ++ip)
60 0 : getImpl().evaluate(vValue[ip],vGlobIP[ip],time,si);
61 0 : }
62 :
63 : template <typename TImpl, typename TData, int dim>
64 : template <int refDim>
65 : void StdDataLinker<TImpl,TData,dim>::
66 : evaluate(TData vValue[],
67 : const MathVector<dim> vGlobIP[],
68 : number time, int si,
69 : GridObject* elem,
70 : const MathVector<dim> vCornerCoords[],
71 : const MathVector<refDim> vLocIP[],
72 : const size_t nip,
73 : LocalVector* u,
74 : const MathMatrix<refDim, dim>* vJT) const
75 : {
76 0 : getImpl().template evaluate<refDim>(vValue,vGlobIP,time,si,elem,
77 : vCornerCoords,vLocIP,nip,u,vJT);
78 : }
79 :
80 : template <typename TImpl, typename TData, int dim>
81 : template <int refDim>
82 0 : void StdDataLinker<TImpl,TData,dim>::eval_deriv(LocalVector* u, GridObject* elem,
83 : const MathVector<dim> vCornerCoords[], bool bDeriv){
84 :
85 : const int si = this->subset();
86 :
87 : std::vector<std::vector<TData> >* vvvDeriv = NULL;
88 :
89 0 : for(size_t s = 0; s < this->num_series(); ++s){
90 :
91 0 : if(bDeriv && this->m_vvvvDeriv[s].size() > 0)
92 : vvvDeriv = &this->m_vvvvDeriv[s][0];
93 : else
94 : vvvDeriv = NULL;
95 :
96 0 : getImpl().template eval_and_deriv<refDim>(this->values(s), this->ips(s), this->time(s), si,
97 : elem, vCornerCoords,
98 : this->template local_ips<refDim>(s), this->num_ip(s),
99 : u, bDeriv, s, vvvDeriv);
100 : }
101 0 : }
102 :
103 : template <typename TImpl, typename TData, int dim>
104 : template <int refDim>
105 0 : void StdDataLinker<TImpl,TData,dim>::eval_deriv(LocalVectorTimeSeries* u, GridObject* elem,
106 : const MathVector<dim> vCornerCoords[], bool bDeriv){
107 :
108 : const int si = this->subset();
109 :
110 : std::vector<std::vector<TData> >* vvvDeriv = NULL;
111 :
112 0 : for(size_t s = 0; s < this->num_series(); ++s){
113 :
114 0 : bool bDoDeriv = bDeriv && this->at_current_time (s); // derivatives only for the 'current' time point!
115 :
116 0 : if(bDoDeriv && this->m_vvvvDeriv[s].size() > 0)
117 : vvvDeriv = &this->m_vvvvDeriv[s][0];
118 : else
119 : vvvDeriv = NULL;
120 :
121 0 : getImpl().template eval_and_deriv<refDim>(this->values(s), this->ips(s), this->time(s), si,
122 : elem, vCornerCoords,
123 : this->template local_ips<refDim>(s), this->num_ip(s),
124 : &(u->solution(this->time_point(s))), bDoDeriv, s, vvvDeriv);
125 : }
126 0 : }
127 :
128 : template <typename TImpl, typename TData, int dim>
129 0 : void StdDataLinker<TImpl,TData,dim>::
130 : compute(LocalVector* u, GridObject* elem,
131 : const MathVector<dim> vCornerCoords[], bool bDeriv){
132 :
133 : UG_ASSERT(elem->base_object_id() == this->dim_local_ips(),
134 : "local ip dimension and reference element dimension mismatch.");
135 :
136 0 : switch(this->dim_local_ips()){
137 0 : case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
138 0 : case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
139 0 : case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
140 0 : default: UG_THROW("StdDataLinker: Dimension not supported.");
141 : }
142 0 : }
143 :
144 : template <typename TImpl, typename TData, int dim>
145 0 : void StdDataLinker<TImpl,TData,dim>::
146 : compute(LocalVectorTimeSeries* u, GridObject* elem,
147 : const MathVector<dim> vCornerCoords[], bool bDeriv){
148 :
149 : UG_ASSERT(elem->base_object_id() == this->dim_local_ips(),
150 : "local ip dimension and reference element dimension mismatch.");
151 :
152 0 : switch(this->dim_local_ips()){
153 0 : case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
154 0 : case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
155 0 : case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
156 0 : default: UG_THROW("StdDataLinker: Dimension not supported.");
157 : }
158 0 : }
159 :
160 : template <typename TImpl, typename TData, int dim>
161 0 : bool StdDataLinker<TImpl,TData,dim>::requires_grid_fct() const
162 : {
163 0 : for(size_t i = 0; i < this->m_vspICplUserData.size(); ++i)
164 0 : if(this->m_vspUserDataInfo[i]->requires_grid_fct())
165 : return true;
166 : return false;
167 : }
168 :
169 : template <typename TImpl, typename TData, int dim>
170 0 : bool StdDataLinker<TImpl,TData,dim>::continuous() const
171 : {
172 : bool bRet = true;
173 0 : for(size_t i = 0; i < this->m_vspICplUserData.size(); ++i)
174 0 : bRet &= this->m_vspUserDataInfo[i]->continuous();
175 0 : return bRet;
176 : }
177 :
178 : template <typename TImpl, typename TData, int dim>
179 0 : bool StdDataLinker<TImpl,TData,dim>::zero_derivative() const
180 : {
181 : bool bRet = true;
182 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
183 0 : bRet &= m_vspICplUserData[i]->zero_derivative();
184 0 : return bRet;
185 : }
186 :
187 : template <typename TImpl, typename TData, int dim>
188 0 : void StdDataLinker<TImpl,TData,dim>::check_setup() const
189 : {
190 : // check, that all inputs are set
191 0 : for(size_t i = 0; i < num_input(); ++i)
192 0 : if(!m_vspICplUserData[i].valid())
193 0 : UG_THROW("StdDataLinker::check_setup: Input number "<<i<<" missing.");
194 0 : }
195 :
196 : template <typename TImpl, typename TData, int dim>
197 0 : void StdDataLinker<TImpl,TData,dim>::
198 : set_function_pattern(ConstSmartPtr<FunctionPattern> fctPatt)
199 : {
200 : // set function pattern in dependent data and collect all function groups
201 0 : std::vector<const FunctionGroup*> vFctGrp(num_input(), NULL);
202 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i){
203 0 : if(m_vspICplUserData[i].valid()){
204 0 : m_vspUserDataInfo[i]->set_function_pattern(fctPatt);
205 0 : vFctGrp[i] = &(m_vspUserDataInfo[i]->function_group());
206 : }
207 : }
208 :
209 : // All data this linker depends on has now an updated function group. We can
210 : // now setup the map of this data. Therefore, we create a union of all function
211 : // this linker depends on and compute maps between this common function group
212 : // and the the function needed by the data.
213 :
214 : // create union of all function groups
215 : try{
216 0 : this->m_fctGrp.set_function_pattern(fctPatt);
217 0 : CreateUnionOfFunctionGroups(this->m_fctGrp, vFctGrp, true);
218 0 : }UG_CATCH_THROW("'StdDataLinker::set_function_pattern': Cannot create"
219 : " common function group.");
220 :
221 : try{
222 0 : CreateFunctionIndexMapping(this->m_map, this->m_fctGrp, this->m_fctGrp.function_pattern());
223 0 : }UG_CATCH_THROW("'StdDataLinker::set_function_pattern':"
224 : "Cannot create Function Index Mapping for Common Functions.");
225 :
226 : // create FunctionIndexMapping for each Disc
227 0 : m_vMap.resize(vFctGrp.size());
228 0 : for(size_t i = 0; i < vFctGrp.size(); ++i)
229 : {
230 0 : if(vFctGrp[i] != NULL)
231 : {
232 : try{
233 0 : CreateFunctionIndexMapping(m_vMap[i], *vFctGrp[i], this->m_fctGrp);
234 0 : }UG_CATCH_THROW("'StdDataLinker::set_function_pattern':"
235 : "Cannot create Function Index Mapping for input "<<i<<".");
236 : }
237 : }
238 0 : }
239 :
240 : template <typename TImpl, typename TData, int dim>
241 0 : void StdDataLinker<TImpl,TData,dim>::
242 : local_ip_series_added(const size_t seriesID)
243 : {
244 : const size_t s = seriesID;
245 :
246 : // we need a series id for all inputs
247 0 : m_vvSeriesID.resize(m_vspICplUserData.size());
248 :
249 : // loop inputs
250 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
251 : {
252 : // check unset data
253 : UG_ASSERT(m_vspICplUserData[i].valid(), "No Input set, but requested.");
254 :
255 : // resize series ids
256 0 : m_vvSeriesID[i].resize(s+1);
257 :
258 : // request local ips for series at input data
259 0 : switch(this->dim_local_ips())
260 : {
261 0 : case 1:
262 0 : m_vvSeriesID[i][s] =
263 : m_vspICplUserData[i]->template register_local_ip_series<1>
264 0 : (this->template local_ips<1>(s), this->num_ip(s),
265 : this->m_vTimePoint[s], this->m_vMayChange[s]);
266 0 : break;
267 0 : case 2:
268 0 : m_vvSeriesID[i][s] =
269 : m_vspICplUserData[i]->template register_local_ip_series<2>
270 0 : (this->template local_ips<2>(s), this->num_ip(s),
271 : this->m_vTimePoint[s], this->m_vMayChange[s]);
272 0 : break;
273 0 : case 3:
274 0 : m_vvSeriesID[i][s] =
275 : m_vspICplUserData[i]->template register_local_ip_series<3>
276 0 : (this->template local_ips<3>(s), this->num_ip(s),
277 : this->m_vTimePoint[s], this->m_vMayChange[s]);
278 0 : break;
279 0 : default: UG_THROW("Dimension not supported."); break;
280 : }
281 : }
282 :
283 : // resize data fields
284 : DependentUserData<TData, dim>::local_ip_series_added(seriesID);
285 0 : }
286 :
287 :
288 : template <typename TImpl, typename TData, int dim>
289 0 : void StdDataLinker<TImpl,TData,dim>::
290 : local_ips_changed(const size_t seriesID, const size_t newNumIP)
291 : {
292 : const size_t s = seriesID;
293 :
294 : // loop inputs
295 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
296 : {
297 : // skip unset data
298 : UG_ASSERT(m_vspICplUserData[i].valid(), "No Input set, but requested.");
299 :
300 0 : switch(this->dim_local_ips())
301 : {
302 0 : case 1: m_vspICplUserData[i]->template set_local_ips<1>
303 0 : (m_vvSeriesID[i][s], this->template local_ips<1>(s), this->num_ip(s));
304 0 : break;
305 0 : case 2: m_vspICplUserData[i]->template set_local_ips<2>
306 0 : (m_vvSeriesID[i][s], this->template local_ips<2>(s), this->num_ip(s));
307 0 : break;
308 0 : case 3: m_vspICplUserData[i]->template set_local_ips<3>
309 0 : (m_vvSeriesID[i][s], this->template local_ips<3>(s), this->num_ip(s));
310 0 : break;
311 0 : default: UG_THROW("Dimension not supported."); break;
312 : }
313 : }
314 :
315 : // resize data fields
316 0 : DependentUserData<TData, dim>::local_ips_changed(seriesID, newNumIP);
317 0 : }
318 :
319 : template <typename TImpl, typename TData, int dim>
320 0 : void StdDataLinker<TImpl,TData,dim>::
321 : local_ip_series_to_be_cleared()
322 : {
323 : // loop inputs
324 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
325 : {
326 : // skip unset data
327 : UG_ASSERT(m_vspICplUserData[i].valid(), "No Input set, but requested.");
328 :
329 0 : m_vspICplUserData[i]->clear ();
330 : }
331 :
332 : // postprocess the base class
333 0 : DependentUserData<TData, dim>::local_ip_series_to_be_cleared();
334 0 : }
335 :
336 : template <typename TImpl, typename TData, int dim>
337 0 : void StdDataLinker<TImpl,TData,dim>::
338 : global_ips_changed(const size_t seriesID, const MathVector<dim>* vPos, const size_t numIP)
339 : {
340 : // loop inputs
341 0 : for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
342 : {
343 : // skip unset data
344 : UG_ASSERT(m_vspICplUserData[i].valid(), "No Input set, but requested.");
345 :
346 : // adjust global ids of imported data
347 0 : m_vspICplUserData[i]->set_global_ips(m_vvSeriesID[i][seriesID], vPos, numIP);
348 : }
349 0 : }
350 :
351 : } // end namespace ug
352 :
353 : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DATA_LINKER_IMPL__ */
|