Line data Source code
1 : /*
2 : * Copyright (c) 2019-2020: G-CSC, Goethe University Frankfurt
3 : * Author: Arne Naegel
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 __LIB_DISC__COMPOSITE_USER_DATA_H_
34 : #define __LIB_DISC__COMPOSITE_USER_DATA_H_
35 :
36 : #include <vector>
37 : #include <string>
38 :
39 : // UG4 headers
40 : #include "lib_grid/tools/subset_group.h"
41 : #include "lib_disc/spatial_disc/user_data/linker/linker.h"
42 :
43 : namespace ug{
44 :
45 : /// This is a compositum for user data defined on different subsets
46 : /**
47 : * This combines user data objects defined on several subsets which is handy,
48 : * but may be slow.
49 : */
50 : template <typename TData, int dim, typename TRet = void>
51 : class CompositeUserData : public UserData<TData, dim, TRet>
52 : {
53 : protected:
54 : typedef CplUserData<TData, dim, TRet> TCplUserData;
55 : public:
56 : typedef UserData<TData, dim, TRet> base_type;
57 : typedef SmartPtr<base_type> ref_type; ///< the attached UserData objects should have the same type as this class (i.e. they are "remapped")
58 :
59 0 : CompositeUserData() : m_bContinuous(true), m_bRequiresGridFunction(false) {}
60 :
61 0 : CompositeUserData(bool continuous) : m_bContinuous(continuous), m_bRequiresGridFunction(false) {}
62 :
63 0 : virtual ~CompositeUserData(){}
64 :
65 : /// Add 'UserData' object for given subset index.
66 0 : void add
67 : (
68 : int si, ///< the subset index
69 : SmartPtr<base_type> ref ///< pointer to the user-data object
70 : )
71 : {
72 : UG_ASSERT (si >= 0, "CompositeUserData: Non-existing subset index!");
73 :
74 0 : if ((size_t) si >= m_vData.size ())
75 0 : m_vData.resize (si + 1);
76 0 : m_vData[si] = ref;
77 :
78 : // UG_ASSERT(ref->continuous() == m_continuous, "CompositeUserData: Mixing continuous and discontinuous data!");
79 0 : m_bContinuous = m_bContinuous && ref->continuous();
80 0 : m_bRequiresGridFunction = m_bRequiresGridFunction || ref->requires_grid_fct();
81 0 : }
82 :
83 : /// Add 'UserData' object for all subsets in a given group
84 0 : void add
85 : (
86 : const SubsetGroup & ssg, ///< the subset group
87 : SmartPtr<base_type> ref ///< pointer to the user-data object
88 : )
89 : {
90 0 : for (size_t i = 0; i < ssg.size (); i++) add (ssg[i], ref);
91 0 : }
92 :
93 : /// Add 'UserData' object for all subsets by their names
94 0 : void add
95 : (
96 : ConstSmartPtr<ISubsetHandler> ssh, ///< subset handler of the domain
97 : const char * ss_names, ///< names of the subdomains
98 : SmartPtr<base_type> ref ///< pointer to the user-data object
99 : )
100 : {
101 : std::vector<std::string> v_ss_names;
102 0 : SubsetGroup ssg (ssh);
103 :
104 0 : TokenizeTrimString (std::string (ss_names), v_ss_names);
105 0 : ssg.add (v_ss_names);
106 0 : add (ssg, ref);
107 0 : }
108 :
109 : /// Checks if anything is assigned to a given subset index
110 0 : bool has(int si) const { return si >= 0 && (size_t) si < m_vData.size () && m_vData[si].valid ();}
111 :
112 0 : SmartPtr<base_type> get(int si) const { check (si); return m_vData[si]; }
113 :
114 0 : bool is_coupled(int si) { return has(si) && m_vData[si].template is_of_type<TCplUserData>(); }
115 :
116 0 : SmartPtr<TCplUserData> get_coupled(int si) { return m_vData[si].template cast_dynamic<TCplUserData>(); }
117 :
118 : // Implementing virtual functions
119 :
120 0 : virtual bool continuous() const {return m_bContinuous;}
121 :
122 : /// returns true, if at least one of the underlying UserData requires grid functions.
123 0 : virtual bool requires_grid_fct() const
124 : {
125 0 : return m_bRequiresGridFunction;
126 : }
127 :
128 : /// returns value for a global position
129 0 : virtual TRet operator() (TData& value,
130 : const MathVector<dim>& globIP,
131 : number time, int si) const
132 0 : { check (si); return (*m_vData[si]) (value, globIP, time, si); }
133 :
134 : /// returns values for global positions
135 0 : virtual void operator()(TData vValue[],
136 : const MathVector<dim> vGlobIP[],
137 : number time, int si, const size_t nip) const
138 0 : { check (si); return (*m_vData[si]) (vValue, vGlobIP, time, si, nip); }
139 :
140 :
141 0 : virtual void operator()(TData vValue[],
142 : const MathVector<dim> vGlobIP[],
143 : number time, int si,
144 : GridObject* elem,
145 : const MathVector<dim> vCornerCoords[],
146 : const MathVector<1> vLocIP[],
147 : const size_t nip,
148 : LocalVector* u,
149 : const MathMatrix<1, dim>* vJT = NULL) const
150 : {
151 0 : check (si); return (*m_vData[si]) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
152 : }
153 :
154 0 : virtual void operator()(TData vValue[],
155 : const MathVector<dim> vGlobIP[],
156 : number time, int si,
157 : GridObject* elem,
158 : const MathVector<dim> vCornerCoords[],
159 : const MathVector<2> vLocIP[],
160 : const size_t nip,
161 : LocalVector* u,
162 : const MathMatrix<2, dim>* vJT = NULL) const
163 : {
164 0 : check (si); return (*m_vData[si]) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
165 : }
166 :
167 0 : virtual void operator()(TData vValue[],
168 : const MathVector<dim> vGlobIP[],
169 : number time, int si,
170 : GridObject* elem,
171 : const MathVector<dim> vCornerCoords[],
172 : const MathVector<3> vLocIP[],
173 : const size_t nip,
174 : LocalVector* u,
175 : const MathMatrix<3, dim>* vJT = NULL) const
176 : {
177 0 : check (si); return (*m_vData[si]) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
178 : }
179 :
180 : private:
181 :
182 : // checks if the subset si is present in the list
183 0 : void check (int si) const
184 : {
185 : if (! has (si))
186 : {
187 0 : UG_THROW ("CompositeUserData: No data for subset " << si);
188 : }
189 0 : }
190 :
191 : private:
192 :
193 : std::vector<SmartPtr<base_type> > m_vData;
194 : bool m_bContinuous;
195 : bool m_bRequiresGridFunction;
196 : };
197 :
198 :
199 : } // namespace ug
200 :
201 : #endif /* __LIB_DISC__COMPOSITE_USER_DATA_H_ */
|