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 : #include "elem_disc_interface.h"
34 : #include "lib_disc/common/groups_util.h"
35 :
36 : namespace ug{
37 :
38 : template <typename TDomain>
39 0 : IElemDiscBase<TDomain>::IElemDiscBase(const char* functions, const char* subsets)
40 : : m_spApproxSpace(NULL), m_spFctPattern(0),
41 0 : m_timePoint(0), m_pLocalVectorTimeSeries(NULL), m_bStationaryForced(false)
42 : //,m_id(ROID_UNKNOWN)
43 : {
44 0 : if(functions == NULL) functions = "";
45 0 : if(subsets == NULL) subsets = "";
46 0 : set_functions(functions);
47 0 : set_subsets(subsets);
48 : // set_default_add_fct(); // OBSOLETE: now part of base-type constructor
49 0 : }
50 :
51 :
52 : template <typename TDomain>
53 0 : IElemDiscBase<TDomain>::
54 : IElemDiscBase(const std::vector<std::string>& vFct,
55 : const std::vector<std::string>& vSubset)
56 : : m_spApproxSpace(NULL), m_spFctPattern(0),
57 0 : m_timePoint(0), m_pLocalVectorTimeSeries(NULL), m_bStationaryForced(false)
58 : //,m_id(ROID_UNKNOWN)
59 : {
60 0 : set_functions(vFct);
61 0 : set_subsets(vSubset);
62 : // set_default_add_fct(); // OBSOLETE: now part of base-type constructor
63 0 : }
64 :
65 :
66 : template <typename TDomain>
67 0 : void IElemDiscBase<TDomain>::
68 : set_approximation_space(SmartPtr<ApproximationSpace<TDomain> > approxSpace)
69 : {
70 : // check whether the approximation space has already been set
71 : bool newApproxSpace = (m_spApproxSpace != approxSpace);
72 :
73 : // remember approx space
74 0 : m_spApproxSpace = approxSpace;
75 :
76 : // set function pattern
77 0 : set_function_pattern(approxSpace->dof_distribution_info());
78 :
79 : // invoke callback
80 0 : if(newApproxSpace)
81 0 : approximation_space_changed();
82 0 : }
83 :
84 : template <typename TLeaf, typename TDomain>
85 0 : void IElemAssembleFuncs<TLeaf, TDomain>::clear_add_fct(ReferenceObjectID id)
86 : {
87 0 : m_vPrepareTimestepElemFct[id] = NULL;
88 0 : m_vFinishTimestepElemFct[id] = NULL;
89 :
90 0 : m_vPrepareElemLoopFct[id] = NULL;
91 0 : m_vPrepareElemFct[id] = NULL;
92 0 : m_vFinishElemLoopFct[id] = NULL;
93 :
94 0 : m_vElemJAFct[id] = NULL;
95 0 : m_vElemJMFct[id] = NULL;
96 :
97 0 : m_vElemdAFct[id] = NULL;
98 0 : m_vElemdAExplFct[id] = NULL;
99 0 : m_vElemdMFct[id] = NULL;
100 :
101 0 : m_vElemRHSFct[id] = NULL;
102 0 : }
103 :
104 :
105 : template <typename TLeaf, typename TDomain>
106 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::clear_add_fct(ReferenceObjectID id)
107 : {
108 0 : m_vPrepareErrEstElemLoopFct[id] = NULL;
109 0 : m_vPrepareErrEstElemFct[id] = NULL;
110 0 : m_vElemComputeErrEstAFct[id] = NULL;
111 0 : m_vElemComputeErrEstMFct[id] = NULL;
112 0 : m_vElemComputeErrEstRhsFct[id] = NULL;
113 0 : m_vFinishErrEstElemLoopFct[id] = NULL;
114 0 : }
115 :
116 :
117 : //template <typename TDomain>
118 : //void IElemDisc<TDomain>::clear_add_fct(ReferenceObjectID id)
119 : //{
120 : /*m_vPrepareTimestepElemFct[id] = NULL;
121 : m_vFinishTimestepElemFct[id] = NULL;
122 :
123 : m_vPrepareElemLoopFct[id] = NULL;
124 : m_vPrepareElemFct[id] = NULL;
125 : m_vFinishElemLoopFct[id] = NULL;
126 :
127 : m_vElemJAFct[id] = NULL;
128 : m_vElemJMFct[id] = NULL;
129 :
130 : m_vElemdAFct[id] = NULL;
131 : m_vElemdAExplFct[id] = NULL;
132 : m_vElemdMFct[id] = NULL;
133 :
134 : m_vElemRHSFct[id] = NULL;
135 :
136 : m_vPrepareErrEstElemLoopFct[id] = NULL;
137 : m_vPrepareErrEstElemFct[id] = NULL;
138 : m_vElemComputeErrEstAFct[id] = NULL;
139 : m_vElemComputeErrEstMFct[id] = NULL;
140 : m_vElemComputeErrEstRhsFct[id] = NULL;
141 : m_vFinishErrEstElemLoopFct[id] = NULL;
142 : */
143 : // IElemAssembleFuncs<IElemDisc<TDomain>, TDomain>::clear_add_fct(id);
144 : // IElemEstimatorFuncs<IElemDisc<TDomain>, TDomain>::clear_add_fct(id);
145 : //}
146 :
147 :
148 : template <typename TLeaf, typename TDomain>
149 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
150 : clear_add_fct()
151 : {
152 0 : for(size_t i = 0; i < NUM_REFERENCE_OBJECTS; ++i)
153 0 : clear_add_fct((ReferenceObjectID) i);
154 :
155 0 : for (size_t i = 0; i < bridge::NUM_ALGEBRA_TYPES; ++i)
156 : {
157 0 : m_vPrepareTimestepFct[i] = NULL;
158 0 : m_vFinishTimestepFct[i] = NULL;
159 : }
160 0 : }
161 :
162 : template <typename TLeaf, typename TDomain>
163 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
164 : clear_add_fct()
165 : {
166 0 : for(size_t i = 0; i < NUM_REFERENCE_OBJECTS; ++i)
167 0 : clear_add_fct((ReferenceObjectID) i);
168 0 : }
169 : /*
170 : template <typename TDomain>
171 : void IElemDisc<TDomain>::clear_add_fct()
172 : {
173 : for(size_t i = 0; i < NUM_REFERENCE_OBJECTS; ++i)
174 : clear_add_fct((ReferenceObjectID) i);
175 :
176 : assemble_base_type::clear_add_fct();
177 : }
178 :
179 : */
180 : template <typename TLeaf, typename TDomain>
181 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
182 : set_default_add_fct()
183 : {
184 0 : for(size_t i = 0; i < NUM_REFERENCE_OBJECTS; ++i)
185 : {
186 0 : m_vPrepareTimestepElemFct[i] = &T::prep_timestep_elem;
187 0 : m_vFinishTimestepElemFct[i] = &T::fsh_timestep_elem;
188 :
189 0 : m_vPrepareElemLoopFct[i] = &T::prep_elem_loop;
190 0 : m_vPrepareElemFct[i] = &T::prep_elem;
191 0 : m_vFinishElemLoopFct[i] = &T::fsh_elem_loop;
192 :
193 0 : m_vElemJAFct[i] = &T::add_jac_A_elem;
194 0 : m_vElemJMFct[i] = &T::add_jac_M_elem;
195 :
196 0 : m_vElemdAFct[i] = &T::add_def_A_elem;
197 0 : m_vElemdAExplFct[i] = &T::add_def_A_expl_elem;
198 0 : m_vElemdMFct[i] = &T::add_def_M_elem;
199 :
200 0 : m_vElemRHSFct[i] = &T::add_rhs_elem;
201 : }
202 :
203 0 : for (size_t i = 0; i < bridge::NUM_ALGEBRA_TYPES; ++i)
204 : {
205 0 : m_vPrepareTimestepFct[i] = &T::prep_timestep;
206 0 : m_vFinishTimestepFct[i] = &T::fsh_timestep;
207 : }
208 :
209 0 : }
210 :
211 : template <typename TLeaf, typename TDomain>
212 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::set_default_add_fct()
213 : {
214 0 : for(size_t i = 0; i < NUM_REFERENCE_OBJECTS; ++i)
215 : {
216 0 : m_vPrepareErrEstElemLoopFct[i] = &T::prep_err_est_elem_loop;
217 0 : m_vPrepareErrEstElemFct[i] = &T::prep_err_est_elem;
218 0 : m_vElemComputeErrEstAFct[i] = &T::compute_err_est_A_elem;
219 0 : m_vElemComputeErrEstMFct[i] = &T::compute_err_est_M_elem;
220 0 : m_vElemComputeErrEstRhsFct[i] = &T::compute_err_est_rhs_elem;
221 0 : m_vFinishErrEstElemLoopFct[i] = &T::fsh_err_est_elem_loop;
222 : }
223 :
224 0 : }
225 :
226 : /*
227 : template <typename TDomain>
228 : void IElemDisc<TDomain>::
229 : set_default_add_fct()
230 : {
231 : IElemAssembleFuncs<IElemDisc<TDomain>, TDomain>::set_default_add_fct();
232 : IElemEstimatorFuncs<IElemDisc<TDomain>, TDomain>::set_default_add_fct();
233 : }
234 : */
235 :
236 : template <typename TDomain>
237 0 : void IElemDiscBase<TDomain>::set_functions(const std::string& fctString)
238 : {
239 0 : set_functions(TokenizeString(fctString));
240 0 : }
241 :
242 : template <typename TDomain>
243 0 : void IElemDiscBase<TDomain>::set_functions(const std::vector<std::string>& functions)
244 : {
245 0 : m_vFct = functions;
246 :
247 : // remove white space
248 0 : for(size_t i = 0; i < m_vFct.size(); ++i)
249 0 : RemoveWhitespaceFromString(m_vFct[i]);
250 :
251 : // if no function passed, clear functions
252 0 : if(m_vFct.size() == 1 && m_vFct[0].empty()) m_vFct.clear();
253 :
254 : // if functions passed with separator, but not all tokens filled, throw error
255 0 : for(size_t i = 0; i < m_vFct.size(); ++i)
256 : {
257 0 : if(m_vFct.empty())
258 0 : UG_THROW("Error while setting functions in an ElemDisc: passed "
259 : "function string lacks a "
260 : "function specification at position "<<i<<"(of "
261 : <<m_vFct.size()-1<<")");
262 : }
263 :
264 0 : update_function_index_mapping();
265 0 : }
266 :
267 : template <typename TDomain>
268 0 : void IElemDiscBase<TDomain>::set_subsets(const std::string& ssString)
269 : {
270 0 : set_subsets(TokenizeString(ssString));
271 0 : }
272 :
273 : template <typename TDomain>
274 0 : void IElemDiscBase<TDomain>::set_subsets(const std::vector<std::string>& subsets)
275 : {
276 0 : m_vSubset = subsets;
277 :
278 : // remove white space
279 0 : for(size_t i = 0; i < m_vSubset.size(); ++i)
280 0 : RemoveWhitespaceFromString(m_vSubset[i]);
281 :
282 : // if no subset passed, clear subsets
283 0 : if(m_vSubset.size() == 1 && m_vSubset[0].empty()) m_vSubset.clear();
284 :
285 : // if subsets passed with separator, but not all tokens filled, throw error
286 0 : for(size_t i = 0; i < m_vSubset.size(); ++i)
287 : {
288 0 : if(m_vSubset.empty())
289 0 : UG_THROW("Error while setting subsets in an ElemDisc: passed "
290 : "subset string lacks a "
291 : "subset specification at position "<<i<<"(of "
292 : <<m_vSubset.size()-1<<")");
293 : }
294 0 : }
295 :
296 : template <typename TDomain>
297 0 : void IElemDiscBase<TDomain>::set_function_pattern(ConstSmartPtr<FunctionPattern> fctPatt)
298 : {
299 0 : m_spFctPattern = fctPatt;
300 0 : update_function_index_mapping();
301 0 : }
302 :
303 : template <typename TDomain>
304 0 : void IElemDiscBase<TDomain>::update_function_index_mapping()
305 : {
306 : // without fct pattern, cannot create mappings
307 0 : if(m_spFctPattern.invalid()) return;
308 :
309 : // create function group of this elem disc
310 : try{
311 0 : m_fctGrp.set_function_pattern(m_spFctPattern);
312 0 : m_fctGrp.add(this->symb_fcts());
313 0 : }UG_CATCH_THROW("ElemDisc: Cannot find some symbolic Function Name.");
314 :
315 : // create a mapping between all functions and the function group of this
316 : // element disc.
317 0 : try{CreateFunctionIndexMapping(m_fctIndexMap, m_fctGrp, m_spFctPattern);
318 0 : }UG_CATCH_THROW("ElemDisc: Cannot create Function Index Mapping.");
319 :
320 : // set function group at imports
321 0 : for(size_t i = 0; i < m_vIImport.size(); ++i){
322 0 : m_vIImport[i]->set_map(m_fctIndexMap);
323 : }
324 : }
325 :
326 : template <typename TDomain>
327 0 : void IElemDiscBase<TDomain>::check_setup(bool bNonRegularGrid)
328 : {
329 : // check that all functions are defined on chosen subsets
330 0 : SubsetGroup discSubsetGrp(m_spFctPattern->subset_handler(), m_vSubset);
331 :
332 : // check that all functions are defined on chosen subsets
333 0 : for(size_t fct = 0; fct < m_fctGrp.size(); ++fct){
334 0 : for(size_t si = 0; si < discSubsetGrp.size(); ++si){
335 : if(!m_spFctPattern->is_def_in_subset(m_fctGrp[fct], discSubsetGrp[si])){
336 : UG_LOG("WARNING in ElemDisc: symbolic Function "<< symb_fcts()[fct]
337 : << " is not defined on subset "<< symb_subsets()[si]
338 : << ". This may be senseful only in particular cases.\n");
339 : }
340 : }
341 : }
342 :
343 : // request assembling for local finite element id
344 0 : std::vector<LFEID> vLfeID(m_fctGrp.size());
345 0 : for(size_t f = 0; f < vLfeID.size(); ++f)
346 0 : vLfeID[f] = m_fctGrp.local_finite_element_id(f);
347 :
348 0 : prepare_setting(vLfeID, bNonRegularGrid);
349 0 : }
350 :
351 :
352 : template <typename TDomain>
353 0 : void IElemDiscBase<TDomain>::register_import(IDataImport<dim>& Imp)
354 : {
355 : // check that not already registered
356 0 : for(size_t i = 0; i < m_vIImport.size(); ++i)
357 0 : if(m_vIImport[i] == &Imp)
358 0 : UG_THROW("Trying to register import twice.");
359 :
360 : // add it
361 0 : m_vIImport.push_back(&Imp);
362 :
363 0 : update_function_index_mapping();
364 0 : }
365 :
366 : template <typename TLeaf, typename TDomain>
367 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
368 : check_roid(ReferenceObjectID roid, int discType)
369 : {
370 :
371 0 : }
372 :
373 :
374 : template <typename TLeaf, typename TDomain>
375 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
376 : set_roid(ReferenceObjectID roid, int discType)
377 : {
378 0 : m_roid = roid;
379 :
380 0 : if(roid == ROID_UNKNOWN)
381 : {
382 0 : m_roid = ROID_UNKNOWN;
383 0 : UG_THROW("ElemDisc: Reference element type has not been set correctly.");
384 : }
385 : check_roid(roid, discType);
386 0 : };
387 :
388 :
389 : template <typename TLeaf, typename TDomain>
390 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
391 : check_roid(ReferenceObjectID roid, int discType)
392 : {
393 0 : if(m_vPrepareElemLoopFct[roid]==NULL)
394 0 : UG_THROW("ElemDisc: Missing evaluation method 'prepare_elem_loop' for "<<roid<<" (world dim: "<<dim<<")");
395 0 : if(m_vPrepareElemFct[roid]==NULL)
396 0 : UG_THROW("ElemDisc: Missing evaluation method 'prepare_elem' for "<<roid<<" (world dim: "<<dim<<")");
397 0 : if(m_vFinishElemLoopFct[roid]==NULL)
398 0 : UG_THROW("ElemDisc: Missing evaluation method 'finish_elem_loop' for "<<roid<<" (world dim: "<<dim<<")");
399 :
400 0 : if(discType & MASS){
401 0 : if(m_vElemJMFct[roid]==NULL)
402 0 : UG_THROW("ElemDisc: Missing evaluation method 'add_jac_M_elem' for "<<roid<<" (world dim: "<<dim<<")");
403 0 : if(m_vElemdMFct[roid]==NULL)
404 0 : UG_THROW("ElemDisc: Missing evaluation method 'add_def_M_elem' for "<<roid<<" (world dim: "<<dim<<")");
405 : }
406 0 : if(discType & STIFF){
407 0 : if(m_vElemJAFct[roid]==NULL)
408 0 : UG_THROW("ElemDisc: Missing evaluation method 'add_jac_A_elem' for "<<roid<<" (world dim: "<<dim<<")");
409 0 : if(m_vElemdAFct[roid]==NULL)
410 0 : UG_THROW("ElemDisc: Missing evaluation method 'add_def_A_elem for' "<<roid<<" (world dim: "<<dim<<")");
411 : }
412 0 : if(discType & RHS){
413 0 : if(m_vElemRHSFct[roid]==NULL)
414 0 : UG_THROW("ElemDisc: Missing evaluation method 'add_rhs_elem' for "<<roid<<" (world dim: "<<dim<<")");
415 : }
416 0 : }
417 :
418 :
419 :
420 : template <typename TLeaf, typename TDomain>
421 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
422 : set_roid(ReferenceObjectID roid, int discType)
423 : {
424 0 : m_roid = roid;
425 :
426 0 : if(roid == ROID_UNKNOWN)
427 : {
428 0 : m_roid = ROID_UNKNOWN;
429 0 : UG_THROW("ElemDisc: Reference element type has not been set correctly.");
430 : }
431 0 : check_roid(roid, discType);
432 0 : };
433 :
434 :
435 : template <typename TDomain>
436 0 : void IElemDiscBase<TDomain>::
437 : set_time_dependent(LocalVectorTimeSeries& locTimeSeries,
438 : const std::vector<number>& vScaleMass,
439 : const std::vector<number>& vScaleStiff)
440 : {
441 0 : m_pLocalVectorTimeSeries = &locTimeSeries;
442 0 : m_vScaleMass = vScaleMass;
443 0 : m_vScaleStiff = vScaleStiff;
444 0 : }
445 :
446 : template <typename TDomain>
447 0 : void IElemDiscBase<TDomain>::set_time_independent()
448 : {
449 0 : m_pLocalVectorTimeSeries = NULL;
450 : m_vScaleMass.clear();
451 : m_vScaleStiff.clear();
452 0 : }
453 :
454 : ////////////////////////////////////////////////////////////////////////////////
455 : // throw functions
456 : ////////////////////////////////////////////////////////////////////////////////
457 :
458 0 : inline void ThrowMissingVirtualMethod(const char* method, const ReferenceObjectID roid){
459 0 : UG_THROW("ElemDisc: No override for the essential assembling function "
460 : "'"<<method<<"' for " << roid << " implemented!");
461 : }
462 0 : inline void ThrowMissingVirtualMethod(const char* method){
463 0 : UG_THROW("ElemDisc: No override for the essential assembling function "
464 : "'"<<method<<"' implemented!");
465 : }
466 :
467 : ////////////////////////////////////////////////////////////////////////////////
468 : // assembling functions dispatches
469 : ////////////////////////////////////////////////////////////////////////////////
470 :
471 : template <typename TLeaf, typename TDomain>
472 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
473 : do_prep_timestep(number future_time, const number time, VectorProxyBase* u, size_t algebra_id)
474 : {
475 : // call assembling routine
476 0 : if (this->m_vPrepareTimestepFct[algebra_id] != NULL)
477 0 : (this->*(m_vPrepareTimestepFct[algebra_id]))(future_time, time, u);
478 0 : }
479 :
480 : template <typename TLeaf, typename TDomain>
481 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
482 : do_prep_timestep_elem(const number time, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
483 : {
484 : // access by map
485 : u.access_by_map(asLeaf().map());
486 0 : if(asLeaf().local_time_series_needed())
487 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
488 :
489 : // call assembling routine
490 0 : if (this->m_vPrepareTimestepElemFct[m_roid] != NULL)
491 0 : (this->*(m_vPrepareTimestepElemFct[m_roid]))(time, u, elem, vCornerCoords);
492 0 : }
493 :
494 : template <typename TLeaf, typename TDomain>
495 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
496 : do_prep_elem(LocalVector& u, GridObject* elem, const ReferenceObjectID roid, const MathVector<dim> vCornerCoords[])
497 : {
498 : // access by map
499 : u.access_by_map(asLeaf().map());
500 0 : if(asLeaf().local_time_series_needed())
501 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
502 :
503 : // call assembling routine
504 : UG_ASSERT(m_vPrepareElemFct[m_roid]!=NULL, "ElemDisc method prepare_elem missing.");
505 0 : (this->*(m_vPrepareElemFct[m_roid]))(u, elem, roid, vCornerCoords);
506 0 : }
507 :
508 : template <typename TLeaf, typename TDomain>
509 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
510 : do_fsh_timestep(const number time, VectorProxyBase* u, size_t algebra_id)
511 : {
512 : // call assembling routine
513 0 : if (this->m_vFinishTimestepFct[algebra_id] != NULL)
514 0 : (this->*(m_vFinishTimestepFct[algebra_id]))(time, u);
515 0 : }
516 :
517 : template <typename TLeaf, typename TDomain>
518 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
519 : do_fsh_timestep_elem(const number time, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
520 : {
521 : // access by map
522 : u.access_by_map(asLeaf().map());
523 0 : if(asLeaf().local_time_series_needed())
524 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
525 :
526 : // call assembling routine
527 0 : if (this->m_vFinishTimestepElemFct[m_roid] != NULL)
528 0 : (this->*(m_vFinishTimestepElemFct[m_roid]))(time, u, elem, vCornerCoords);
529 0 : }
530 :
531 : template <typename TLeaf, typename TDomain>
532 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
533 : do_prep_elem_loop(const ReferenceObjectID roid, const int si)
534 : {
535 : // set id and disc part (this checks the assemble functions)
536 0 : set_roid(roid, si);
537 :
538 : // remove positions in currently registered imports
539 0 : for(size_t i = 0; i < asLeaf().m_vIImport.size(); ++i)
540 0 : asLeaf().m_vIImport[i]->clear_ips();
541 :
542 : // call prep_elem_loop (this may set ip-series to imports)
543 : // call assembling routine
544 : UG_ASSERT(m_vPrepareElemLoopFct[m_roid]!=NULL, "ElemDisc method prepare_elem_loop missing.");
545 0 : (this->*m_vPrepareElemLoopFct[m_roid])(roid, si);
546 :
547 : // set roid in imports (for evaluation function)
548 0 : for(size_t i = 0; i < asLeaf().m_vIImport.size(); ++i)
549 0 : asLeaf().m_vIImport[i]->set_roid(roid);
550 0 : }
551 :
552 : template <typename TLeaf, typename TDomain>
553 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
554 : do_fsh_elem_loop()
555 : {
556 : // call finish
557 : UG_ASSERT(m_vFinishElemLoopFct[m_roid]!=NULL, "ElemDisc method finish_elem_loop missing.");
558 0 : (this->*m_vFinishElemLoopFct[m_roid])();
559 :
560 : // remove positions in currently registered imports
561 0 : for(size_t i = 0; i < asLeaf().m_vIImport.size(); ++i)
562 0 : asLeaf().m_vIImport[i]->clear_ips();
563 0 : }
564 :
565 : template <typename TLeaf, typename TDomain>
566 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
567 : do_add_jac_A_elem(LocalMatrix& J, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
568 : {
569 : // access by map
570 : u.access_by_map(asLeaf().map());
571 : J.access_by_map(asLeaf().map());
572 0 : if(asLeaf().local_time_series_needed())
573 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
574 :
575 : // call assembling routine
576 : UG_ASSERT(m_vElemJAFct[m_roid]!=NULL, "ElemDisc method add_jac_A missing.");
577 0 : (this->*m_vElemJAFct[m_roid])(J, u, elem, vCornerCoords);
578 0 : }
579 :
580 : template <typename TLeaf, typename TDomain>
581 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
582 : do_add_jac_M_elem(LocalMatrix& J, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
583 : {
584 : // check if really needed (may occur in cases, when mixing stat and instat)
585 0 : if(asLeaf().m_bStationaryForced) return;
586 :
587 : // access by map
588 : u.access_by_map(asLeaf().map());
589 : J.access_by_map(asLeaf().map());
590 0 : if(asLeaf().local_time_series_needed())
591 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
592 :
593 : // call assembling routine
594 : UG_ASSERT(m_vElemJMFct[m_roid]!=NULL, "ElemDisc method add_jac_M missing.");
595 0 : (this->*m_vElemJMFct[m_roid])(J, u, elem, vCornerCoords);
596 : }
597 :
598 : template <typename TLeaf, typename TDomain>
599 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
600 : do_add_def_A_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
601 : {
602 : // access by map
603 : u.access_by_map(asLeaf().map());
604 : d.access_by_map(asLeaf().map());
605 0 : if(asLeaf().local_time_series_needed())
606 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
607 :
608 : // call assembling routine
609 : UG_ASSERT(m_vElemdAFct[m_roid]!=NULL, "ElemDisc method add_def_A missing.");
610 0 : (this->*m_vElemdAFct[m_roid])(d, u, elem, vCornerCoords);
611 0 : }
612 :
613 : template <typename TLeaf, typename TDomain>
614 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
615 : do_add_def_A_expl_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
616 : {
617 : // access by map
618 : u.access_by_map(asLeaf().map());
619 : d.access_by_map(asLeaf().map());
620 0 : if(asLeaf().local_time_series_needed())
621 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
622 :
623 : // call assembling routine
624 0 : if(this->m_vElemdAExplFct[m_roid] != NULL)
625 0 : (this->*m_vElemdAExplFct[m_roid])(d, u, elem, vCornerCoords);
626 0 : }
627 :
628 : template <typename TLeaf, typename TDomain>
629 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
630 : do_add_def_M_elem(LocalVector& d, LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
631 : {
632 : // check if really needed (may occur in cases, when mixing stat and instat)
633 0 : if(asLeaf().m_bStationaryForced) return;
634 :
635 : // access by map
636 : u.access_by_map(asLeaf().map());
637 : d.access_by_map(asLeaf().map());
638 0 : if(asLeaf().local_time_series_needed())
639 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
640 :
641 : // call assembling routine
642 : UG_ASSERT(m_vElemdMFct[m_roid]!=NULL, "ElemDisc method add_def_M missing.");
643 0 : (this->*m_vElemdMFct[m_roid])(d, u, elem, vCornerCoords);
644 : }
645 :
646 : template <typename TLeaf, typename TDomain>
647 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
648 : do_add_rhs_elem(LocalVector& rhs, GridObject* elem, const MathVector<dim> vCornerCoords[])
649 : {
650 : // access by map
651 : rhs.access_by_map(asLeaf().map());
652 0 : if(asLeaf().local_time_series_needed())
653 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
654 :
655 : // call assembling routine
656 : UG_ASSERT(m_vElemRHSFct[m_roid]!=NULL, "ElemDisc method add_rhs missing.");
657 0 : (this->*m_vElemRHSFct[m_roid])(rhs, elem, vCornerCoords);
658 0 : }
659 :
660 : template <typename TLeaf, typename TDomain>
661 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
662 : do_prep_err_est_elem_loop(const ReferenceObjectID roid, const int si)
663 : {
664 : // set id and disc part (this checks the assemble functions)
665 0 : set_roid(roid, si);
666 :
667 : // remove positions in currently registered imports
668 0 : for(std::size_t i = 0; i < asLeaf().num_imports(); ++i)
669 0 : asLeaf().get_import(i).clear_ips();
670 :
671 : // call prep_elem_loop (this may set ip-series to imports)
672 : UG_ASSERT(m_vPrepareErrEstElemLoopFct[m_roid]!=NULL, "ElemDisc method prep_err_est_elem_loop missing.");
673 0 : (this->*m_vPrepareErrEstElemLoopFct[m_roid])(roid, si);
674 :
675 : // set roid in imports (for evaluation function)
676 0 : for(std::size_t i = 0; i < asLeaf().num_imports(); ++i)
677 0 : asLeaf().get_import(i).set_roid(roid);
678 0 : }
679 :
680 : template <typename TLeaf, typename TDomain>
681 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
682 : do_prep_err_est_elem(LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
683 : {
684 : // access by map
685 : u.access_by_map(asLeaf().map());
686 0 : if (asLeaf().local_time_series_needed())
687 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
688 :
689 : // call assembling routine
690 : UG_ASSERT(m_vPrepareErrEstElemFct[m_roid]!=NULL, "ElemDisc method prepare_err_est_elem missing.");
691 0 : (this->*(m_vPrepareErrEstElemFct[m_roid]))(u, elem, vCornerCoords);
692 0 : }
693 :
694 : template <typename TLeaf, typename TDomain>
695 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
696 : do_compute_err_est_A_elem(LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
697 : {
698 : // access by map
699 : u.access_by_map(asLeaf().map());
700 0 : if (asLeaf().local_time_series_needed())
701 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
702 :
703 : // call assembling routine
704 0 : if (this->m_vElemComputeErrEstAFct[m_roid] != NULL)
705 0 : (this->*(m_vElemComputeErrEstAFct[m_roid]))(u, elem, vCornerCoords, scale);
706 0 : }
707 :
708 : template <typename TLeaf, typename TDomain>
709 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
710 : do_compute_err_est_M_elem(LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
711 : {
712 : // access by map
713 : u.access_by_map(asLeaf().map());
714 0 : if(asLeaf().local_time_series_needed())
715 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
716 :
717 : // call assembling routine
718 0 : if(this->m_vElemComputeErrEstMFct[m_roid] != NULL)
719 0 : (this->*(m_vElemComputeErrEstMFct[m_roid]))(u, elem, vCornerCoords, scale);
720 0 : }
721 :
722 : template <typename TLeaf, typename TDomain>
723 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
724 : do_compute_err_est_rhs_elem(GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
725 : {
726 0 : if(asLeaf().local_time_series_needed())
727 0 : asLeaf().m_pLocalVectorTimeSeries->access_by_map(asLeaf().map());
728 :
729 : // call assembling routine
730 0 : if(this->m_vElemComputeErrEstRhsFct[m_roid] != NULL)
731 0 : (this->*(m_vElemComputeErrEstRhsFct[m_roid]))(elem, vCornerCoords, scale);
732 0 : }
733 :
734 : template <typename TLeaf, typename TDomain>
735 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
736 : do_fsh_err_est_elem_loop()
737 : {
738 : // call finish
739 0 : if (this->m_vFinishErrEstElemLoopFct[m_roid] != NULL)
740 0 : (this->*m_vFinishErrEstElemLoopFct[m_roid])();
741 :
742 : // remove positions in currently registered imports
743 0 : for(size_t i = 0; i < asLeaf().num_imports(); ++i)
744 0 : asLeaf().get_import(i).clear_ips();
745 0 : }
746 :
747 :
748 :
749 : ////////////////////////////////////////////////////////////////////////////////
750 : // virtual assembling functions default
751 : ////////////////////////////////////////////////////////////////////////////////
752 :
753 : template <typename TLeaf, typename TDomain>
754 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
755 : prep_timestep(number future_time, number time, VectorProxyBase* u)
756 : {
757 : // do nothing
758 0 : }
759 :
760 : template <typename TLeaf, typename TDomain>
761 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
762 : prep_timestep_elem(const number time, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
763 : {
764 : // ThrowMissingVirtualMethod("prep_timestep_elem", elem->reference_object_id ());
765 0 : }
766 :
767 : template <typename TLeaf, typename TDomain>
768 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
769 : prep_elem(const LocalVector& u, GridObject* elem, const ReferenceObjectID roid, const MathVector<dim> vCornerCoords[])
770 : {
771 0 : ThrowMissingVirtualMethod("prep_elem", elem->reference_object_id ());
772 : }
773 :
774 : template <typename TLeaf, typename TDomain>
775 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
776 : fsh_timestep(number time, VectorProxyBase* u)
777 : {
778 : // do nothing
779 0 : }
780 :
781 : template <typename TLeaf, typename TDomain>
782 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
783 : fsh_timestep_elem(const number time, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
784 : {
785 : // ThrowMissingVirtualMethod("fsh_timestep_elem", elem->reference_object_id ());
786 0 : }
787 :
788 : template <typename TLeaf, typename TDomain>
789 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
790 : prep_elem_loop(const ReferenceObjectID roid, const int si)
791 : {
792 0 : ThrowMissingVirtualMethod("prep_elem_loop", roid);
793 : }
794 :
795 : template <typename TLeaf, typename TDomain>
796 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
797 : fsh_elem_loop()
798 : {
799 0 : ThrowMissingVirtualMethod("fsh_elem_loop");
800 : }
801 :
802 : template <typename TLeaf, typename TDomain>
803 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
804 : add_jac_A_elem(LocalMatrix& J, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
805 : {
806 0 : ThrowMissingVirtualMethod("add_jac_A_elem", elem->reference_object_id ());
807 : }
808 :
809 : template <typename TLeaf, typename TDomain>
810 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
811 : add_jac_M_elem(LocalMatrix& J, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
812 : {
813 0 : ThrowMissingVirtualMethod("add_jac_M_elem", elem->reference_object_id ());
814 : }
815 :
816 : template <typename TLeaf, typename TDomain>
817 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
818 : add_def_A_elem(LocalVector& d, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
819 : {
820 0 : ThrowMissingVirtualMethod("add_def_A_elem", elem->reference_object_id ());
821 : }
822 :
823 : template <typename TLeaf, typename TDomain>
824 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
825 : add_def_A_expl_elem(LocalVector& d, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
826 : {
827 : // ThrowMissingVirtualMethod("add_def_A_expl_elem", elem->reference_object_id ());
828 0 : }
829 :
830 : template <typename TLeaf, typename TDomain>
831 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
832 : add_def_M_elem(LocalVector& d, const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
833 : {
834 0 : ThrowMissingVirtualMethod("add_def_M_elem", elem->reference_object_id ());
835 : }
836 :
837 : template <typename TLeaf, typename TDomain>
838 0 : void IElemAssembleFuncs<TLeaf, TDomain>::
839 : add_rhs_elem(LocalVector& rhs, GridObject* elem, const MathVector<dim> vCornerCoords[])
840 : {
841 0 : ThrowMissingVirtualMethod("add_rhs_elem", elem->reference_object_id ());
842 : }
843 :
844 : template <typename TLeaf, typename TDomain>
845 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
846 : prep_err_est_elem_loop(const ReferenceObjectID roid, const int si)
847 : {
848 : // ThrowMissingVirtualMethod("prep_err_est_elem_loop", roi);
849 0 : }
850 :
851 : template <typename TLeaf, typename TDomain>
852 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
853 : prep_err_est_elem(const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
854 : {
855 : //ThrowMissingVirtualMethod("prep_elem", elem->reference_object_id ());
856 0 : }
857 :
858 : template <typename TLeaf, typename TDomain>
859 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
860 : compute_err_est_A_elem(const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
861 : {
862 : // ThrowMissingVirtualMethod("compute_err_est_elem", elem->reference_object_id ());
863 0 : }
864 :
865 : template <typename TLeaf, typename TDomain>
866 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
867 : compute_err_est_M_elem(const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
868 : {
869 : // ThrowMissingVirtualMethod("compute_err_est_elem", elem->reference_object_id ());
870 0 : }
871 :
872 : template <typename TLeaf, typename TDomain>
873 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
874 : compute_err_est_rhs_elem(GridObject* elem, const MathVector<dim> vCornerCoords[], const number& scale)
875 : {
876 : // ThrowMissingVirtualMethod("compute_err_est_elem", elem->reference_object_id ());
877 0 : }
878 :
879 : template <typename TLeaf, typename TDomain>
880 0 : void IElemEstimatorFuncs<TLeaf, TDomain>::
881 : fsh_err_est_elem_loop()
882 : {
883 : // ThrowMissingVirtualMethod("fsh_err_est_elem_loop");
884 0 : }
885 :
886 :
887 : ////////////////////////////////////////////////////////////////////////////////
888 : // explicit template instantiations
889 : ////////////////////////////////////////////////////////////////////////////////
890 :
891 : #ifdef UG_DIM_1
892 : template class IElemDiscBase<Domain1d>;
893 : template class IElemAssembleFuncs<IElemDisc<Domain1d>, Domain1d>;
894 : template class IElemEstimatorFuncs<IElemDisc<Domain1d>, Domain1d>;
895 : template class IElemError<Domain1d>;
896 : template class IElemDisc<Domain1d>;
897 : #endif
898 : #ifdef UG_DIM_2
899 : template class IElemDiscBase<Domain2d>;
900 : template class IElemAssembleFuncs<IElemDisc<Domain2d>, Domain2d>;
901 : template class IElemEstimatorFuncs<IElemDisc<Domain2d>, Domain2d>;
902 : template class IElemError<Domain2d>;
903 : template class IElemDisc<Domain2d>;
904 : #endif
905 : #ifdef UG_DIM_3
906 : template class IElemDiscBase<Domain3d>;
907 : template class IElemAssembleFuncs<IElemDisc<Domain3d>, Domain3d>;
908 : template class IElemEstimatorFuncs<IElemDisc<Domain3d>, Domain3d>;
909 : template class IElemError<Domain3d>;
910 : template class IElemDisc<Domain3d>;
911 : #endif
912 :
913 : } // end namespace ug
914 :
|