1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
8 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef QMCPLUSPLUS_UNIT_CONVERSION_H
15 #define QMCPLUSPLUS_UNIT_CONVERSION_H
16 
17 #include <Configuration.h>
18 
19 namespace qmcplusplus
20 {
21 namespace Units
22 {
23 typedef QMCTraits::RealType real;
24 
25 namespace constants
26 {
27 const real kb = 1.3806503e-23; // J/K
28 }
29 
30 namespace count
31 {
32 const real mol = 6.0221415e23;
33 }
34 
35 namespace distance
36 {
37 const real m  = 1.e0;
38 const real A  = 1.e-10 * m;
39 const real B  = .52917720859e-10 * m;
40 const real nm = 1.e-9 * m;
41 const real pm = 1.e-12 * m;
42 const real fm = 1.e-15 * m;
43 } // namespace distance
44 
45 namespace time
46 {
47 const real s  = 1.e0;
48 const real ms = 1.e-3 * s;
49 const real ns = 1.e-9 * s;
50 const real ps = 1.e-12 * s;
51 const real fs = 1.e-15 * s;
52 } // namespace time
53 
54 namespace mass
55 {
56 const real kg  = 1.e0;
57 const real me  = 9.10938291e-31 * kg;
58 const real mp  = 1.672621777e-27 * kg;
59 const real amu = 1.660538921e-27 * kg;
60 const real Da  = amu;
61 } // namespace mass
62 
63 namespace energy
64 {
65 using constants::kb;
66 using count::mol;
67 const real J      = 1.e0;
68 const real eV     = 1.60217646e-19 * J;
69 const real Ry     = 13.6056923 * eV;
70 const real Ha     = 2 * Ry;
71 const real kJ_mol = 1000. * J / mol;
72 const real K      = J / kb;
73 } // namespace energy
74 
75 namespace charge
76 {
77 const real C = 1.e0;
78 const real e = 1.60217646e-19 * C;
79 } // namespace charge
80 
81 namespace pressure
82 {
83 const real Pa   = 1.e0;
84 const real bar  = 1.e5 * Pa;
85 const real Mbar = 1.e6 * bar;
86 const real GPa  = 1.e9 * Pa;
87 const real atm  = 1.01325e5 * Pa;
88 } // namespace pressure
89 
90 namespace force
91 {
92 const real N  = 1.e0;
93 const real pN = 1e-12 * N;
94 } // namespace force
95 
96 
97 enum units
98 {
99   mol = 0,
100   A,
101   B,
102   m,
103   nm,
104   pm,
105   fm,
106   s,
107   ms,
108   ns,
109   ps,
110   fs,
111   kg,
112   me,
113   mp,
114   amu,
115   Da,
116   J,
117   eV,
118   Ry,
119   Ha,
120   kJ_mol,
121   K,
122   C,
123   e,
124   Pa,
125   bar,
126   Mbar,
127   GPa,
128   atm,
129   N,
130   pN,
131   mole,
132   angstrom,
133   bohr,
134   meter,
135   nanometer,
136   picometer,
137   femtometer,
138   second,
139   millisecond,
140   nanosecond,
141   picosecond,
142   femtosecond,
143   kilogram,
144   electron_mass,
145   proton_mass,
146   atomic_mass_unit,
147   dalton,
148   joule,
149   electron_volt,
150   rydberg,
151   hartree,
152   kilojoule_per_mole,
153   kelvin,
154   coulomb,
155   proton_charge,
156   pascal,
157   megabar,
158   gigapascal,
159   atmosphere,
160   newton,
161   piconewton,
162   nunits
163 };
164 
165 
166 const real unit_values[nunits] =
167     {count::mol, distance::A,  distance::B,    distance::m,    distance::nm,  distance::pm,   distance::fm, time::s,
168      time::ms,   time::ns,     time::ps,       time::fs,       mass::kg,      mass::me,       mass::mp,     mass::amu,
169      mass::Da,   energy::J,    energy::eV,     energy::Ry,     energy::Ha,    energy::kJ_mol, energy::K,    charge::C,
170      charge::e,  pressure::Pa, pressure::bar,  pressure::Mbar, pressure::GPa, pressure::atm,  force::N,     force::pN,
171      count::mol, distance::A,  distance::B,    distance::m,    distance::nm,  distance::pm,   distance::fm, time::s,
172      time::ms,   time::ns,     time::ps,       time::fs,       mass::kg,      mass::me,       mass::mp,     mass::amu,
173      mass::Da,   energy::J,    energy::eV,     energy::Ry,     energy::Ha,    energy::kJ_mol, energy::K,    charge::C,
174      charge::e,  pressure::Pa, pressure::Mbar, pressure::GPa,  pressure::atm, force::N,       force::pN};
175 
176 
convert(real value,units units_in,units units_out)177 inline real convert(real value, units units_in, units units_out)
178 {
179   return value * unit_values[units_in] / unit_values[units_out];
180 }
181 
182 
183 template<typename array>
convert_array(array & values,units units_in,units units_out)184 inline void convert_array(array& values, units units_in, units units_out)
185 {
186   real conv = unit_values[units_in] / unit_values[units_out];
187   typename array::iterator v;
188   for (v = values.begin(); v != values.end(); ++v)
189     (*v) *= conv;
190 }
191 
192 
193 /// convert from std::string to count unit
194 units count_unit(const std::string& su);
195 
196 /// convert from std::string to distance unit
197 units distance_unit(const std::string& su);
198 
199 /// convert from std::string to time unit
200 units time_unit(const std::string& su);
201 
202 /// convert from std::string to mass unit
203 units mass_unit(const std::string& su);
204 
205 /// convert from std::string to energy unit
206 units energy_unit(const std::string& su);
207 
208 /// convert from std::string to charge unit
209 units charge_unit(const std::string& su);
210 
211 /// convert from std::string to pressure unit
212 units pressure_unit(const std::string& su);
213 
214 /// convert from std::string to force unit
215 units force_unit(const std::string& su);
216 
217 } // namespace Units
218 
219 } // namespace qmcplusplus
220 
221 
222 #endif
223