37 #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__INVERSE_LINKER_IMPL__
38 #define __H__UG__LIB_DISC__SPATIAL_DISC__INVERSE_LINKER_IMPL__
55 UG_THROW(
"InverseLinker: number of inputs mismatch.");
70 const size_t numInput = base_type::num_input() / 2;
73 m_vpDivisorData.resize(numInput+1);
74 m_vpDependData.resize(numInput+1);
75 m_vpDividendData.resize(numInput+1);
76 m_vpDividendDependData.resize(numInput+1);
79 UG_ASSERT(divisor.valid(),
"Null Pointer as Input set.");
80 m_vpDivisorData[numInput] = divisor;
81 m_vpDependData[numInput] = divisor.template cast_dynamic<DependentUserData<number, dim> >();
84 UG_ASSERT(dividend.valid(),
"Null Pointer as Scale set.");
85 m_vpDividendData[numInput] = dividend;
86 m_vpDividendDependData[numInput] = dividend.template cast_dynamic<DependentUserData<number, dim> >();
89 base_type::set_num_input(2*numInput+2);
90 base_type::set_input(2*numInput, divisor, divisor);
91 base_type::set_input(2*numInput+1, dividend, dividend);
98 divide(CreateConstUserData<dim>(dividend,
number()), divisor);
105 divide(dividend, CreateConstUserData<dim>(divisor,
number()));
112 divide(CreateConstUserData<dim>(dividend,
number()),
113 CreateConstUserData<dim>(divisor,
number()));
121 number time,
int si)
const
129 for(
size_t c = 0; c < m_vpDivisorData.size(); ++c)
131 (*m_vpDivisorData[c])(valDivisor, globIP, time, si);
132 (*m_vpDividendData[c])(valDividend, globIP, time, si);
133 UG_ASSERT(valDivisor!=0,
"DIVISOR IS 0");
136 value *= valDividend/valDivisor;
141 template <
int refDim>
154 for(
size_t ip = 0; ip < nip; ++ip)
157 std::vector<number> vValData(nip);
158 std::vector<number> vValScale(nip);
161 for(
size_t c = 0; c < m_vpDivisorData.size(); ++c)
163 (*m_vpDivisorData[c])(&vValData[0], vGlobIP, time, si,
164 elem, vCornerCoords, vLocIP, nip, u, vJT);
165 (*m_vpDividendData[c])(&vValScale[0], vGlobIP, time, si,
166 elem, vCornerCoords, vLocIP, nip, u, vJT);
168 for(
size_t ip = 0; ip < nip; ++ip)
169 vValue[ip] *= vValScale[ip]/vValData[ip];
174 template <
int refDim>
186 std::vector<std::vector<number> > vvvDeriv[],
190 UG_ASSERT(m_vpDivisorData.size() == m_vpDividendData.size(),
"Wrong num Scales.");
193 for(
size_t ip = 0; ip < nip; ++ip)
199 for(
size_t c2 = 0; c2 < m_vpDivisorData.size(); ++c2)
202 vValue[ip] *= dividend_value(c2,
s,ip)/divisor_value(c2,
s,ip);
208 if(!bDeriv || this->zero_derivative())
return;
211 UG_ASSERT(m_vpDependData.size() == m_vpDividendDependData.size(),
212 "Wrong num Scales.");
215 this->set_zero(vvvDeriv, nip);
230 for(
size_t c = 0; c < m_vpDivisorData.size(); ++c)
232 for(
size_t ip = 0; ip < nip; ++ip)
235 for(
size_t c2 = 0; c2 < m_vpDivisorData.size(); ++c2)
237 if(c == c2)
continue;
238 vValue *= dividend_value(c2,
s,ip)/divisor_value(c2,
s,ip);
242 if(!m_vpDivisorData[c]->zero_derivative())
246 for(
size_t fct = 0; fct < divisor_num_fct(c); ++fct)
249 const size_t commonFct = divisor_common_fct(c, fct);
252 for(
size_t sh = 0; sh < this->num_sh(fct); ++sh)
254 if(dividend_value(c,
s,ip)!=0)
257 vvvDeriv[ip][commonFct][sh] +=
260 (dividend_value(c,
s,ip))/divisor_value(c,
s,ip)/divisor_value(c,
s,ip)
261 *divisor_deriv(c,
s, ip, fct, sh);
265 vvvDeriv[ip][commonFct][sh] += 0;
273 if(!m_vpDividendData[c]->zero_derivative())
277 for(
size_t fct = 0; fct < dividend_num_fct(c); ++fct)
280 const size_t commonFct = dividend_common_fct(c, fct);
283 for(
size_t sh = 0; sh < this->num_sh(fct); ++sh)
285 if(dividend_value(c,
s,ip)!=0)
287 vvvDeriv[ip][commonFct][sh] +=
289 * dividend_deriv(c,
s, ip, fct, sh) / divisor_value(c,
s,ip);
293 vvvDeriv[ip][commonFct][sh] += 0;
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: inverse_linker.h:60
InverseLinker()
constructor
Definition: inverse_linker.h:67
void evaluate(number &value, const MathVector< dim > &globIP, number time, int si) const
Definition: inverse_linker_impl.h:119
std::vector< SmartPtr< CplUserData< number, dim > > > m_vpDivisorData
data Divisor
Definition: inverse_linker.h:163
void eval_and_deriv(number 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< number > > vvvDeriv[], const MathMatrix< refDim, dim > *vJT=NULL) const
Definition: inverse_linker_impl.h:176
void divide(SmartPtr< CplUserData< number, dim > > dividend, SmartPtr< CplUserData< number, dim > > divisor)
Definition: inverse_linker_impl.h:66
std::vector< SmartPtr< CplUserData< number, dim > > > m_vpDividendData
data Dividend
Definition: inverse_linker.h:157
Definition: local_algebra.h:198
A class for fixed size, dense matrices.
Definition: math_matrix.h:52
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
bool CloseToZero(double d)
Definition: number_util.h:48
bool IsFiniteAndNotTooBig(double d)
Definition: number_util.h:39