Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
point.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * Multiscale Universal Interface Code Coupling Library *
3 * *
4 * Copyright (C) 2019 Y. H. Tang, S. Kudo, X. Bian, Z. Li, G. E. Karniadakis *
5 * *
6 * This software is jointly licensed under the Apache License, Version 2.0 *
7 * and the GNU General Public License version 3, you may use it according *
8 * to either. *
9 * *
10 * ** Apache License, version 2.0 ** *
11 * *
12 * Licensed under the Apache License, Version 2.0 (the "License"); *
13 * you may not use this file except in compliance with the License. *
14 * You may obtain a copy of the License at *
15 * *
16 * http://www.apache.org/licenses/LICENSE-2.0 *
17 * *
18 * Unless required by applicable law or agreed to in writing, software *
19 * distributed under the License is distributed on an "AS IS" BASIS, *
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
21 * See the License for the specific language governing permissions and *
22 * limitations under the License. *
23 * *
24 * ** GNU General Public License, version 3 ** *
25 * *
26 * This program is free software: you can redistribute it and/or modify *
27 * it under the terms of the GNU General Public License as published by *
28 * the Free Software Foundation, either version 3 of the License, or *
29 * (at your option) any later version. *
30 * *
31 * This program is distributed in the hope that it will be useful, *
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
34 * GNU General Public License for more details. *
35 * *
36 * You should have received a copy of the GNU General Public License *
37 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
38 *****************************************************************************/
39 
51 #ifndef MUI_POINT_H_
52 #define MUI_POINT_H_
53 
54 #include<array>
55 #include<cmath>
56 #include<cassert>
57 
58 namespace mui {
59 
60 using uint = unsigned int;
61 using ulong = unsigned long;
62 
63 // error-checking helpers
64 template<typename T1, typename T2> struct same_type { static bool const yes = false; };
65 template<typename T> struct same_type<T,T> { static bool const yes = true; };
66 
67 
68 
69 /*---------------------------------------------------------------------------
70  Interface
71 ---------------------------------------------------------------------------*/
72 
73 template<class VEX, typename SCALAR, uint D>
74 struct vexpr {
75  using TYPE_ = SCALAR;
76  static const uint D_ = D;
77 
78  // the only work in constructor is type checking
79  inline vexpr() {
80  static_assert( same_type<TYPE_, typename VEX::TYPE_>::yes, "MUI Error [point.h]: Point element type mismatch" );
81  static_assert( D_ == VEX::D_, "MUI Error [point.h]: Point dimensionality mismatch" );
82  }
83 
84  // dereferencing using static polymorphism
85  inline SCALAR operator[] (uint i) const {
86  return static_cast<VEX const &>(*this)[i];
87  }
88 
89  inline operator VEX & () { return static_cast<VEX &>(*this); }
90  inline operator VEX const& () const { return static_cast<VEX const&>(*this); }
91 
92  inline uint d() const { return D_; }
93 };
94 
95 /*---------------------------------------------------------------------------
96  Container
97 ---------------------------------------------------------------------------*/
98 
99 template<typename SCALAR, uint D>
100 struct point : public vexpr<point<SCALAR,D>, SCALAR, D> {
101 protected:
102  SCALAR x[D];
103 public:
104  using TYPE_ = SCALAR;
105  static const uint D_ = D;
106 
107  // default constructor
108  inline point() {}
109  // construct from scalar constant
110  explicit inline point(float const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
111  explicit inline point(double const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
112  explicit inline point(int const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
113  explicit inline point(uint const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
114  explicit inline point(long const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
115  explicit inline point(ulong const s) { for(uint i = 0 ; i < D ; i++) x[i] = s; }
116  // construct from C-array
117  explicit inline point(float const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
118  explicit inline point(double const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
119  explicit inline point(int const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
120  explicit inline point(uint const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
121  explicit inline point(long const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
122  explicit inline point(ulong const *ps) { for(uint i = 0 ; i < D ; i++) x[i] = ps[i]; }
123  // construct from parameter pack
124  // 'head' differentiate it from constructing from vector expression
125  template<typename ...T> inline point(SCALAR const head, T const ... tail ) {
126  std::array<TYPE_,D_> s( { head, static_cast<SCALAR>(tail)... } );
127  for(uint i = 0 ; i < D ; i++) x[i] = s[i];
128  }
129  // construct from any vector expression
130  template<class E> inline point( const vexpr<E,SCALAR,D> &u ) {
131  for(uint i = 0 ; i < D ; i++) x[i] = u[i];
132  }
133 
134  // point must be assignable, while other expressions may not
135  inline SCALAR & operator [] (uint i) { assert( i < D ); return x[i]; }
136  inline SCALAR const& operator [] (uint i) const { assert( i < D ); return x[i]; }
137 
138  // STL-style direct data accessor
139  inline SCALAR * data() { return x; }
140  inline SCALAR const* data() const { return x; }
141 
142  // assign from any vector expression
143  template<class E> inline point & operator += ( const vexpr<E,SCALAR,D> &u ) {
144  for(uint i = 0 ; i < D ; i++) x[i] += u[i];
145  return *this;
146  }
147  template<class E> inline point & operator -= ( const vexpr<E,SCALAR,D> &u ) {
148  for(uint i = 0 ; i < D ; i++) x[i] -= u[i];
149  return *this;
150  }
151  template<class E> inline point & operator *= ( const vexpr<E,SCALAR,D> &u ) {
152  for(uint i = 0 ; i < D ; i++) x[i] *= u[i];
153  return *this;
154  }
155  template<class E> inline point & operator /= ( const vexpr<E,SCALAR,D> &u ) {
156  for(uint i = 0 ; i < D ; i++) x[i] /= u[i];
157  return *this;
158  }
159  // conventional vector-scalar operators
160  inline point & operator += ( SCALAR const u ) {
161  for(uint i = 0 ; i < D ; i++) x[i] += u;
162  return *this;
163  }
164  inline point & operator -= ( SCALAR const u ) {
165  for(uint i = 0 ; i < D ; i++) x[i] -= u;
166  return *this;
167  }
168  inline point & operator *= ( SCALAR const u ) {
169  for(uint i = 0 ; i < D ; i++) x[i] *= u;
170  return *this;
171  }
172  inline point & operator /= ( SCALAR const u ) {
173  for(uint i = 0 ; i < D ; i++) x[i] /= u;
174  return *this;
175  }
176 };
177 
178 /*---------------------------------------------------------------------------
179  Arithmetic Functors
180 ---------------------------------------------------------------------------*/
181 
182 template<class E1, class E2, typename SCALAR, uint D>
183 struct vexpr_add: public vexpr<vexpr_add<E1,E2,SCALAR,D>, SCALAR, D> {
184  inline vexpr_add( vexpr<E1,SCALAR,D> const& u, vexpr<E2,SCALAR,D> const& v ) : u_(u), v_(v) {}
185  inline SCALAR operator [] (uint i) const { return u_[i] + v_[i]; }
186 protected:
187  E1 const& u_;
188  E2 const& v_;
189 };
190 
191 template<class E1, class E2, typename SCALAR, uint D>
192 struct vexpr_sub: public vexpr<vexpr_sub<E1,E2,SCALAR,D>, SCALAR, D> {
193  inline vexpr_sub( vexpr<E1,SCALAR,D> const& u, vexpr<E2,SCALAR,D> const& v ) : u_(u), v_(v) {}
194  inline SCALAR operator [] (uint i) const { return u_[i] - v_[i]; }
195 protected:
196  E1 const& u_;
197  E2 const& v_;
198 };
199 
200 template<class E, typename SCALAR, uint D>
201 struct vexpr_neg: public vexpr<vexpr_neg<E,SCALAR,D>, SCALAR, D> {
202  inline vexpr_neg( vexpr<E,SCALAR,D> const& u ) : u_(u) {}
203  inline SCALAR operator [] (uint i) const { return -u_[i]; }
204 protected:
205  E const& u_;
206 };
207 
208 template<class E1, class E2, typename SCALAR, uint D>
209 struct vexpr_mul: public vexpr<vexpr_mul<E1,E2,SCALAR,D>, SCALAR, D> {
210  inline vexpr_mul( vexpr<E1,SCALAR,D> const& u, vexpr<E2,SCALAR,D> const& v ) : u_(u), v_(v) {}
211  inline SCALAR operator [] (uint i) const { return u_[i] * v_[i]; }
212 protected:
213  E1 const& u_;
214  E2 const& v_;
215 };
216 
217 template<class E, typename SCALAR, uint D>
218 struct vexpr_scale: public vexpr<vexpr_scale<E,SCALAR,D>, SCALAR, D> {
219  inline vexpr_scale( vexpr<E,SCALAR,D> const& u, SCALAR const a ) : u_(u), a_(a) {}
220  inline SCALAR operator [] (uint i) const { return u_[i] * a_; }
221 protected:
222  E const& u_;
223  SCALAR const a_;
224 };
225 
226 template<class E1, class E2, typename SCALAR, uint D>
227 struct vexpr_div: public vexpr<vexpr_div<E1,E2,SCALAR,D>, SCALAR, D> {
228  inline vexpr_div( vexpr<E1,SCALAR,D> const& u, vexpr<E2,SCALAR,D> const& v ) : u_(u), v_(v) {}
229  inline SCALAR operator [] (uint i) const { return u_[i] / v_[i]; }
230 protected:
231  E1 const& u_;
232  E2 const& v_;
233 };
234 
235 template<class E, typename SCALAR, uint D>
236 struct vexpr_rscale: public vexpr<vexpr_rscale<E,SCALAR,D>, SCALAR, D> {
237  inline vexpr_rscale( vexpr<E,SCALAR,D> const& u, SCALAR const a ) : u_(u), a_(a) {}
238  inline SCALAR operator [] (uint i) const { return u_[i] / a_; }
239 protected:
240  E const& u_;
241  SCALAR const a_;
242 };
243 
244 template<class E, typename SCALAR, uint D>
245 struct vexpr_rcp: public vexpr<vexpr_rcp<E,SCALAR,D>, SCALAR, D> {
246  inline vexpr_rcp( vexpr<E,SCALAR,D> const& u ) : u_(u) {}
247  inline SCALAR operator [] (uint i) const { return SCALAR(1)/u_[i]; }
248 protected:
249  E const& u_;
250 };
251 
252 template<class E, typename SCALAR, uint D>
253 struct vexpr_scale_rcp: public vexpr<vexpr_scale_rcp<E,SCALAR,D>, SCALAR, D> {
254  inline vexpr_scale_rcp( SCALAR const a, vexpr<E,SCALAR,D> const& u ) : a_(a), u_(u) {}
255  inline SCALAR operator [] (uint i) const { return a_ / u_[i]; }
256 protected:
257  SCALAR const a_;
258  E const& u_;
259 };
260 
261 template<class E, class OP, typename SCALAR, uint D>
262 struct vexpr_apply1: public vexpr<vexpr_apply1<E,OP,SCALAR,D>, SCALAR, D> {
263  inline vexpr_apply1( vexpr<E,SCALAR,D> const& u, OP const& op ) : u_(u), o_(op) {}
264  inline SCALAR operator [] (uint i) const { return o_( u_[i] ); }
265 protected:
266  E const& u_;
267  OP const& o_;
268 };
269 
270 template<class E1, class E2, class OP, typename SCALAR, uint D>
271 struct vexpr_apply2: public vexpr<vexpr_apply2<E1,E2,OP,SCALAR,D>, SCALAR, D> {
272  inline vexpr_apply2( vexpr<E1,SCALAR,D> const& u, vexpr<E2,SCALAR,D> const& v, OP const& op ) : u_(u), v_(v), o_(op) {}
273  inline SCALAR operator [] (uint i) const { return o_( u_[i], v_[i] ); }
274 protected:
275  E1 const& u_;
276  E2 const& v_;
277  OP const& o_;
278 };
279 
280 /*---------------------------------------------------------------------------
281  Operator Overloads
282 ---------------------------------------------------------------------------*/
283 
284 template<class E1, class E2, typename SCALAR, uint D> inline
286  return vexpr_add<E1, E2, SCALAR, D>( u, v );
287 }
288 
289 template<class E1, class E2, typename SCALAR, uint D> inline
291  return vexpr_sub<E1, E2, SCALAR, D>( u, v );
292 }
293 
294 template<class E, typename SCALAR, uint D> inline
296  return vexpr_neg<E, SCALAR, D>( u );
297 }
298 
299 template<class E1, class E2, typename SCALAR, uint D> inline
301  return vexpr_mul<E1, E2, SCALAR, D>( u, v );
302 }
303 
304 template<class E, typename SCALAR, uint D> inline
306  return vexpr_scale<E, SCALAR, D>( u, a );
307 }
308 
309 template<class E, typename SCALAR, uint D> inline
311  return vexpr_scale<E, SCALAR, D>( u, a );
312 }
313 
314 template<class E, typename SCALAR, uint D> inline
316  return vexpr_rscale<E, SCALAR, D>( u, a );
317 }
318 
319 template<class E1, class E2, typename SCALAR, uint D> inline
321  return vexpr_div<E1, E2, SCALAR, D>( u, v );
322 }
323 
324 template<class E, typename SCALAR, uint D> inline
326  return vexpr_scale_rcp<E, SCALAR, D>( a, u );
327 }
328 
329 /*---------------------------------------------------------------------------
330  Math functions
331 ---------------------------------------------------------------------------*/
332 
333 template<class E1, class E2, typename SCALAR> inline
336  for(uint i=0;i<3;i++) x[i] = u[(i+1U)%3U] * v[(i+2U)%3U] - u[(i+2U)%3U] * v[(i+1U)%3U];
337  return x;
338 }
339 
340 // generic reduction template
341 template<class E, class OP, typename SCALAR, uint D> inline
342 SCALAR reduce( vexpr<E,SCALAR,D> const &u, OP const & op ) {
343  SCALAR core( u[0] );
344  for(uint i = 1 ; i < D ; i++) core = op( core, u[i] );
345  return core;
346 }
347 
348 // biggest element within a vector
349 template<class E, typename SCALAR, uint D> inline
350 SCALAR max( vexpr<E,SCALAR,D> const &u ) {
351  return reduce( u, [](SCALAR a, SCALAR b){return a>b?a:b;} );
352 }
353 
354 // smallest element within a vector
355 template<class E, typename SCALAR, uint D> inline
356 SCALAR min( vexpr<E,SCALAR,D> const &u ) {
357  return reduce( u, [](SCALAR a, SCALAR b){return a<b?a:b;} );
358 }
359 
360 // smallest element within a vector
361 template<class E, typename SCALAR, uint D> inline
362 SCALAR sum( vexpr<E,SCALAR,D> const &u ) {
363  return reduce( u, [](SCALAR a, SCALAR b){return a+b;} );
364 }
365 
366 // smallest element within a vector
367 template<class E, typename SCALAR, uint D> inline
368 SCALAR mean( vexpr<E,SCALAR,D> const &u ) {
369  return sum(u) / double(D);
370 }
371 
372 // inner product
373 template<class E1, class E2, typename SCALAR, uint D> inline
374 SCALAR dot( vexpr<E1,SCALAR,D> const &u, vexpr<E2,SCALAR,D> const &v ) {
375  return sum( u * v );
376 }
377 
378 // square of L2 norm
379 template<class E, typename SCALAR, uint D> inline
380 SCALAR normsq( vexpr<E,SCALAR,D> const &u ) {
381  return sum( u * u );
382 }
383 
384 // L2 norm
385 template<class E, typename SCALAR, uint D> inline
386 SCALAR norm( vexpr<E,SCALAR,D> const &u ) {
387  return std::sqrt( normsq(u) );
388 }
389 
390 // element-wise arbitrary function applied for each element
391 template<class E, class OP, typename SCALAR, uint D> inline
393  return vexpr_apply1<E, OP, SCALAR, D>( u, op );
394 }
395 
396 // element-wise arbitrary function applied element-wisely between 2 vectors
397 template<class E1, class E2, class OP, typename SCALAR, uint D> inline
399  return vexpr_apply2<E1, E2, OP, SCALAR, D>( u, v, op );
400 }
401 
402 }
403 
404 #endif /* POINT_H_ */
T
Definition: dim.h:363
Definition: comm.h:54
SCALAR dot(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:374
point< SCALAR, 3U > cross(vexpr< E1, SCALAR, 3U > const &u, vexpr< E2, SCALAR, 3U > const &v)
Definition: point.h:334
vexpr_sub< E1, E2, SCALAR, D > operator-(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:290
vexpr_scale< E, SCALAR, D > operator/(vexpr< E, SCALAR, D > const &u, SCALAR const a)
Definition: point.h:315
SCALAR reduce(vexpr< E, SCALAR, D > const &u, OP const &op)
Definition: point.h:342
vexpr_add< E1, E2, SCALAR, D > operator+(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:285
unsigned long ulong
Definition: point.h:61
SCALAR sum(vexpr< E, SCALAR, D > const &u)
Definition: point.h:362
vexpr_mul< E1, E2, SCALAR, D > operator*(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:300
SCALAR mean(vexpr< E, SCALAR, D > const &u)
Definition: point.h:368
SCALAR max(vexpr< E, SCALAR, D > const &u)
Definition: point.h:350
unsigned int uint
Definition: util.h:94
SCALAR normsq(vexpr< E, SCALAR, D > const &u)
Definition: point.h:380
vexpr_apply1< E, OP, SCALAR, D > apply(vexpr< E, SCALAR, D > const &u, OP const &op)
Definition: point.h:392
SCALAR min(vexpr< E, SCALAR, D > const &u)
Definition: point.h:356
SCALAR norm(vexpr< E, SCALAR, D > const &u)
Definition: point.h:386
Definition: point.h:100
SCALAR const * data() const
Definition: point.h:140
point(const vexpr< E, SCALAR, D > &u)
Definition: point.h:130
point(int const *ps)
Definition: point.h:119
point & operator+=(const vexpr< E, SCALAR, D > &u)
Definition: point.h:143
point(ulong const *ps)
Definition: point.h:122
point(int const s)
Definition: point.h:112
point & operator-=(const vexpr< E, SCALAR, D > &u)
Definition: point.h:147
static const uint D_
Definition: point.h:105
point(float const *ps)
Definition: point.h:117
SCALAR TYPE_
Definition: point.h:104
SCALAR x[D]
Definition: point.h:102
SCALAR & operator[](uint i)
Definition: point.h:135
point()
Definition: point.h:108
point(float const s)
Definition: point.h:110
point(uint const *ps)
Definition: point.h:120
point & operator*=(const vexpr< E, SCALAR, D > &u)
Definition: point.h:151
point(double const *ps)
Definition: point.h:118
SCALAR * data()
Definition: point.h:139
point(double const s)
Definition: point.h:111
point(long const s)
Definition: point.h:114
point(uint const s)
Definition: point.h:113
point(long const *ps)
Definition: point.h:121
point(SCALAR const head, T const ... tail)
Definition: point.h:125
point & operator/=(const vexpr< E, SCALAR, D > &u)
Definition: point.h:155
point(ulong const s)
Definition: point.h:115
Definition: point.h:64
static bool const yes
Definition: point.h:64
Definition: point.h:183
SCALAR operator[](uint i) const
Definition: point.h:185
E2 const & v_
Definition: point.h:188
E1 const & u_
Definition: point.h:187
vexpr_add(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:184
Definition: point.h:262
E const & u_
Definition: point.h:266
vexpr_apply1(vexpr< E, SCALAR, D > const &u, OP const &op)
Definition: point.h:263
SCALAR operator[](uint i) const
Definition: point.h:264
OP const & o_
Definition: point.h:267
Definition: point.h:271
SCALAR operator[](uint i) const
Definition: point.h:273
E2 const & v_
Definition: point.h:276
vexpr_apply2(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v, OP const &op)
Definition: point.h:272
OP const & o_
Definition: point.h:277
E1 const & u_
Definition: point.h:275
Definition: point.h:227
SCALAR operator[](uint i) const
Definition: point.h:229
E1 const & u_
Definition: point.h:231
E2 const & v_
Definition: point.h:232
vexpr_div(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:228
Definition: point.h:209
E1 const & u_
Definition: point.h:213
E2 const & v_
Definition: point.h:214
SCALAR operator[](uint i) const
Definition: point.h:211
vexpr_mul(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:210
Definition: point.h:201
E const & u_
Definition: point.h:205
vexpr_neg(vexpr< E, SCALAR, D > const &u)
Definition: point.h:202
SCALAR operator[](uint i) const
Definition: point.h:203
Definition: point.h:245
vexpr_rcp(vexpr< E, SCALAR, D > const &u)
Definition: point.h:246
E const & u_
Definition: point.h:249
SCALAR operator[](uint i) const
Definition: point.h:247
Definition: point.h:236
SCALAR const a_
Definition: point.h:241
SCALAR operator[](uint i) const
Definition: point.h:238
E const & u_
Definition: point.h:240
vexpr_rscale(vexpr< E, SCALAR, D > const &u, SCALAR const a)
Definition: point.h:237
Definition: point.h:253
SCALAR operator[](uint i) const
Definition: point.h:255
E const & u_
Definition: point.h:258
vexpr_scale_rcp(SCALAR const a, vexpr< E, SCALAR, D > const &u)
Definition: point.h:254
SCALAR const a_
Definition: point.h:257
Definition: point.h:218
SCALAR const a_
Definition: point.h:223
vexpr_scale(vexpr< E, SCALAR, D > const &u, SCALAR const a)
Definition: point.h:219
E const & u_
Definition: point.h:222
SCALAR operator[](uint i) const
Definition: point.h:220
Definition: point.h:192
E1 const & u_
Definition: point.h:196
SCALAR operator[](uint i) const
Definition: point.h:194
E2 const & v_
Definition: point.h:197
vexpr_sub(vexpr< E1, SCALAR, D > const &u, vexpr< E2, SCALAR, D > const &v)
Definition: point.h:193
Definition: point.h:74
SCALAR TYPE_
Definition: point.h:75
SCALAR operator[](uint i) const
Definition: point.h:85
vexpr()
Definition: point.h:79
uint d() const
Definition: point.h:92
static const uint D_
Definition: point.h:76