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