ug4
linker_impl.h
Go to the documentation of this file.
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 
41 // Data Linker
43 
44 template <typename TImpl, typename TData, int dim>
46 operator() (TData& value,
47  const MathVector<dim>& globIP,
48  number time, int si) const
49 {
50  getImpl().evaluate(value,globIP,time,si);
51 }
52 
53 template <typename TImpl, typename TData, int dim>
55 operator()(TData vValue[],
56  const MathVector<dim> vGlobIP[],
57  number time, int si, const size_t nip) const
58 {
59  for(size_t ip = 0; ip < nip; ++ip)
60  getImpl().evaluate(vValue[ip],vGlobIP[ip],time,si);
61 }
62 
63 template <typename TImpl, typename TData, int dim>
64 template <int refDim>
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  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>
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  for(size_t s = 0; s < this->num_series(); ++s){
90 
91  if(bDeriv && this->m_vvvvDeriv[s].size() > 0)
92  vvvDeriv = &this->m_vvvvDeriv[s][0];
93  else
94  vvvDeriv = NULL;
95 
96  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 }
102 
103 template <typename TImpl, typename TData, int dim>
104 template <int refDim>
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  for(size_t s = 0; s < this->num_series(); ++s){
113 
114  bool bDoDeriv = bDeriv && this->at_current_time (s); // derivatives only for the 'current' time point!
115 
116  if(bDoDeriv && this->m_vvvvDeriv[s].size() > 0)
117  vvvDeriv = &this->m_vvvvDeriv[s][0];
118  else
119  vvvDeriv = NULL;
120 
121  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 }
127 
128 template <typename TImpl, typename TData, int 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  switch(this->dim_local_ips()){
137  case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
138  case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
139  case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
140  default: UG_THROW("StdDataLinker: Dimension not supported.");
141  }
142 }
143 
144 template <typename TImpl, typename TData, int dim>
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  switch(this->dim_local_ips()){
153  case 1: eval_deriv<1>(u,elem,vCornerCoords,bDeriv); break;
154  case 2: eval_deriv<2>(u,elem,vCornerCoords,bDeriv); break;
155  case 3: eval_deriv<3>(u,elem,vCornerCoords,bDeriv); break;
156  default: UG_THROW("StdDataLinker: Dimension not supported.");
157  }
158 }
159 
160 template <typename TImpl, typename TData, int dim>
162 {
163  for(size_t i = 0; i < this->m_vspICplUserData.size(); ++i)
164  if(this->m_vspUserDataInfo[i]->requires_grid_fct())
165  return true;
166  return false;
167 }
168 
169 template <typename TImpl, typename TData, int dim>
171 {
172  bool bRet = true;
173  for(size_t i = 0; i < this->m_vspICplUserData.size(); ++i)
174  bRet &= this->m_vspUserDataInfo[i]->continuous();
175  return bRet;
176 }
177 
178 template <typename TImpl, typename TData, int dim>
180 {
181  bool bRet = true;
182  for(size_t i = 0; i < m_vspICplUserData.size(); ++i)
183  bRet &= m_vspICplUserData[i]->zero_derivative();
184  return bRet;
185 }
186 
187 template <typename TImpl, typename TData, int dim>
189 {
190 // check, that all inputs are set
191  for(size_t i = 0; i < num_input(); ++i)
192  if(!m_vspICplUserData[i].valid())
193  UG_THROW("StdDataLinker::check_setup: Input number "<<i<<" missing.");
194 }
195 
196 template <typename TImpl, typename TData, int dim>
199 {
200 // set function pattern in dependent data and collect all function groups
201  std::vector<const FunctionGroup*> vFctGrp(num_input(), NULL);
202  for(size_t i = 0; i < m_vspICplUserData.size(); ++i){
203  if(m_vspICplUserData[i].valid()){
204  m_vspUserDataInfo[i]->set_function_pattern(fctPatt);
205  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  this->m_fctGrp.set_function_pattern(fctPatt);
217  CreateUnionOfFunctionGroups(this->m_fctGrp, vFctGrp, true);
218  }UG_CATCH_THROW("'StdDataLinker::set_function_pattern': Cannot create"
219  " common function group.");
220 
221  try{
222  CreateFunctionIndexMapping(this->m_map, this->m_fctGrp, this->m_fctGrp.function_pattern());
223  }UG_CATCH_THROW("'StdDataLinker::set_function_pattern':"
224  "Cannot create Function Index Mapping for Common Functions.");
225 
226 // create FunctionIndexMapping for each Disc
227  m_vMap.resize(vFctGrp.size());
228  for(size_t i = 0; i < vFctGrp.size(); ++i)
229  {
230  if(vFctGrp[i] != NULL)
231  {
232  try{
233  CreateFunctionIndexMapping(m_vMap[i], *vFctGrp[i], this->m_fctGrp);
234  }UG_CATCH_THROW("'StdDataLinker::set_function_pattern':"
235  "Cannot create Function Index Mapping for input "<<i<<".");
236  }
237  }
238 }
239 
240 template <typename TImpl, typename TData, int 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  m_vvSeriesID.resize(m_vspICplUserData.size());
248 
249 // loop inputs
250  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  m_vvSeriesID[i].resize(s+1);
257 
258  // request local ips for series at input data
259  switch(this->dim_local_ips())
260  {
261  case 1:
262  m_vvSeriesID[i][s] =
263  m_vspICplUserData[i]->template register_local_ip_series<1>
264  (this->template local_ips<1>(s), this->num_ip(s),
265  this->m_vTimePoint[s], this->m_vMayChange[s]);
266  break;
267  case 2:
268  m_vvSeriesID[i][s] =
269  m_vspICplUserData[i]->template register_local_ip_series<2>
270  (this->template local_ips<2>(s), this->num_ip(s),
271  this->m_vTimePoint[s], this->m_vMayChange[s]);
272  break;
273  case 3:
274  m_vvSeriesID[i][s] =
275  m_vspICplUserData[i]->template register_local_ip_series<3>
276  (this->template local_ips<3>(s), this->num_ip(s),
277  this->m_vTimePoint[s], this->m_vMayChange[s]);
278  break;
279  default: UG_THROW("Dimension not supported."); break;
280  }
281  }
282 
283 // resize data fields
285 }
286 
287 
288 template <typename TImpl, typename TData, int 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  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  switch(this->dim_local_ips())
301  {
302  case 1: m_vspICplUserData[i]->template set_local_ips<1>
303  (m_vvSeriesID[i][s], this->template local_ips<1>(s), this->num_ip(s));
304  break;
305  case 2: m_vspICplUserData[i]->template set_local_ips<2>
306  (m_vvSeriesID[i][s], this->template local_ips<2>(s), this->num_ip(s));
307  break;
308  case 3: m_vspICplUserData[i]->template set_local_ips<3>
309  (m_vvSeriesID[i][s], this->template local_ips<3>(s), this->num_ip(s));
310  break;
311  default: UG_THROW("Dimension not supported."); break;
312  }
313  }
314 
315 // resize data fields
317 }
318 
319 template <typename TImpl, typename TData, int dim>
321 global_ips_changed(const size_t seriesID, const MathVector<dim>* vPos, const size_t numIP)
322 {
323 // loop inputs
324  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  // adjust global ids of imported data
330  m_vspICplUserData[i]->set_global_ips(m_vvSeriesID[i][seriesID], vPos, numIP);
331  }
332 }
333 
334 } // end namespace ug
335 
336 #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DATA_LINKER_IMPL__ */
parameterString s
Definition: smart_pointer.h:296
virtual void local_ip_series_added(const size_t seriesID)
resizes the derivative field when local ip change is signaled
Definition: user_data_impl.h:525
virtual void local_ips_changed(const size_t seriesID, const size_t newNumIP)
implement callback, called when local IPs changed
Definition: user_data_impl.h:545
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
virtual int base_object_id() const =0
Definition: local_algebra.h:198
time series of local vectors
Definition: solution_time_series.h:167
const LocalVector & solution(size_t i) const
returns the local vector for the i'th time point
Definition: solution_time_series.h:182
A class for fixed size, dense matrices.
Definition: math_matrix.h:52
void eval_deriv(LocalVector *u, GridObject *elem, const MathVector< dim > vCornerCoords[], bool bDeriv=false)
Definition: linker_impl.h:82
virtual void local_ips_changed(const size_t seriesID, const size_t newNumIP)
forwards the local positions to the data inputs
Definition: linker_impl.h:290
virtual void set_function_pattern(ConstSmartPtr< FunctionPattern > fctPatt)
updates the function group
Definition: linker_impl.h:198
virtual void operator()(TData &value, const MathVector< dim > &globIP, number time, int si) const
returns value for a global position
Definition: linker_impl.h:46
virtual bool zero_derivative() const
returns if derivative is zero
Definition: linker_impl.h:179
virtual void global_ips_changed(const size_t seriesID, const MathVector< dim > *vPos, const size_t numIP)
forwards the global positions to the data inputs
Definition: linker_impl.h:321
virtual void local_ip_series_added(const size_t seriesID)
requests series id's from input data
Definition: linker_impl.h:242
virtual void check_setup() const
returns if data is ok
Definition: linker_impl.h:188
virtual void compute(LocalVector *u, GridObject *elem, const MathVector< dim > vCornerCoords[], bool bDeriv=false)
compute values (and derivatives iff compDeriv == true)
Definition: linker_impl.h:130
void evaluate(TData vValue[], const MathVector< dim > vGlobIP[], number time, int si, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< refDim > vLocIP[], const size_t nip, LocalVector *u, const MathMatrix< refDim, dim > *vJT=NULL) const
Definition: linker_impl.h:66
virtual bool requires_grid_fct() const
returns that a grid function is needed for evaluation
Definition: linker_impl.h:161
virtual bool continuous() const
returns if provided data is continuous over geometric object boundaries
Definition: linker_impl.h:170
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_CATCH_THROW(msg)
Definition: error.h:64
#define UG_THROW(msg)
Definition: error.h:57
double number
Definition: types.h:124
the ug namespace
void CreateUnionOfFunctionGroups(FunctionGroup &fctGrp, const vector< const FunctionGroup * > &vFctGrp, bool sortFct)
Definition: groups_util.cpp:93
void CreateFunctionIndexMapping(FunctionIndexMapping &map, const FunctionGroup &grpFromSmall, const FunctionGroup &grpToLarge)
Definition: groups_util.cpp:44