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