ug4
scale_add_linker_impl.h
Go to the documentation of this file.
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__SCALE_ADD_LINKER_IMPL__
34 #define __H__UG__LIB_DISC__SPATIAL_DISC__SCALE_ADD_LINKER_IMPL__
35 
36 #include "scale_add_linker.h"
37 #include "linker_traits.h"
39 
40 namespace ug{
41 
43 // ScaleAddLinker
45 
46 template <typename TData, int dim, typename TDataScale, typename TRet>
48 ScaleAddLinker(const ScaleAddLinker& linker)
49 {
50  if(linker.m_vpUserData.size() != linker.m_vpScaleData.size())
51  UG_THROW("ScaleAddLinker: number of scaling factors and data mismatch.");
52 
53  for(size_t i = 0; i < linker.m_vpUserData.size(); ++i)
54  {
55  this->add(linker.m_vpScaleData[i], linker.m_vpUserData[i]);
56  }
57 }
58 
59 
60 template <typename TData, int dim, typename TDataScale, typename TRet>
63 {
64 // current number of inputs
65  const size_t numInput = base_type::num_input() / 2;
66 
67 // resize scaling
68  m_vpUserData.resize(numInput+1);
69  m_vpDependData.resize(numInput+1);
70  m_vpScaleData.resize(numInput+1);
71  m_vpScaleDependData.resize(numInput+1);
72 
73 // remember userdata
74  UG_ASSERT(data.valid(), "Null Pointer as Input set.");
75  m_vpUserData[numInput] = data;
76  m_vpDependData[numInput] = data.template cast_dynamic<DependentUserData<TData, dim> >();
77 
78 // remember userdata
79  UG_ASSERT(scale.valid(), "Null Pointer as Scale set.");
80  m_vpScaleData[numInput] = scale;
81  m_vpScaleDependData[numInput] = scale.template cast_dynamic<DependentUserData<TDataScale, dim> >();
82 
83 // increase number of inputs by one and set inputs at base class
84  base_type::set_num_input(2*numInput+2);
85  base_type::set_input(2*numInput, data, data);
86  base_type::set_input(2*numInput+1, scale, scale);
87 }
88 
89 template <typename TData, int dim, typename TDataScale, typename TRet>
92 {
93  add(CreateConstUserData<dim>(scale, TDataScale()), data);
94 }
95 
96 template <typename TData, int dim, typename TDataScale, typename TRet>
99 {
100  add(scale, CreateConstUserData<dim>(data, TData()));
101 }
102 
103 template <typename TData, int dim, typename TDataScale, typename TRet>
105 add(number scale, number data)
106 {
107  add(CreateConstUserData<dim>(scale, TDataScale()),
108  CreateConstUserData<dim>(data, TData()));
109 }
110 
111 
112 template <typename TData, int dim, typename TDataScale, typename TRet>
114 evaluate (TRet& value,
115  const MathVector<dim>& globIP,
116  number time, int si) const
117 {
118  // reset value
119  value = 0.0;
120 
121  TData valData;
122  TDataScale valScale;
123 
124 // add contribution of each summand
125  for(size_t c = 0; c < m_vpUserData.size(); ++c)
126  {
127  (*m_vpUserData[c])(valData, globIP, time, si);
128  (*m_vpScaleData[c])(valScale, globIP, time, si);
129 
131  mult_add(value, valData, valScale);
132  }
133 }
134 
135 template <typename TData, int dim, typename TDataScale, typename TRet>
136 template <int refDim>
138 evaluate(TRet vValue[],
139  const MathVector<dim> vGlobIP[],
140  number time, int si,
141  GridObject* elem,
142  const MathVector<dim> vCornerCoords[],
143  const MathVector<refDim> vLocIP[],
144  const size_t nip,
145  LocalVector* u,
146  const MathMatrix<refDim, dim>* vJT) const
147 {
148  // reset value
149  for(size_t ip = 0; ip < nip; ++ip)
150  vValue[ip] = 0.0;
151 
152  std::vector<TData> vValData(nip);
153  std::vector<TDataScale> vValScale(nip);
154 
155 // add contribution of each summand
156  for(size_t c = 0; c < m_vpUserData.size(); ++c)
157  {
158  (*m_vpUserData[c])(&vValData[0], vGlobIP, time, si,
159  elem, vCornerCoords, vLocIP, nip, u, vJT);
160  (*m_vpScaleData[c])(&vValScale[0], vGlobIP, time, si,
161  elem, vCornerCoords, vLocIP, nip, u, vJT);
162 
163  for(size_t ip = 0; ip < nip; ++ip)
165  mult_add(vValue[ip], vValData[ip], vValScale[ip]);
166  }
167 }
168 
169 template <typename TData, int dim, typename TDataScale, typename TRet>
170 template <int refDim>
172 eval_and_deriv(TRet vValue[],
173  const MathVector<dim> vGlobIP[],
174  number time, int si,
175  GridObject* elem,
176  const MathVector<dim> vCornerCoords[],
177  const MathVector<refDim> vLocIP[],
178  const size_t nip,
179  LocalVector* u,
180  bool bDeriv,
181  int s,
182  std::vector<std::vector<TRet> > vvvDeriv[],
183  const MathMatrix<refDim, dim>* vJT) const
184 {
185 // check that size of Scalings and inputs is equal
186  UG_ASSERT(m_vpUserData.size() == m_vpScaleData.size(), "Wrong num Scales.");
187 
188 // compute value
189  for(size_t ip = 0; ip < nip; ++ip)
190  {
191  // reset value
192  vValue[ip] = 0.0;
193 
194  // add contribution of each summand
195  for(size_t c = 0; c < m_vpUserData.size(); ++c)
196  {
198  mult_add(vValue[ip],
199  input_value(c, s, ip),
200  scale_value(c, s, ip));
201  }
202  }
203 
204 // check if derivative is required
205  if(!bDeriv || this->zero_derivative()) return;
206 
207 // check sizes
208  UG_ASSERT(m_vpDependData.size() == m_vpScaleDependData.size(),
209  "Wrong num Scales.");
210 
211 // clear all derivative values
212  this->set_zero(vvvDeriv, nip);
213 
214 // loop all inputs
215  for(size_t c = 0; c < m_vpUserData.size(); ++c)
216  {
217  // check if input has derivative
218  if(!m_vpUserData[c]->zero_derivative())
219  {
220  for(size_t ip = 0; ip < nip; ++ip)
221  {
222  // loop functions
223  for(size_t fct = 0; fct < input_num_fct(c); ++fct)
224  {
225  // get common fct id for this function
226  const size_t commonFct = input_common_fct(c, fct);
227 
228  // loop dofs
229  for(size_t sh = 0; sh < this->num_sh(fct); ++sh)
230  {
232  mult_add(vvvDeriv[ip][commonFct][sh],
233  input_deriv(c, s, ip, fct, sh),
234  scale_value(c, s, ip));
235  }
236  }
237  }
238  }
239 
240  // check if scaling has derivative
241  if(!m_vpScaleData[c]->zero_derivative())
242  {
243  for(size_t ip = 0; ip < nip; ++ip)
244  {
245  // loop functions
246  for(size_t fct = 0; fct < scale_num_fct(c); ++fct)
247  {
248  // get common fct id for this function
249  const size_t commonFct = scale_common_fct(c, fct);
250 
251  // loop dofs
252  for(size_t sh = 0; sh < this->num_sh(fct); ++sh)
253  {
255  mult_add(vvvDeriv[ip][commonFct][sh],
256  input_value(c, s, ip),
257  scale_deriv(c, s, ip, fct, sh));
258  }
259  }
260  }
261  }
262  }
263 }
264 
265 
266 } // end namespace ug
267 
268 #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__SCALE_ADD_LINKER_IMPL__ */
parameterString s
Definition: smart_pointer.h:108
Type based UserData.
Definition: user_data.h:501
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
Definition: local_algebra.h:198
A class for fixed size, dense matrices.
Definition: math_matrix.h:52
Definition: scale_add_linker.h:61
std::vector< SmartPtr< CplUserData< TData, dim > > > m_vpUserData
data input
Definition: scale_add_linker.h:167
void eval_and_deriv(TRet 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, bool bDeriv, int s, std::vector< std::vector< TRet > > vvvDeriv[], const MathMatrix< refDim, dim > *vJT=NULL) const
Definition: scale_add_linker_impl.h:172
std::vector< SmartPtr< CplUserData< TDataScale, dim > > > m_vpScaleData
data input
Definition: scale_add_linker.h:161
void add(SmartPtr< CplUserData< TDataScale, dim > > scale, SmartPtr< CplUserData< TData, dim > > data)
Definition: scale_add_linker_impl.h:62
void evaluate(TRet &value, const MathVector< dim > &globIP, number time, int si) const
Definition: scale_add_linker_impl.h:114
ScaleAddLinker()
constructor
Definition: scale_add_linker.h:68
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
double number
Definition: types.h:124
the ug namespace
Linker Traits.
Definition: linker_traits.h:47
static void mult_add(TData &out, const TData &in1, const TDataIn &s)
computes out += s * in1 (with appropriate '*')