Line data Source code
1 : /*
2 : * Copyright (c) 2010-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__USER_DATA__USER_DATA__
34 : #define __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__USER_DATA__
35 :
36 : #include <vector>
37 : #include <cstring>
38 :
39 : #include "common/types.h"
40 : #include "lib_disc/common/local_algebra.h"
41 : #include "lib_disc/time_disc/solution_time_series.h"
42 : #include "lib_disc/common/function_group.h"
43 :
44 : namespace ug{
45 :
46 : ////////////////////////////////////////////////////////////////////////////////
47 : // UserData Info
48 : ////////////////////////////////////////////////////////////////////////////////
49 :
50 : /// base class providing runtime-info on dimension and type
51 0 : class UserDataInfo {
52 : public:
53 : /// returns dimension
54 : virtual int get_dim() const = 0;
55 :
56 : /// returns type of data as string (e.g. "Number", "Vector", "Matrix")
57 : virtual std::string type() const = 0;
58 :
59 : /// returns if provided data is continuous over geometric object boundaries
60 : virtual bool continuous() const = 0;
61 :
62 : /// virtual destructor
63 0 : virtual ~UserDataInfo() {}
64 :
65 : public:
66 : /// returns if grid function is needed for evaluation
67 : virtual bool requires_grid_fct() const = 0;
68 :
69 : /// sets the function pattern for a possibly needed grid function
70 0 : virtual void set_function_pattern(ConstSmartPtr<FunctionPattern> fctPatt) {
71 0 : m_fctGrp.set_function_pattern(fctPatt);
72 0 : }
73 :
74 : /// Function Group of functions
75 0 : const FunctionGroup& function_group() const {return m_fctGrp;}
76 :
77 : /// get function mapping
78 0 : const FunctionIndexMapping& map() const{return m_map;}
79 :
80 : /// number of functions this export depends on
81 : size_t num_fct() const {return m_map.num_fct();}
82 :
83 : /// sets the name of the object (s. the field m_objName)
84 : /**
85 : * Note that the object name is not unique in general. Several objects may have the same name.
86 : */
87 0 : void set_obj_name(const char * name)
88 : {
89 0 : if (name == NULL) {m_objName = SPNULL; return;}
90 0 : if (m_objName.valid ()) // we assume that the name is assigned once; otherwise we warn
91 0 : UG_LOG ("Warning: Replacing existing UserData object name '" << m_objName.get() << "' with '" << name << "'.\n");
92 0 : const size_t name_len = strnlen (name, 128);
93 0 : SmartPtr<char> new_name (new char [name_len+1]);
94 0 : memcpy (new_name.get(), name, name_len); (new_name.get()) [name_len] = '\0';
95 0 : m_objName = new_name;
96 : }
97 :
98 : /// gets the name of the object (s. the field m_objName)
99 : /**
100 : * Note that the object name is not unique in general. Several objects may have the same name.
101 : */
102 0 : const char * obj_name () {return m_objName.get ();}
103 :
104 : protected:
105 : /// functions the data depends on
106 : FunctionGroup m_fctGrp;
107 :
108 : /// Mapping for import fct
109 : FunctionIndexMapping m_map;
110 :
111 : /// This field is used mainly for debugging: One can assign a name to the object to identify it when running
112 : SmartPtr<char> m_objName; ///< this strange type underlines the debugging nature of this field: it is seldom used but should be easily accessed in a debugger
113 : };
114 :
115 : ////////////////////////////////////////////////////////////////////////////////
116 : // UserData
117 : ////////////////////////////////////////////////////////////////////////////////
118 :
119 : // Traits
120 : template <typename TData>
121 : struct user_data_traits{static std::string name() {return "(unknown)";}};
122 : template <>
123 6 : struct user_data_traits<number>{static std::string name() {return "Number";}};
124 : template <std::size_t dim>
125 6 : struct user_data_traits< MathVector<dim> >{static std::string name() {return "Vector";}};
126 : template <std::size_t dim>
127 6 : struct user_data_traits< MathMatrix<dim,dim> >{static std::string name() {return "Matrix";}};
128 : template <std::size_t dim>
129 6 : struct user_data_traits< MathTensor<4,dim> >{static std::string name() {return "Tensor4";}};
130 :
131 : /// Type based UserData
132 : /**
133 : * This class is the base class for all integration point data for a templated
134 : * type. It provides the access to the data and handles the global integration
135 : * points.
136 : *
137 : * \tparam TData Data
138 : * \tparam dim world dimension
139 : * \tparam TRet Type of return flag (bool or void)
140 : */
141 : template <typename TData, int dim, typename TRet = void>
142 0 : class UserData : virtual public UserDataInfo
143 : {
144 : public:
145 : typedef TData data_type;
146 : typedef TRet return_type;
147 :
148 : /// returns dimension
149 0 : int get_dim() const {return dim;}
150 :
151 : /// returns type of data as string (e.g. "Number", "Vector", "Matrix")
152 0 : std::string type() const {return user_data_traits<TData>::name();}
153 :
154 : /// returns if provided data is continuous over geometric object boundaries
155 : virtual bool continuous() const = 0;
156 :
157 : /// returns if grid function is needed for evaluation
158 : virtual bool requires_grid_fct() const = 0;
159 :
160 : public:
161 : /// returns value for a global position
162 : virtual TRet operator() (TData& value,
163 : const MathVector<dim>& globIP,
164 : number time, int si) const = 0;
165 :
166 : /// returns values for global positions
167 : virtual void operator()(TData vValue[],
168 : const MathVector<dim> vGlobIP[],
169 : number time, int si, const size_t nip) const = 0;
170 :
171 : /// returns a value at a vertex
172 0 : virtual void operator() (TData& value,
173 : const MathVector<dim>& globIP,
174 : number time, int si,
175 : Vertex* vrt) const
176 : {
177 : // The standard version uses only the coordinates. But it can be redefined.
178 0 : operator()(value, globIP, time, si);
179 0 : }
180 :
181 : /// returns value for local and global position
182 : /// \{
183 : TRet operator() (TData& value,
184 : const MathVector<dim>& globIP,
185 : number time, int si,
186 : GridObject* elem,
187 : const MathVector<dim> vCornerCoords[],
188 : const MathVector<1>& locIP,
189 : LocalVector* u) const {
190 0 : operator()(&value, &globIP, time, si, elem, vCornerCoords, &locIP, 1, u);
191 0 : }
192 :
193 : TRet operator() (TData& value,
194 : const MathVector<dim>& globIP,
195 : number time, int si,
196 : GridObject* elem,
197 : const MathVector<dim> vCornerCoords[],
198 : const MathVector<2>& locIP,
199 : LocalVector* u) const {
200 0 : operator()(&value, &globIP, time, si, elem, vCornerCoords, &locIP, 1, u);
201 0 : }
202 :
203 : TRet operator() (TData& value,
204 : const MathVector<dim>& globIP,
205 : number time, int si,
206 : GridObject* elem,
207 : const MathVector<dim> vCornerCoords[],
208 : const MathVector<3>& locIP,
209 : LocalVector* u) const {
210 0 : operator()(&value, &globIP, time, si, elem, vCornerCoords, &locIP, 1, u);
211 0 : }
212 : /// \}
213 :
214 : /// returns values for local and global positions
215 : /// \{
216 : virtual void operator()(TData vValue[],
217 : const MathVector<dim> vGlobIP[],
218 : number time, int si,
219 : GridObject* elem,
220 : const MathVector<dim> vCornerCoords[],
221 : const MathVector<1> vLocIP[],
222 : const size_t nip,
223 : LocalVector* u,
224 : const MathMatrix<1, dim>* vJT = NULL) const = 0;
225 :
226 : virtual void operator()(TData vValue[],
227 : const MathVector<dim> vGlobIP[],
228 : number time, int si,
229 : GridObject* elem,
230 : const MathVector<dim> vCornerCoords[],
231 : const MathVector<2> vLocIP[],
232 : const size_t nip,
233 : LocalVector* u,
234 : const MathMatrix<2, dim>* vJT = NULL) const = 0;
235 :
236 : virtual void operator()(TData vValue[],
237 : const MathVector<dim> vGlobIP[],
238 : number time, int si,
239 : GridObject* elem,
240 : const MathVector<dim> vCornerCoords[],
241 : const MathVector<3> vLocIP[],
242 : const size_t nip,
243 : LocalVector* u,
244 : const MathMatrix<3, dim>* vJT = NULL) const = 0;
245 : /// \}
246 : };
247 : ////////////////////////////////////////////////////////////////////////////////
248 : // UserData Interface
249 : ////////////////////////////////////////////////////////////////////////////////
250 :
251 : /// Base class for UserData
252 : /**
253 : * This is the base class for all coupled data at integration point. It handles
254 : * the set of local integration points and stores the current time.
255 : *
256 : * \tparam dim world dimension
257 : */
258 : template <int dim>
259 : class ICplUserData : virtual public UserDataInfo
260 : {
261 : public:
262 : /// default constructor
263 : ICplUserData();
264 :
265 : /// clear all data
266 : void clear();
267 :
268 : public:
269 : /// set the subset of evaluation
270 0 : void set_subset(int si) {m_si = si;}
271 :
272 : /// returns the subset of evaluation
273 0 : int subset() const {return m_si;}
274 :
275 : /// set evaluation time
276 0 : void set_times(const std::vector<number>& vTime) {m_vTime = vTime;}
277 :
278 : /// sets the current time point
279 0 : void set_time_point(size_t timePoint) {m_timePoint = timePoint;}
280 :
281 : /// returns the current time point
282 : size_t time_point() {return m_timePoint;}
283 :
284 : /// get the current evaluation time
285 0 : number time() const {return m_vTime[m_timePoint];}
286 :
287 : public:
288 : /// returns if data is constant
289 0 : virtual bool constant() const {return false;}
290 :
291 : /// number of other Data this data depends on
292 0 : virtual size_t num_needed_data() const {return 0;}
293 :
294 : /// return needed data
295 0 : virtual SmartPtr<ICplUserData> needed_data(size_t i) {return SPNULL;}
296 :
297 : /// compute values (and derivatives iff compDeriv == true)
298 : virtual void compute(LocalVector* u,
299 : GridObject* elem,
300 : const MathVector<dim> vCornerCoords[],
301 : bool bDeriv = false) = 0;
302 :
303 : /// compute values (and derivatives iff compDeriv == true, but only for the 'current' time point)
304 : virtual void compute(LocalVectorTimeSeries* u,
305 : GridObject* elem,
306 : const MathVector<dim> vCornerCoords[],
307 : bool bDeriv = false) = 0;
308 :
309 : /// returns if the dependent data is ready for evaluation
310 0 : virtual void check_setup() const {}
311 :
312 : /// virtual desctructor
313 0 : virtual ~ICplUserData() {};
314 :
315 : public:
316 : /// returns if data depends on solution
317 0 : virtual bool zero_derivative() const {return true;}
318 :
319 : /// resize arrays
320 0 : virtual void update_dof_sizes(const LocalIndices& ind) {}
321 :
322 : public:
323 : /// returns the number of ip series
324 : size_t num_series() const {return m_vNumIP.size();}
325 :
326 : /// returns the number of integration points
327 0 : size_t num_ip(size_t s) const {UG_ASSERT(s < num_series(), "Invalid series"); return m_vNumIP[s];}
328 :
329 : /// set local positions, returns series id
330 : /**
331 : * This method registers a local ip series. If the position of points may
332 : * change during computations, this can be specified.
333 : * IMPORTANT: the memory of the local ip values must remain valid until the
334 : * UserData is deleted.
335 : *
336 : * \returns size_t series id
337 : */
338 : template <int ldim>
339 : size_t register_local_ip_series(const MathVector<ldim>* vPos,
340 : const size_t numIP,
341 : const int timePointSpec,
342 : bool bMayChange = true);
343 :
344 : /// set local positions without the specification of the time point, returns series id
345 : template <int ldim>
346 : size_t register_local_ip_series(const MathVector<ldim>* vPos,
347 : const size_t numIP,
348 : bool bMayChange = true)
349 : {
350 : return this->template register_local_ip_series<ldim> (vPos, numIP, -1, bMayChange);
351 : };
352 :
353 : /// sets new local ip positions for a local ip series
354 : /**
355 : * This method set new local positions for an already registered ip series.
356 : * Of course this is only possible for a ip series with the bMayChange
357 : * flag set to true.
358 : */
359 : template <int ldim>
360 : void set_local_ips(const size_t seriesId, const MathVector<ldim>* vPos,
361 : const size_t numIP);
362 :
363 : /// sets a new time point for a local ip series
364 : /**
365 : * This method set a new time point for an already registered ip series.
366 : * Of course this is only possible for a ip series with the bMayChange
367 : * flag set to true.
368 : */
369 : void set_time_point(const size_t seriesId, const int timePointSpec);
370 :
371 : /// returns current local ip dimension
372 0 : int dim_local_ips() const {return m_locPosDim;}
373 :
374 : /// returns local ips
375 : template <int ldim>
376 : const MathVector<ldim>* local_ips(size_t s) const;
377 :
378 : /// returns local ip
379 : template <int ldim>
380 : const MathVector<ldim>& local_ip(size_t s, size_t ip) const;
381 :
382 : /// returns the time point specification (note: it may be -1, i.e. not specified)
383 : inline int time_point_specification(size_t s) const;
384 :
385 : /// returns the time point specification (in particular, the current one, if the own one not specified)
386 : inline size_t time_point(size_t s) const;
387 :
388 : /// get the specified evaluation time
389 0 : number time(size_t s) const {return m_vTime[time_point(s)];}
390 :
391 : /// returns true iff the time point specification is equal to the current one, or not specified
392 : inline bool at_current_time(size_t s) const;
393 :
394 : /// set global positions
395 : void set_global_ips(size_t s, const MathVector<dim>* vPos, size_t numIP);
396 :
397 : /// returns global ips
398 0 : const MathVector<dim>* ips(size_t s) const {check_s(s); return m_vvGlobPos[s];}
399 :
400 : /// returns global ip
401 0 : const MathVector<dim>& ip(size_t s, size_t ip) const{check_s_ip(s,ip); return m_vvGlobPos[s][ip];}
402 :
403 : protected:
404 : /// callback invoked after local ips have been added to the series
405 : /**
406 : * This callback is invoked when local ips have been added. It can
407 : * be used by derived classes to react on this fact, e.g. to forward the
408 : * local_ips or to adapt data field sizes.
409 : * Note: The number of series can only be increased and the number of ips
410 : * for a series can not be changed once set. This is important to
411 : * allow derived classes to only increase their data fields as well,
412 : * leaving accessing pointers invariant. If the local ip series must
413 : * be changed, this can only be done through a clear(), that will
414 : * invoke the local_ip_series_to_be_cleared() callback, and adding all local
415 : * series again.
416 : */
417 0 : virtual void local_ip_series_added(const size_t seriesID){m_vvGlobPos.resize(seriesID+1);}
418 :
419 : /// callback invoked, if a local ip series has been changed
420 : virtual void local_ips_changed(const size_t seriesID, const size_t newNumIP) = 0;
421 :
422 : /// callback invoked, when local ips are cleared
423 0 : virtual void local_ip_series_to_be_cleared() {m_vvGlobPos.clear();}
424 :
425 : /// callback invoked after global ips have been changed
426 : /**
427 : * This callback is invoked when the global ips have been changed. It can
428 : * be used by derived classes to react on this fact, e.g. to forward the
429 : * global_ips.
430 : */
431 0 : virtual void global_ips_changed(const size_t seriesID, const MathVector<dim>* vPos, const size_t numIP) {};
432 :
433 : /// checks in debug mode the correct usage of indices
434 : inline void check_s(size_t s) const;
435 :
436 : /// checks in debug mode the correct usage of indices
437 : inline void check_s_ip(size_t s, size_t ip) const;
438 :
439 : protected:
440 : /// help function to get local ips
441 0 : std::vector<const MathVector<1>*>& get_local_ips(Int2Type<1>) {return m_pvLocIP1d;}
442 0 : std::vector<const MathVector<2>*>& get_local_ips(Int2Type<2>) {return m_pvLocIP2d;}
443 0 : std::vector<const MathVector<3>*>& get_local_ips(Int2Type<3>) {return m_pvLocIP3d;}
444 : const std::vector<const MathVector<1>*>& get_local_ips(Int2Type<1>) const {return m_pvLocIP1d;}
445 : const std::vector<const MathVector<2>*>& get_local_ips(Int2Type<2>) const {return m_pvLocIP2d;}
446 : const std::vector<const MathVector<3>*>& get_local_ips(Int2Type<3>) const {return m_pvLocIP3d;}
447 :
448 : protected:
449 : /// flags if local ips may change
450 : std::vector<bool> m_vMayChange;
451 :
452 : /// number of evaluation points (-1 indicates no ips set)
453 : std::vector<size_t> m_vNumIP;
454 :
455 : /// dimension of local position (-1 indicates no dim set)
456 : int m_locPosDim;
457 :
458 : /// local ips of dimension 1d-3d
459 : std::vector<const MathVector<1>*> m_pvLocIP1d;
460 : std::vector<const MathVector<2>*> m_pvLocIP2d;
461 : std::vector<const MathVector<3>*> m_pvLocIP3d;
462 :
463 : /// time points for the series
464 : std::vector<int> m_vTimePoint;
465 :
466 : /// global ips
467 : std::vector<const MathVector<dim>*> m_vvGlobPos;
468 :
469 : /// time for evaluation
470 : std::vector<number> m_vTime;
471 :
472 : /// current time point (used if no explicit specification for series)
473 : size_t m_timePoint;
474 :
475 : /// default time point (or -1 if not specified)
476 : int m_defaultTimePoint;
477 :
478 : /// subset for evaluation
479 : int m_si;
480 : };
481 :
482 : ////////////////////////////////////////////////////////////////////////////////
483 : // UserData
484 : ////////////////////////////////////////////////////////////////////////////////
485 :
486 : // predeclaration
487 : template <typename TData, int dim> class DataImport;
488 :
489 : /// Type based UserData
490 : /**
491 : * This class is the base class for all integration point data for a templated
492 : * type. It provides the access to the data and handles the global integration
493 : * points.
494 : *
495 : * \tparam TData Data
496 : * \tparam dim world dimension
497 : * \tparam TRet Type of return flag (bool or void)
498 : */
499 : template <typename TData, int dim, typename TRet = void>
500 : class CplUserData : public ICplUserData<dim>, public UserData<TData,dim,TRet>
501 : {
502 : public:
503 : /// type of base class
504 : typedef ICplUserData<dim> base_type;
505 :
506 : /// explicitly forward some functions
507 : using base_type::num_series;
508 : using base_type::num_ip;
509 :
510 : public:
511 : /// returns the value at ip
512 : const TData& value(size_t s, size_t ip) const
513 : {check_series_ip(s,ip); return m_vvValue[s][ip];}
514 :
515 : /// returns all values for a series
516 : const TData* values(size_t s) const
517 : {
518 : check_series(s);
519 0 : if(m_vvValue[s].empty())
520 0 : return NULL;
521 : return &(m_vvValue[s][0]);
522 : }
523 :
524 : /// returns the value at ip
525 : TData& value(size_t s, size_t ip)
526 : {check_series_ip(s,ip);return m_vvValue[s][ip];}
527 :
528 : /// returns all values for a series
529 : TData* values(size_t s)
530 : {
531 : check_series(s);
532 0 : if(m_vvValue[s].empty())
533 0 : return NULL;
534 : return &(m_vvValue[s][0]);
535 : }
536 :
537 : /// returns flag, if data is evaluated (for conditional data)
538 : bool defined(size_t s, size_t ip) const
539 : {check_series_ip(s,ip); return m_vvBoolFlag[s][ip];}
540 :
541 : /// destructor
542 0 : ~CplUserData() {local_ip_series_to_be_cleared();}
543 :
544 : /// register external callback, invoked when data storage changed
545 : void register_storage_callback(DataImport<TData,dim>* obj, void (DataImport<TData,dim>::*func)());
546 :
547 : /// register all callbacks registered by class
548 : void unregister_storage_callback(DataImport<TData,dim>* obj);
549 :
550 : protected:
551 : /// checks in debug mode the correct index
552 : inline void check_series(size_t s) const;
553 :
554 : /// checks in debug mode the correct index
555 : inline void check_series_ip(size_t s, size_t ip) const;
556 :
557 : /// resizes the data field, when local ip changed signaled
558 : virtual void local_ip_series_added(const size_t seriesID);
559 :
560 : /// free the data field memory and set series to zero
561 : virtual void local_ip_series_to_be_cleared();
562 :
563 : /// implement callback, called when local IPs changed
564 : virtual void local_ips_changed(const size_t seriesID, const size_t newNumIP);
565 :
566 : /// callback, invoked when storage of data has changed for a series
567 0 : virtual void value_storage_changed(const size_t seriesID) {}
568 :
569 : /// calls are registered external storage callbacks
570 : void call_storage_callback() const;
571 :
572 : private:
573 : /// data at ip (size: (0,...num_series-1) x (0,...,num_ip-1))
574 : std::vector<std::vector<TData> > m_vvValue;
575 :
576 : /// bool flag at ip (size: (0,...num_series-1) x (0,...,num_ip-1))
577 : std::vector<std::vector<bool> > m_vvBoolFlag;
578 :
579 : /// registered callbacks
580 : // typedef void (DataImport<TData,dim>::*CallbackFct)();
581 : typedef boost::function<void ()> CallbackFct;
582 : std::vector<std::pair<DataImport<TData,dim>*, CallbackFct> > m_vCallback;
583 :
584 : };
585 :
586 : ////////////////////////////////////////////////////////////////////////////////
587 : // Dependent UserData
588 : ////////////////////////////////////////////////////////////////////////////////
589 :
590 : /// Dependent UserData
591 : /**
592 : * This class extends the UserData by the derivatives of the data w.r.t. to
593 : * unknown solutions.
594 : */
595 : template <typename TData, int dim>
596 : class DependentUserData : public CplUserData<TData, dim>
597 : {
598 : public:
599 : /// Base class type
600 : typedef CplUserData<TData, dim> base_type;
601 :
602 : // explicitly forward methods of ICplUserData
603 : using base_type::num_series;
604 : using base_type::num_ip;
605 : using base_type::local_ips;
606 :
607 : public:
608 : /// default constructor
609 0 : DependentUserData() {}
610 :
611 : /// sets the associated symbolic functions
612 : /// \{
613 : DependentUserData(const char* symbFct) {set_functions(symbFct);}
614 : DependentUserData(const std::string& symbFct) {set_functions(symbFct);}
615 : DependentUserData(const std::vector<std::string>& symbFct) {set_functions(symbFct);}
616 : /// \}
617 :
618 : public:
619 : /// number of shapes for local function
620 : size_t num_sh(size_t fct) const
621 : {
622 : UG_ASSERT(fct < m_vvNumDoFPerFct.size(), "Wrong index");
623 0 : return m_vvNumDoFPerFct[fct];
624 : }
625 :
626 : /// returns the derivative of the local function, at ip and for a dof
627 : const TData& deriv(size_t s, size_t ip, size_t fct, size_t dof) const
628 : {check_s_ip_fct_dof(s,ip,fct,dof);return m_vvvvDeriv[s][ip][fct][dof];}
629 :
630 : /// returns the derivative of the local function, at ip and for a dof
631 : TData& deriv(size_t s, size_t ip, size_t fct, size_t dof)
632 : {check_s_ip_fct_dof(s,ip,fct,dof);return m_vvvvDeriv[s][ip][fct][dof];}
633 :
634 : /// returns the derivatives of the local function, at ip
635 : TData* deriv(size_t s, size_t ip, size_t fct)
636 : {check_s_ip_fct(s,ip,fct);return &(m_vvvvDeriv[s][ip][fct][0]);}
637 :
638 : /// returns the derivatives of the local function, at ip
639 : const TData* deriv(size_t s, size_t ip, size_t fct) const
640 : {check_s_ip_fct(s,ip,fct);return &(m_vvvvDeriv[s][ip][fct][0]);}
641 :
642 : /// sets all derivative values to zero
643 : static void set_zero(std::vector<std::vector<TData> > vvvDeriv[], const size_t nip);
644 :
645 : public:
646 : /// returns that data depends on solution
647 0 : virtual bool zero_derivative() const {return false;}
648 :
649 : /// returns if grid function is needed for evaluation
650 0 : virtual bool requires_grid_fct() const {return true;}
651 :
652 : /// resize lin defect arrays
653 : virtual void update_dof_sizes(const LocalIndices& ind);
654 :
655 : /// sets the associated function pattern
656 : virtual void set_function_pattern(ConstSmartPtr<FunctionPattern> fctPatt);
657 :
658 : /// sets the associated symbolic functions
659 : /// \{
660 : void set_functions(const char* symbFct);
661 : void set_functions(const std::string& symbFct);
662 : void set_functions(const std::vector<std::string>& symbFct);
663 : /// \}
664 :
665 : protected:
666 : /// extracts the function group
667 : void extract_fct_grp();
668 :
669 : protected:
670 : /// string of symbolic functions required
671 : std::vector<std::string> m_SymbFct;
672 :
673 : protected:
674 : /// checks in debug mode the correct usage of indices
675 : inline void check_s_ip(size_t s, size_t ip) const;
676 :
677 : /// checks in debug mode the correct usage of indices
678 : inline void check_s_ip_fct(size_t s, size_t ip, size_t fct) const;
679 :
680 : /// checks in debug mode the correct usage of indices
681 : inline void check_s_ip_fct_dof(size_t s, size_t ip, size_t fct, size_t dof) const;
682 :
683 : /// resizes the derivative field when local ip change is signaled
684 : virtual void local_ip_series_added(const size_t seriesID);
685 :
686 : /// implement callback, called when local IPs changed
687 : virtual void local_ips_changed(const size_t seriesID, const size_t newNumIP);
688 :
689 : /// implement callback, invoked when local ips are cleared
690 : virtual void local_ip_series_to_be_cleared();
691 :
692 : /// resizes the derivative arrays for current number of ips.
693 : void resize_deriv_array();
694 :
695 : /// resizes the derivative arrays for current number of ips of a single series
696 : void resize_deriv_array(const size_t seriesID);
697 :
698 : protected:
699 : /// number of functions and their dofs
700 : std::vector<size_t> m_vvNumDoFPerFct;
701 :
702 : // Data (size: (0,...,num_series-1) x (0,...,num_ip-1) x (0,...,num_fct-1) x (0,...,num_sh(fct) )
703 : /// Derivatives
704 : std::vector<std::vector<std::vector<std::vector<TData> > > > m_vvvvDeriv;
705 : };
706 :
707 : } // end namespace ug
708 :
709 : //include implementation
710 : #include "user_data_impl.h"
711 :
712 : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__USER_DATA__ */
|