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__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"
38 : #include "lib_disc/spatial_disc/user_data/const_user_data.h"
39 :
40 : namespace ug{
41 :
42 : ////////////////////////////////////////////////////////////////////////////////
43 : // ScaleAddLinker
44 : ////////////////////////////////////////////////////////////////////////////////
45 :
46 : template <typename TData, int dim, typename TDataScale, typename TRet>
47 0 : ScaleAddLinker<TData,dim,TDataScale,TRet>::
48 0 : ScaleAddLinker(const ScaleAddLinker& linker)
49 : {
50 0 : if(linker.m_vpUserData.size() != linker.m_vpScaleData.size())
51 0 : UG_THROW("ScaleAddLinker: number of scaling factors and data mismatch.");
52 :
53 0 : for(size_t i = 0; i < linker.m_vpUserData.size(); ++i)
54 : {
55 0 : this->add(linker.m_vpScaleData[i], linker.m_vpUserData[i]);
56 : }
57 0 : }
58 :
59 :
60 : template <typename TData, int dim, typename TDataScale, typename TRet>
61 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
62 : add(SmartPtr<CplUserData<TDataScale, dim> > scale, SmartPtr<CplUserData<TData, dim> > data)
63 : {
64 : // current number of inputs
65 0 : const size_t numInput = base_type::num_input() / 2;
66 :
67 : // resize scaling
68 0 : m_vpUserData.resize(numInput+1);
69 0 : m_vpDependData.resize(numInput+1);
70 0 : m_vpScaleData.resize(numInput+1);
71 0 : m_vpScaleDependData.resize(numInput+1);
72 :
73 : // remember userdata
74 : UG_ASSERT(data.valid(), "Null Pointer as Input set.");
75 0 : m_vpUserData[numInput] = data;
76 0 : 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 0 : m_vpScaleData[numInput] = scale;
81 0 : 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 0 : base_type::set_num_input(2*numInput+2);
85 0 : base_type::set_input(2*numInput, data, data);
86 0 : base_type::set_input(2*numInput+1, scale, scale);
87 0 : }
88 :
89 : template <typename TData, int dim, typename TDataScale, typename TRet>
90 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
91 : add(number scale, SmartPtr<CplUserData<TData, dim> > data)
92 : {
93 0 : add(CreateConstUserData<dim>(scale, TDataScale()), data);
94 0 : }
95 :
96 : template <typename TData, int dim, typename TDataScale, typename TRet>
97 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
98 : add(SmartPtr<CplUserData<TDataScale, dim> > scale, number data)
99 : {
100 0 : add(scale, CreateConstUserData<dim>(data, TData()));
101 0 : }
102 :
103 : template <typename TData, int dim, typename TDataScale, typename TRet>
104 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
105 : add(number scale, number data)
106 : {
107 0 : add(CreateConstUserData<dim>(scale, TDataScale()),
108 0 : CreateConstUserData<dim>(data, TData()));
109 0 : }
110 :
111 :
112 : template <typename TData, int dim, typename TDataScale, typename TRet>
113 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
114 : evaluate (TRet& value,
115 : const MathVector<dim>& globIP,
116 : number time, int si) const
117 : {
118 : // reset value
119 0 : value = 0.0;
120 :
121 0 : TData valData;
122 : TDataScale valScale;
123 :
124 : // add contribution of each summand
125 0 : for(size_t c = 0; c < m_vpUserData.size(); ++c)
126 : {
127 0 : (*m_vpUserData[c])(valData, globIP, time, si);
128 0 : (*m_vpScaleData[c])(valScale, globIP, time, si);
129 :
130 : linker_traits<TData, TDataScale,TRet>::
131 0 : mult_add(value, valData, valScale);
132 : }
133 0 : }
134 :
135 : template <typename TData, int dim, typename TDataScale, typename TRet>
136 : template <int refDim>
137 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
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 0 : for(size_t ip = 0; ip < nip; ++ip)
150 0 : vValue[ip] = 0.0;
151 :
152 0 : std::vector<TData> vValData(nip);
153 0 : std::vector<TDataScale> vValScale(nip);
154 :
155 : // add contribution of each summand
156 0 : for(size_t c = 0; c < m_vpUserData.size(); ++c)
157 : {
158 0 : (*m_vpUserData[c])(&vValData[0], vGlobIP, time, si,
159 : elem, vCornerCoords, vLocIP, nip, u, vJT);
160 0 : (*m_vpScaleData[c])(&vValScale[0], vGlobIP, time, si,
161 : elem, vCornerCoords, vLocIP, nip, u, vJT);
162 :
163 0 : for(size_t ip = 0; ip < nip; ++ip)
164 : linker_traits<TData, TDataScale,TRet>::
165 0 : mult_add(vValue[ip], vValData[ip], vValScale[ip]);
166 : }
167 0 : }
168 :
169 : template <typename TData, int dim, typename TDataScale, typename TRet>
170 : template <int refDim>
171 0 : void ScaleAddLinker<TData,dim,TDataScale,TRet>::
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 0 : for(size_t ip = 0; ip < nip; ++ip)
190 : {
191 : // reset value
192 0 : vValue[ip] = 0.0;
193 :
194 : // add contribution of each summand
195 0 : for(size_t c = 0; c < m_vpUserData.size(); ++c)
196 : {
197 : linker_traits<TData, TDataScale,TRet>::
198 0 : mult_add(vValue[ip],
199 : input_value(c, s, ip),
200 0 : scale_value(c, s, ip));
201 : }
202 : }
203 :
204 : // check if derivative is required
205 0 : 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 0 : this->set_zero(vvvDeriv, nip);
213 :
214 : // loop all inputs
215 0 : for(size_t c = 0; c < m_vpUserData.size(); ++c)
216 : {
217 : // check if input has derivative
218 0 : if(!m_vpUserData[c]->zero_derivative())
219 : {
220 0 : for(size_t ip = 0; ip < nip; ++ip)
221 : {
222 : // loop functions
223 0 : 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 0 : for(size_t sh = 0; sh < this->num_sh(fct); ++sh)
230 : {
231 : linker_traits<TData, TDataScale,TRet>::
232 0 : mult_add(vvvDeriv[ip][commonFct][sh],
233 : input_deriv(c, s, ip, fct, sh),
234 0 : scale_value(c, s, ip));
235 : }
236 : }
237 : }
238 : }
239 :
240 : // check if scaling has derivative
241 0 : if(!m_vpScaleData[c]->zero_derivative())
242 : {
243 0 : for(size_t ip = 0; ip < nip; ++ip)
244 : {
245 : // loop functions
246 0 : 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 0 : for(size_t sh = 0; sh < this->num_sh(fct); ++sh)
253 : {
254 : linker_traits<TData, TDataScale,TRet>::
255 0 : mult_add(vvvDeriv[ip][commonFct][sh],
256 : input_value(c, s, ip),
257 0 : 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__ */
|