Line data Source code
1 : /*
2 : * Copyright (c) 2013-2022: G-CSC, Goethe University Frankfurt
3 : * Author: Dmitry Logashenko
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 : /*
34 : * A linker that cuts out values of a given userdata objection in some interval.
35 : */
36 : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__INTERVAL_LINKER__
37 : #define __H__UG__LIB_DISC__SPATIAL_DISC__INTERVAL_LINKER__
38 :
39 : /* ug4 headers */
40 : #include "common/common.h"
41 :
42 : #include "linker.h"
43 :
44 : namespace ug {
45 :
46 : /**
47 : * User data filtering out values of a given argument beyond a given interval. Out of the
48 : * interval, the return value is "def_val" (0 by default)
49 : */
50 : template <int dim>
51 : class IntervalNumberLinker
52 : : public StdDataLinker<IntervalNumberLinker<dim>, number, dim>
53 : {
54 : /// Base class type
55 : typedef StdDataLinker<IntervalNumberLinker<dim>, number, dim> base_type;
56 :
57 : public:
58 :
59 : /// Constructor
60 0 : IntervalNumberLinker
61 : (
62 : SmartPtr<CplUserData<number, dim> > spData, ///< data to filter
63 : MathVector<dim>& minCoord, ///< left boundaries of the interval
64 : MathVector<dim>& maxCoord ///< right boundaries of the interval
65 : )
66 0 : {
67 0 : init (spData, minCoord, maxCoord);
68 0 : }
69 :
70 : /// Constructor
71 0 : IntervalNumberLinker
72 : (
73 : SmartPtr<CplUserData<number, dim> > spData, ///< data to filter
74 : std::vector<number> min_coord, ///< left boundaries of the interval
75 : std::vector<number> max_coord ///< right boundaries of the interval
76 : )
77 0 : {
78 0 : if (min_coord.size () != dim || max_coord.size () != dim)
79 0 : UG_THROW ("IntervalNumberLinker: Illegal sizes of the boundar arrays!");
80 : MathVector<dim> minCoord, maxCoord;
81 0 : for (size_t i = 0; i < dim; i++)
82 : {
83 0 : minCoord[i] = min_coord[i]; maxCoord[i] = max_coord[i];
84 : }
85 :
86 0 : init (spData, minCoord, maxCoord);
87 0 : }
88 :
89 : /// sets the default values out of the interval
90 0 : void set_default (number v) {def_val = v;}
91 :
92 : /// Returns true because without a grid function, we do not get the element
93 0 : virtual bool requires_grid_fct() const {return true;}
94 :
95 : /// Evaluation for the global coordinates
96 0 : inline void evaluate
97 : (
98 : number& value,
99 : const MathVector<dim>& glob_ip,
100 : number time,
101 : int si
102 : ) const
103 : {
104 0 : if (is_in (glob_ip))
105 0 : (* m_spData) (value, glob_ip, time, si);
106 : else
107 0 : value = def_val;
108 0 : }
109 :
110 : /// Computation without the derivatives
111 : template <int refDim>
112 0 : inline void evaluate
113 : (
114 : number vValue[],
115 : const MathVector<dim> vGlobIP[],
116 : number time,
117 : int si,
118 : GridObject* elem,
119 : const MathVector<dim> vCornerCoords[],
120 : const MathVector<refDim> vLocIP[],
121 : const size_t nip,
122 : LocalVector* u,
123 : const MathMatrix<refDim, dim>* vJT = NULL
124 : ) const
125 : {
126 : // Compute all, then replace:
127 :
128 0 : (*m_spData) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
129 :
130 0 : for (size_t ip = 0; ip < nip; ip++)
131 0 : if (! is_in (vGlobIP[ip]))
132 0 : vValue[ip] = def_val;
133 0 : }
134 :
135 : /// Computation of the values and the derivatives
136 : template <int refDim>
137 0 : void eval_and_deriv
138 : (
139 : number vValue[],
140 : const MathVector<dim> vGlobIP[],
141 : number time,
142 : int si,
143 : GridObject* elem,
144 : const MathVector<dim> vCornerCoords[],
145 : const MathVector<refDim> vLocIP[],
146 : const size_t nip,
147 : LocalVector* u,
148 : bool bDeriv,
149 : int s,
150 : std::vector<std::vector<number> > vvvDeriv[],
151 : const MathMatrix<refDim, dim>* vJT = NULL
152 : ) const
153 : {
154 0 : if (this->zero_derivative ())
155 : bDeriv = false;
156 : else
157 0 : this->set_zero (vvvDeriv, nip);
158 :
159 0 : const number* vValues = m_spData->values (s);
160 :
161 0 : for (size_t ip = 0; ip < nip; ip++)
162 0 : if (is_in (vGlobIP[ip]))
163 : {
164 0 : vValue[ip] = vValues[ip];
165 0 : if (bDeriv)
166 0 : for (size_t fct = 0; fct < m_spDData->num_fct (); fct++)
167 : {
168 : const number* vDValues = m_spDData->deriv (s, ip, fct);
169 : const size_t c_fct = this->input_common_fct (0, fct);
170 0 : for (size_t sh = 0; sh < this->num_sh (c_fct); sh++)
171 0 : vvvDeriv[ip][c_fct][sh] = vDValues [sh];
172 : }
173 : }
174 : else
175 0 : vValue[ip] = def_val;
176 : // The derivatives are all initialized with 0.
177 0 : }
178 :
179 : private:
180 :
181 : /// a general initializer (to call from a constructor)
182 0 : void init
183 : (
184 : SmartPtr<CplUserData<number, dim> > spData, ///< data to filter
185 : MathVector<dim>& minCoord, ///< left boundaries of the interval
186 : MathVector<dim>& maxCoord ///< right boundaries of the interval
187 : )
188 : {
189 : this->set_num_input (1);
190 0 : m_spData = spData;
191 0 : m_spDData = spData.template cast_dynamic<DependentUserData<number, dim> > ();
192 0 : this->set_input (0, spData, spData);
193 : m_minCoord = minCoord; m_maxCoord = maxCoord;
194 :
195 0 : def_val = 0;
196 0 : }
197 :
198 : /// checks if the point is in the interval
199 : bool is_in
200 : (
201 : const MathVector<dim>& x // the point
202 : ) const
203 : {
204 0 : for (size_t i = 0; i < dim; i++)
205 0 : if (x[i] < m_minCoord[i] || x[i] > m_maxCoord[i])
206 : return false;
207 : return true;
208 : }
209 :
210 : /// data to filter
211 : SmartPtr<CplUserData<number, dim> > m_spData;
212 : SmartPtr<DependentUserData<number, dim> > m_spDData;
213 :
214 : /// the interval
215 : MathVector<dim> m_minCoord, m_maxCoord;
216 :
217 : // the default value
218 : number def_val;
219 : };
220 :
221 : } // end namespace ug
222 :
223 : #endif // __H__UG__LIB_DISC__SPATIAL_DISC__INTERVAL_LINKER__
224 :
225 : /* End of File */
|