Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
dim.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 
47 #ifndef DIM_H_
48 #define DIM_H_
49 
50 #include "util.h"
51 
52 namespace mui {
53 
54 namespace dim {
55 
56 /******************************************************************************
57  Documentation
58 ******************************************************************************/
59 
60 // using namespace dim;
61 // using namespace dim::mechanical;
62 // using namespace dim::electrical;
63 // using namespace dim::magnetic;
64 // using namespace dim::optical;
65 // using namespace dim::radioactive;
66 // using namespace dim::chemical;
67 
68 /******************************************************************************
69  Base class
70 ******************************************************************************/
71 
72 // MUI convention:
73 // [M]ass
74 // [L]ength
75 // [T]ime
76 // [T]emperature
77 // [A]mount of substance
78 // [E]lectrical current
79 // [L]uminos intensity
80 // amount of [I]nformation
81 
82 template<int... MLTTAELI>
83 struct dim
84 {
85  double a; // prefactor
86  inline dim() : a(0) {}
87  inline dim( double _a_ ) : a(_a_) {}
88  inline dim( const dim &other ) : a(other.a) {}
89  template<int... ANOTHER_MLTTAELI> dim( const dim<ANOTHER_MLTTAELI...> &error ) {
90  error.Cannot_Assign_Quantities_With_Incompatible_Dimensionalities;
91  }
92 
93  // copy-assign
94  inline dim& operator = ( const dim &other ) { a = other.a; return *this; }
95  template<int... ANOTHER_MLTTAELI>
96  class Cannot_Assign_Quantities_With_Incompatible_Dimensionalities
97  operator = ( const dim<ANOTHER_MLTTAELI...> &other );
98 
99  // get numeric value
100  inline operator double () { return a; }
101 
102  // conversion
103  inline dim convert_to( const dim &other ) {
104  return dim( a / other.a );
105  }
106  template<int... ANOTHER_MLTTAELI>
107  class Cannot_Assign_Quantities_With_Incompatible_Dimensionalities
108  convert_to( const dim<ANOTHER_MLTTAELI...> &other );
109 
110  // serialization
111  friend inline ostream& operator << ( ostream &out, dim q ) {
112  out << q.a;
113  return out;
114  }
115  friend inline istream& operator >> ( istream &in, dim q ) {
116  in >> q.a;
117  return in;
118  }
119 };
120 
121 /******************************************************************************
122  Arithmetic
123 ******************************************************************************/
124 
125 // addition
126 template<int... MLTTAELI1, int... MLTTAELI2> inline
127 class Cannot_Add_Values_With_Mismatching_Dimensionality operator + ( const dim<MLTTAELI1...> &d1, const dim<MLTTAELI2...> &d2 );
128 
129 template<int... MLTTAELI> inline
130 dim<MLTTAELI...> operator + ( const dim<MLTTAELI...> &d1, const dim<MLTTAELI...> &d2 ) {
131  return dim<MLTTAELI...>( d1.a + d2.a );
132 }
133 
134 // negate
135 template<int... MLTTAELI> inline
136 dim<MLTTAELI...> operator - ( const dim<MLTTAELI...> &d ) {
137  return dim<MLTTAELI...>( -d.a );
138 }
139 
140 // substraction
141 template<int... MLTTAELI1, int... MLTTAELI2> inline
142 class Cannot_Subtract_Values_With_Mismatching_Dimensionality operator - ( const dim<MLTTAELI1...> &d1, const dim<MLTTAELI2...> &d2 );
143 
144 template<int... MLTTAELI> inline
145 dim<MLTTAELI...> operator - ( const dim<MLTTAELI...> &d1, const dim<MLTTAELI...> &d2 ) {
146  return dim<MLTTAELI...>( d1.a - d2.a );
147 }
148 
149 // multiplication
150 // case 0: all dimensions cancel, result is scalar
151 template<int... MLTTAELI> inline
152 double operator * ( const dim<MLTTAELI...> &u1, const dim<-MLTTAELI...> &u2 ) {
153  return u1.a * u2.a;
154 }
155 // case 1: result in something with new dimensionality
156 template<int... MLTTAELI1, int... MLTTAELI2> inline
157 dim<(MLTTAELI1+MLTTAELI2)...> operator * ( const dim<MLTTAELI1...> &u1, const dim<MLTTAELI2...> &u2 ) {
158  dim<(MLTTAELI1+MLTTAELI2)...> u;
159  u.a = u1.a * u2.a;
160  return u;
161 }
162 
163 // multiply by constant
164 template<int... MLTTAELI> inline
165 dim<MLTTAELI...> operator * ( const dim<MLTTAELI...> &u, const double f ) {
166  return dim<MLTTAELI...>( u.a * f );
167 }
168 template<int... MLTTAELI> inline
169 dim<MLTTAELI...> operator * ( const double f, const dim<MLTTAELI...> &u ) {
170  return dim<MLTTAELI...>( u.a * f );
171 }
172 
173 // division
174 // case 0: all dimensions cancel, result is scalar
175 template<int... MLTTAELI> inline
176 double operator / ( const dim<MLTTAELI...> &u1, const dim<MLTTAELI...> &u2 ) {
177  return u1.a / u2.a;
178 }
179 // case 1: result in something with new dimensionality
180 template<int... MLTTAELI1, int... MLTTAELI2> inline
181 dim<(MLTTAELI1-MLTTAELI2)...> operator / ( const dim<MLTTAELI1...> &u1, const dim<MLTTAELI2...> &u2 ) {
182  dim<(MLTTAELI1-MLTTAELI2)...> u;
183  u.a = u1.a / u2.a;
184  return u;
185 }
186 
187 // divide by constant
188 template<int... MLTTAELI> inline
189 dim<MLTTAELI...> operator / ( const dim<MLTTAELI...> &u, const double f ) {
190  return u * (1.0/f);
191 }
192 
193 // inversion
194 template<int... MLTTAELI> inline
195 dim<-MLTTAELI...> operator / ( const double f, const dim<MLTTAELI...> &u ) {
196  return dim<-MLTTAELI...>( f / u.a );
197 }
198 
199 /******************************************************************************
200  Dimensions
201 ******************************************************************************/
202 
203 // Fundamental dimensions
204 // M L T T A E L I
213 
214 // Derived dimensions - General
215 using angle = decltype( length() / length() );
216 using area = decltype( length() * length() );
217 using frequency = decltype( 1.0 / time() );
218 using velocity = decltype( length() / time() );
219 using acceleration= decltype( velocity() / time() );
220 using force = decltype( mass() * acceleration() );
221 using pressure = decltype( force() / area() );
222 using energy = decltype( force() * length() );
223 using solid_angle = decltype( area() / area() );
224 using power = decltype( energy() / time() );
225 
226 // Derived dimensions - By discipline
227 namespace mechanical {
228 }
229 namespace electrical {
230  using charge = decltype( current() * time() );
231  using voltage = decltype( power() / current() );
232  using capacitance = decltype( charge() / voltage() );
233  using resistance = decltype( voltage() / current() );
234  using conductance = decltype( current() / voltage() );
235 }
236 namespace magnetic {
237  using electrical::voltage;
238  using flux = decltype( voltage() * time() );
239  using strength = decltype( flux() / area() );
240  using inductance = decltype( flux() / current() );
241 }
242 namespace optical {
243  using flux = decltype( luminos() * solid_angle() );
244  using illuminance = decltype( flux() / area() );
245 }
246 namespace radioactive {
247  using activity = decltype( 1.0 / time() );
248  using dose = decltype( energy() / mass() );
249 }
250 namespace chemical {
251  using catativity = decltype( amount() / time() );
252 }
253 
254 /******************************************************************************
255  Units
256 ******************************************************************************/
257 
258 // Example
259 inline angle operator "" _deg ( long double u ) {
260  return angle( u * ( PI / 360.0 ) );
261 }
262 inline angle operator "" _deg ( unsigned long long u ) {
263  return angle( u * ( PI / 360.0 ) );
264 }
265 
266 // Short-hand macro
267 #define make_unit(dimension,suffix,conversion) \
268  inline dimension operator "" _##suffix ( long double u ) { \
269  return dimension( conversion ); \
270  } \
271  inline dimension operator "" _##suffix ( unsigned long long u ) { \
272  return dimension( conversion ); \
273  }
274 
275 // Fundamental units
276 make_unit(mass,ton,u*1e3)
278 make_unit(mass,g,u*1e-3)
280 make_unit(length,km,u*1e3)
286 make_unit(length,Angstrom,u*1e-10)
287 make_unit(time,day,u*86400.0)
288 make_unit(time,hr,u*3600.0)
292 make_unit(time,us,u*1e-6)
294 make_unit(time,ps,u*1e-12)
298 make_unit(amount,mol,u*6.02214178999999989284864e23)
300 make_unit(current,mAmp,u*1e-3)
302 make_unit(information,bit,u*0.125)
310 
311 // Derived dimensions - General
314 make_unit(velocity,kmph,u*(1000.0/3600.0))
316 make_unit(force,kN,u*1e3)
318 make_unit(force,mN,u*1e-3)
320 make_unit(force,nN,u*1e-9)
322 make_unit(pressure,GPa,u*1e9)
324 make_unit(pressure,kPa,u*1e3)
326 make_unit(energy,GJ,u*1e9)
328 make_unit(energy,kJ,u*1e3)
334 make_unit(energy,eV,u*1.602176565e-19)
336 make_unit(power,MW,u*1e6)
340 make_unit(power,uW,u*1e-6)
341 
342 // Derived dimensions - By discipline
343 namespace mechanical {
344 }
345 namespace electrical {
347  make_unit(charge,e,u*1.60217648700000002946104e-19)
348  make_unit(voltage,kV,u*1e3)
350  make_unit(voltage,mV,u*1e-3)
356  make_unit(resistance,Mohm,u*1e6)
360 }
361 namespace magnetic {
364  make_unit(inductance,H,u)
365 }
366 namespace optical {
369 }
370 namespace radioactive {
373  make_unit(dose,Sv,u)
374 }
375 namespace chemical {
376  make_unit(catativity,kat,u)
377 }
378 
379 #undef make_unit
380 
381 }
382 
383 }
384 
385 #endif /* DIM_H_ */
Definition: stream.h:61
Definition: stream.h:67
decltype(amount()/time()) catativity
Definition: dim.h:251
decltype(power()/current()) voltage
Definition: dim.h:231
u u u uF
Definition: dim.h:353
u u u u u kohm
Definition: dim.h:357
decltype(current()/voltage()) conductance
Definition: dim.h:234
u u u u pF
Definition: dim.h:355
u u u u u u S
Definition: dim.h:359
decltype(voltage()/current()) resistance
Definition: dim.h:233
e
Definition: dim.h:347
decltype(charge()/voltage()) capacitance
Definition: dim.h:232
make_unit(charge, C, u) make_unit(charge
u u F
Definition: dim.h:351
decltype(current() *time()) charge
Definition: dim.h:230
u V
Definition: dim.h:349
T
Definition: dim.h:363
decltype(flux()/current()) inductance
Definition: dim.h:240
decltype(flux()/area()) strength
Definition: dim.h:239
decltype(voltage() *time()) flux
Definition: dim.h:238
decltype(flux()/area()) illuminance
Definition: dim.h:244
decltype(luminos() *solid_angle()) flux
Definition: dim.h:243
lux
Definition: dim.h:368
decltype(energy()/mass()) dose
Definition: dim.h:248
decltype(1.0/time()) activity
Definition: dim.h:247
Gy
Definition: dim.h:372
decltype(force() *length()) energy
Definition: dim.h:222
dim< 0, 0, 0, 0, 1, 0, 0, 0 > amount
Definition: dim.h:209
u u u u u u u u u fs
Definition: dim.h:295
decltype(energy()/time()) power
Definition: dim.h:224
u mg
Definition: dim.h:279
u u u u u day
Definition: dim.h:287
make_unit(mass, ton, u *1e3) make_unit(mass
u u u mm
Definition: dim.h:283
u u u u u u u u u u u u u u u u u u u u u u u u u u uJ
Definition: dim.h:331
u u u u u u u u u u u u u u u u u u u u uN
Definition: dim.h:319
u u u u u u u u u u u u u u u GB
Definition: dim.h:307
u u u u u u u u u u u u u u u u u u u u u u MPa
Definition: dim.h:323
decltype(area()/area()) solid_angle
Definition: dim.h:223
decltype(1.0/time()) frequency
Definition: dim.h:217
decltype(length()/time()) velocity
Definition: dim.h:218
u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u mW
Definition: dim.h:339
u u u u u u u u u u u u u u u u u u u u u u u u u u u u sr
Definition: dim.h:335
dim< 0, 0, 1, 0, 0, 0, 0, 0 > time
Definition: dim.h:207
class Cannot_Add_Values_With_Mismatching_Dimensionality operator+(const dim< MLTTAELI1... > &d1, const dim< MLTTAELI2... > &d2)
u u u u u u u ms
Definition: dim.h:291
u u u u u u min
Definition: dim.h:289
double operator/(const dim< MLTTAELI... > &u1, const dim< MLTTAELI... > &u2)
Definition: dim.h:176
u u u u u u u u u u u u u u u u PB
Definition: dim.h:309
u u u u nm
Definition: dim.h:285
u u u u u u u u u u u u u u u u u u u u u u u u u u u pJ
Definition: dim.h:333
decltype(mass() *acceleration()) force
Definition: dim.h:220
u u m
Definition: dim.h:281
decltype(force()/area()) pressure
Definition: dim.h:221
u u u u u u u u ns
Definition: dim.h:293
dim< 1, 0, 0, 0, 0, 0, 0, 0 > mass
Definition: dim.h:205
u u u u u u u u u u C
Definition: dim.h:297
u u u u u u u u u u u u u u KB
Definition: dim.h:305
decltype(length()/length()) angle
Definition: dim.h:215
dim< MLTTAELI... > operator-(const dim< MLTTAELI... > &d)
Definition: dim.h:136
u u u u u u u u u u u u u u u u u u u u u pN
Definition: dim.h:321
kg
Definition: dim.h:277
dim< 0, 0, 0, 0, 0, 0, 1, 0 > luminos
Definition: dim.h:211
u u u u u u u u u u u u u u u u u u u N
Definition: dim.h:317
u u u u u u u u u u u u u u u u u u u u u u u u u u u u u kW
Definition: dim.h:337
u u u u u u u u u u u u cd
Definition: dim.h:301
u u u u u u u u u u u u u u u u u u u u u u u Pa
Definition: dim.h:325
u u u u u u u u u u u u u u u u u u u u u u u u MJ
Definition: dim.h:327
u u u u u u u u u u u u u u u u u u G
Definition: dim.h:315
u u u u u u u u u u u Amp
Definition: dim.h:299
dim< 0, 0, 0, 0, 0, 1, 0, 0 > current
Definition: dim.h:210
u u u u u u u u u u u u u u u u u Hz
Definition: dim.h:313
dim< 0, 1, 0, 0, 0, 0, 0, 0 > length
Definition: dim.h:206
u u u u u u u u u u u u u u u u u u u u u u u u u J
Definition: dim.h:329
decltype(velocity()/time()) acceleration
Definition: dim.h:219
decltype(length() *length()) area
Definition: dim.h:216
u u u u u u u u u u u u u nibble
Definition: dim.h:303
double operator*(const dim< MLTTAELI... > &u1, const dim<-MLTTAELI... > &u2)
Definition: dim.h:152
Definition: comm.h:54
Definition: dim.h:84
friend ostream & operator<<(ostream &out, dim q)
Definition: dim.h:111
double a
Definition: dim.h:85
dim & operator=(const dim &other)
Definition: dim.h:94
dim(const dim &other)
Definition: dim.h:88
dim(double _a_)
Definition: dim.h:87
friend istream & operator>>(istream &in, dim q)
Definition: dim.h:115
dim convert_to(const dim &other)
Definition: dim.h:103
dim()
Definition: dim.h:86
dim(const dim< ANOTHER_MLTTAELI... > &error)
Definition: dim.h:89
Provides a number of utility functions used through the rest of the library.