convert_units.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2008-2020, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_CONVERT_UNITS_H
24 #define O2SCL_CONVERT_UNITS_H
25 
26 /** \file convert_units.h
27  \brief File defining \ref o2scl::convert_units
28 */
29 
30 #include <cstdio>
31 #include <cstdlib>
32 #include <iostream>
33 #include <map>
34 
35 #include <o2scl/misc.h>
36 #include <o2scl/constants.h>
37 #include <o2scl/string_conv.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief Convert units
44 
45  Allow the user to convert between two different units after
46  specifying a conversion factor. This class will also
47  automatically combine two conversion factors to create a new
48  unit conversion (but it cannot combine more than two).
49 
50  Conversions are performed by the \ref convert() function. The
51  run-time unit cache is initially filled with hard-coded
52  conversions, and \ref convert() searches this cache is searched
53  for the requested conversion first. If the conversion is not
54  found and if \ref use_gnu_units is true, then \ref convert()
55  tries to open a pipe to open a shell to get the conversion
56  factor from <tt>'units'</tt>. If this is successful, then the
57  conversion factor is returned and the conversion is added to the
58  cache.
59 
60  If the GNU units command is not in the local path, the user may
61  modify \ref units_cmd_string to specify the full pathname. One
62  can also modify \ref units_cmd_string to specify a different
63  <tt>units.dat</tt> file.
64 
65  Example:
66  \code
67  convert_units cu;
68  cout << "A solar mass is " << cu.convert("Msun","g",1.0)
69  << " g. " << endl;
70  \endcode
71 
72  An object of this type is created by \ref o2scl_settings
73  (of type \ref lib_settings_class) for several unit
74  conversions used internally in \o2 .
75 
76  \note Combining two conversions allows for some surprising
77  apparent contradictions from numerical precision errors. If
78  there are two matching unit conversion pairs which give the same
79  requested conversion factor, then one can arrange a situation
80  where the same conversion factor is reported with slightly
81  different values after adding a related conversion to the table.
82  One way to fix this is to force the class not to combine two
83  conversions by setting \ref combine_two_conv to false.
84  Alternatively, one can ensure that no combination is necessary
85  by manually adding the desired combination conversion to the
86  cache after it is first computed.
87 
88  \note \o2 uses some unit aliases which are not used the the GNU
89  or OSX units commands, like "Msun" for the solar mass and adds
90  some units not present like "Rschwarz" for the Schwarzchild
91  radius of a 1 solar mass black hole.
92 
93  \note Only the const versions, \ref convert_const and
94  \ref convert_ret_const are guaranteed to be thread-safe,
95  since they are not allowed to update the unit cache.
96 
97  \future Add G=1.
98 
99  \future An in_cache() function to test
100  to see if a conversion is currently in the cache.
101 
102  \future Ideally, a real C++ API for the GNU units command
103  would be better.
104  */
105  template<class fp_t=double> class convert_units {
106 
107 #ifndef DOXYGEN_INTERNAL
108 
109  protected:
110 
111  /// The type for caching unit conversions
112  typedef struct {
113  /// The input unit
114  std::string f;
115  /// The output unit
116  std::string t;
117  /// The conversion factor
118  fp_t c;
119  } unit_t;
120 
121  /// The cache where unit conversions are stored
122  std::map<std::string,unit_t,std::greater<std::string> > mcache;
123 
124  /// The iterator type
125  typedef typename std::map<std::string,unit_t,
126  std::greater<std::string> >::iterator miter;
127 
128  /// The const iterator type
129  typedef typename std::map<std::string,unit_t,
130  std::greater<std::string> >::const_iterator mciter;
131 
132  /** \brief The internal conversion function which tries the
133  cache first and, if that failed, tries GNU units.
134 
135  This function returns 0 if the conversion was successful. If
136  the conversion fails and \ref err_on_fail is \c true, then the
137  error handler is called. If the conversion fails and \ref
138  err_on_fail is \c false, then the value \ref
139  o2scl::exc_enotfound is returned.
140 
141  The public conversion functions in this class are
142  basically just wrappers around this internal function.
143  */
144  int convert_internal(std::string from, std::string to,
145  fp_t val, fp_t &converted,
146  fp_t &factor, bool &new_conv) const {
147 
148  // Remove whitespace
149  remove_whitespace(from);
150  remove_whitespace(to);
151 
152  int ret_cache=convert_cache(from,to,val,converted,factor);
153 
154  if (ret_cache==0) {
155  new_conv=false;
156  return 0;
157  }
158 
159  if (use_gnu_units) {
160 
161  if (verbose>0) {
162  std::cout << "convert_units::convert(): "
163  << "Value of use_gnu_units is true." << std::endl;
164  }
165 
166  int ret_gnu=convert_gnu_units(from,to,val,converted,factor,new_conv);
167 
168  if (ret_gnu==0) {
169  new_conv=true;
170  return 0;
171  }
172 
173  } else {
174 
175  if (verbose>0) {
176  std::cout << "convert_units::convert(): "
177  << "Value of use_gnu_units is false." << std::endl;
178  }
179 
180  }
181 
182  if (err_on_fail) {
183  std::string str=((std::string)"Conversion between ")+from+" and "+to+
184  " not found in convert_units::convert_ret().";
185  O2SCL_ERR(str.c_str(),exc_enotfound);
186  }
187 
188  return exc_enotfound;
189  }
190 
191  /** \brief Attempt to use GNU units to perform a conversion
192 
193  This function attempts to open a pipe to GNU units independent
194  of the value of \ref use_gnu_units. However, it will always
195  return a non-zero valeu if \c HAVE_POPEN is not defined
196  signaling that the <tt>popen()</tt> function is not available
197  (but does not call the error handler in this case). The
198  function returns 0 if the conversion was successful. If
199  HAVE_POPEN is defined but the call to GNU units fails
200  for some reason, then the error handler is called if
201  \ref err_on_fail is true.
202  */
203  int convert_gnu_units(std::string from, std::string to,
204  fp_t val, fp_t &converted,
205  fp_t &factor, bool &new_conv) const {
206 
207  // Run the GNU 'units' command
208  std::string cmd=units_cmd_string+" '"+from+"' '"+to+"'";
209  if (verbose>0) {
210  std::cout << "convert_units::convert_gnu_units(): "
211  << "Units command is " << cmd << std::endl;
212  }
213 
214 #ifdef HAVE_POPEN
215 
216  if (verbose>0) {
217  std::cout << "convert_units::convert_gnu_units(): "
218  << "Define constant popen is defined." << std::endl;
219  }
220 
221  std::cout << "Using GNU units: " << cmd << std::endl;
222  FILE *ps_pipe=popen(cmd.c_str(),"r");
223  if (!ps_pipe) {
224  if (err_on_fail) {
225  O2SCL_ERR2("Pipe could not be opened in ",
226  "convert_units::convert_gnu_units().",exc_efilenotfound);
227  }
228  return exc_efilenotfound;
229  }
230 
231  char line1[80];
232  int size=80;
233 
234  // Variable 'cret' is unused, but put here to avoid
235  // unused return value errors
236  char *cret=fgets(line1,80,ps_pipe);
237  if (verbose>0) {
238  std::cout << "convert_units::convert_gnu_units(): "
239  << "Units output is " << line1 << std::endl;
240  }
241 
242  // Read the output from the 'units' command and compute the
243  // conversion factor
244  std::string s=line1, t1, t2;
245  std::istringstream *ins=new std::istringstream(s);
246  (*ins) >> t1 >> t2;
247  delete ins;
248  if (verbose>0) {
249  std::cout << "convert_units::convert_gnu_units(): "
250  << "Units string to convert is "
251  << t2 << std::endl;
252  }
253  int sret=o2scl::stod_nothrow(t2,factor);
254  if (sret!=0) {
255  if (err_on_fail) {
256  std::string str=((std::string)"Conversion between ")+from+" and "+to+
257  " not found in convert_units::convert_gnu_units().";
258  O2SCL_ERR(str.c_str(),exc_enotfound);
259  }
260  return exc_enotfound;
261  }
262  if (verbose>0) {
263  std::cout << "convert_units::convert_gnu_units(): "
264  << "Converted value is "
265  << factor*val << std::endl;
266  }
267 
268  // Cleanup
269  if (pclose(ps_pipe)!=0) {
270  if (err_on_fail) {
271  O2SCL_ERR2("Pipe could not be closed in ",
272  "convert_units::convert_gnu_units().",exc_efailed);
273  }
274  return exc_efailed;
275  }
276 
277  converted=factor*val;
278 
279 #else
280 
281  if (verbose>0) {
282  std::cout << "convert_units::convert_gnu_units(): "
283  << "Define constant popen is not defined." << std::endl;
284  }
285 
286  return exc_efailed;
287 
288 #endif
289 
290  return 0;
291  }
292 
293 
294  /** \brief Attempt to construct a conversion from the internal
295  unit cache
296 
297  This function returns 0 if the conversion was successful and
298  \ref o2scl::exc_efailed otherwise. This function
299  does not call the error handler.
300  */
301  int convert_cache(std::string from, std::string to,
302  fp_t val, fp_t &converted,
303  fp_t &factor) const {
304 
305  // Look in cache for conversion
306  std::string both=from+","+to;
307  mciter m3=mcache.find(both);
308  if (m3!=mcache.end()) {
309  factor=m3->second.c;
310  converted=val*factor;
311  return 0;
312  }
313 
314  // Look in cache for reverse conversion
315  std::string both2=to+","+from;
316  m3=mcache.find(both2);
317  if (m3!=mcache.end()) {
318  factor=1.0/m3->second.c;
319  converted=val*factor;
320  return 0;
321  }
322 
323  if (combine_two_conv) {
324 
325  // Look for combined conversions
326  for(mciter m=mcache.begin();m!=mcache.end();m++) {
327  if (m->second.f==from) {
328  std::string b=m->second.t+","+to;
329  mciter m2=mcache.find(b);
330  if (m2!=mcache.end()) {
331  if (verbose>0) {
332  std::cout << "Using conversions: " << m->second.f << " , "
333  << m->second.t << " " << m->second.c << std::endl;
334  std::cout << " (1) and: " << m2->second.f << " , "
335  << m2->second.t << " " << m2->second.c << std::endl;
336  }
337  factor=m->second.c*m2->second.c;
338  converted=val*factor;
339  return 0;
340  }
341  std::string b2=to+","+m->second.t;
342  mciter m4=mcache.find(b2);
343  if (m4!=mcache.end()) {
344  if (verbose>0) {
345  std::cout << "Using conversions: " << m->second.f << " , "
346  << m->second.t << std::endl;
347  std::cout << " (2) and: " << m4->second.f << " , "
348  << m4->second.t << std::endl;
349  }
350  factor=m->second.c/m4->second.c;
351  converted=val*factor;
352  return 0;
353  }
354  } else if (m->second.t==from) {
355  std::string b=m->second.f+","+to;
356  mciter m2=mcache.find(b);
357  if (m2!=mcache.end()) {
358  if (verbose>0) {
359  std::cout << "Using conversions: " << m->second.f << " , "
360  << m->second.t << std::endl;
361  std::cout << " (3) and: " << m2->second.f << " , "
362  << m2->second.t << std::endl;
363  }
364  factor=m2->second.c/m->second.c;
365  converted=val*factor;
366  return 0;
367  }
368  } else if (m->second.f==to) {
369  std::string b=m->second.t+","+from;
370  mciter m2=mcache.find(b);
371  if (m2!=mcache.end()) {
372  if (verbose>0) {
373  std::cout << "Using conversions: " << m->second.f << " , "
374  << m->second.t << std::endl;
375  std::cout << " (4) and: " << m2->second.f << " , "
376  << m2->second.t << std::endl;
377  }
378  factor=1.0/m->second.c/m2->second.c;
379  converted=val*factor;
380  return 0;
381  }
382  std::string b2=from+","+m->second.t;
383  mciter m4=mcache.find(b2);
384  if (m4!=mcache.end()) {
385  if (verbose>0) {
386  std::cout << "Using conversions: " << m->second.f << " , "
387  << m->second.t << std::endl;
388  std::cout << " (5) and: " << m4->second.f << " , "
389  << m4->second.t << std::endl;
390  }
391  factor=m4->second.c/m->second.c;
392  converted=val*factor;
393  return 0;
394  }
395  } else if (m->second.t==to) {
396  std::string b=m->second.f+","+from;
397  mciter m2=mcache.find(b);
398  if (m2!=mcache.end()) {
399  if (verbose>0) {
400  std::cout << "Using conversions: " << m->second.f << " , "
401  << m->second.t << std::endl;
402  std::cout << " (6) and: " << m2->second.f << " , "
403  << m2->second.t << std::endl;
404  }
405  factor=m->second.c/m2->second.c;
406  converted=val*factor;
407  return 0;
408  }
409  }
410  }
411 
412  }
413 
414  return exc_efailed;
415  }
416 
417 
418 #endif
419 
420  public:
421 
422  /// Create a unit-conversion object
424  verbose=0;
425  use_gnu_units=true;
426  units_cmd_string="units";
427  err_on_fail=true;
428  combine_two_conv=true;
429  }
430 
431 
432  virtual ~convert_units() {}
433 
434  /// \name Basic usage
435  //@{
436  /** \brief Return the value \c val after converting using units \c
437  from and \c to
438  */
439  virtual fp_t convert(std::string from, std::string to, fp_t val) {
440  fp_t converted;
441  int ret=convert_ret(from,to,val,converted);
442  if (ret==exc_efilenotfound) {
443  O2SCL_ERR("Pipe could not be opened in convert_units::convert().",
445  }
446  if (ret==exc_efailed) {
447  O2SCL_ERR("Pipe could not be closed in convert_units::convert().",
448  exc_efailed);
449  }
450  if (ret==exc_enotfound) {
451  std::string str=((std::string)"Conversion between ")+from+" and "+to+
452  " not found in convert_units::convert().";
453  O2SCL_ERR(str.c_str(),exc_enotfound);
454  }
455  return converted;
456  }
457 
458  /** \brief Return the value \c val after converting using units \c
459  from and \c to (const version)
460  */
461  virtual fp_t convert_const(std::string from, std::string to,
462  fp_t val) const {
463  fp_t converted;
464  int ret=convert_ret_const(from,to,val,converted);
465  if (ret==exc_enotfound) {
466  std::string str=((std::string)"Conversion between ")+from+" and "+to+
467  " not found in convert_units::convert().";
468  O2SCL_ERR(str.c_str(),exc_enotfound);
469  }
470  return converted;
471  }
472  //@}
473 
474  /// \name User settings
475  //@{
476  /// Verbosity (default 0)
477  int verbose;
478 
479  /** \brief If true, use a system call to units to derive new
480  conversions (default true)
481 
482  This also requires <tt>popen()</tt>.
483  */
485 
486  /// If true, throw an exception when a conversion fails (default true)
488 
489  /// If true, allow combinations of two conversions (default true)
491 
492  /// Command string to call units (default "units")
493  std::string units_cmd_string;
494  //@}
495 
496  /// \name Conversions which don't throw exceptions
497  //@{
498  /** \brief Return the value \c val after converting using units \c
499  from and \c to, returning a non-zero value on failure
500  */
501  virtual int convert_ret(std::string from, std::string to, fp_t val,
502  fp_t &converted) {
503  fp_t factor;
504  bool new_conv;
505 
506  int ret=convert_internal(from,to,val,converted,factor,new_conv);
507 
508  if (ret==0 && new_conv) {
509  // Add the newly computed conversion to the table
510  unit_t ut;
511  ut.f=from;
512  ut.t=to;
513  ut.c=factor;
514  std::string both=from+","+to;
515  mcache.insert(make_pair(both,ut));
516  }
517 
518  return ret;
519  }
520 
521  /** \brief Return the value \c val after converting using units \c
522  from and \c to, returning a non-zero value on failure
523  (const version)
524  */
525  virtual int convert_ret_const(std::string from, std::string to,
526  fp_t val, fp_t &converted) const {
527  fp_t factor;
528  bool new_conv;
529 
530  return convert_internal(from,to,val,converted,factor,new_conv);
531  }
532 
533  //@}
534 
535  /// \name Manipulate cache and create units.dat files
536  //@{
537  /// Manually insert a unit conversion into the cache
538  void insert_cache(std::string from, std::string to, fp_t conv) {
539 
540  // Remove whitespace
541  remove_whitespace(from);
542  remove_whitespace(to);
543 
544  if (err_on_fail &&
545  (from.find(',')!=std::string::npos ||
546  to.find(',')!=std::string::npos)) {
547  O2SCL_ERR("Units cannot contain comma in insert_cache()",
548  exc_efailed);
549  }
550 
551  unit_t ut;
552  ut.f=from;
553  ut.t=to;
554  ut.c=conv;
555  std::string both=from+","+to;
556 
557  // If it's already inside the cache, just update the conversion
558  // value
559  miter m3=mcache.find(both);
560  if (m3!=mcache.end()) {
561  m3->second=ut;
562  }
563 
564  mcache.insert(make_pair(both,ut));
565  return;
566  }
567 
568  /// Print the present unit cache to std::cout
569  void print_cache() const {
570  mciter m;
571  if (mcache.size()==0) {
572  std::cout << "No units in cache." << std::endl;
573  } else {
574  std::cout << "Unit cache: " << std::endl;
575  for (m=mcache.begin();m!=mcache.end();m++) {
576  std::cout.setf(std::ios::left);
577  std::cout.width(25);
578  std::cout << m->second.f << " ";
579  std::cout.width(25);
580  std::cout << m->second.t << " ";
581  std::cout.unsetf(std::ios::left);
582  std::cout.precision(10);
583  std::cout << m->second.c << std::endl;
584  }
585  }
586  return;
587  }
588 
589  /// Manually remove a unit conversion into the cache
590  void remove_cache(std::string from, std::string to) {
591 
592  // Remove whitespace
593  remove_whitespace(from);
594  remove_whitespace(to);
595  std::string both=from+","+to;
596 
597  miter m3=mcache.find(both);
598  if (m3!=mcache.end()) {
599  mcache.erase(m3);
600  return;
601  }
602 
603  if (err_on_fail) {
604  O2SCL_ERR((((std::string)"Conversion ")+from+" -> "+to+
605  " not found in convert_units::remove_cache().").c_str(),
606  exc_enotfound);
607  }
608 
609  return;
610  }
611 
612  /** \brief Add default conversions
613 
614  Where possible, this uses templates from constants.h to define
615  the conversions exactly in the user-specified floating-point
616  type.
617  */
619 
620  // Default conversions are given here. Obviously GNU units is better
621  // at handling these things, but it's nice to have some of the easy
622  // conversions in by default rather than worrying about opening a
623  // pipe, etc.
624 
625  fp_t sol_mks=o2scl_const::speed_of_light_f<fp_t>(o2scl_const::o2scl_mks);
626  fp_t sol_cgs=o2scl_const::speed_of_light_f<fp_t>(o2scl_const::o2scl_cgs);
627  fp_t hc=o2scl_const::hc_mev_fm_f<fp_t>();
628  fp_t elem_charge=o2scl_const::elem_charge_f<fp_t>();
629 
630  // hbar=c=1 conversion from mass to inverse length
631  insert_cache("kg","1/fm",1.0e-15/
632  o2scl_const::hbar_f<fp_t>(o2scl_const::o2scl_mks)*
633  sol_mks);
634 
635  // Simple mass/energy conversions with c^2=1
636 
637  insert_cache("kg","MeV",pow(sol_mks,2.0)/
638  elem_charge*1.0e-6);
639  insert_cache("MeV","eV",1.0e6);
640  insert_cache("keV","eV",1.0e3);
641  insert_cache("meV","eV",1.0e-3);
642  insert_cache("Msun","kg",o2scl_mks::solar_mass);
643  insert_cache("erg","kg",o2scl_mks::erg/pow(sol_mks,2.0));
644 
645  // Joules and Kelvin
646 
647  insert_cache("eV","J",elem_charge);
649  insert_cache("K","kg",o2scl_mks::boltzmann/pow(sol_mks,2.0));
650 
651  // Energy density and pressure conversions
652 
655  insert_cache("kPa","Pa",1.0e3);
656  insert_cache("Pa","kg/m^3",1.0/sol_mks/sol_mks);
657  insert_cache("Pa","g/cm^3",10.0/sol_cgs/sol_cgs);
658  insert_cache("Pa","MeV/fm^3",1.0e-44/o2scl_cgs::electron_volt);
659  insert_cache("Pa","erg/cm^3",10.0);
660  insert_cache("g/cm^3","Msun/km^3",1.0e12/o2scl_mks::solar_mass);
661  insert_cache("erg/cm^3","Msun/km^3",1.0e12/sol_cgs/
662  sol_cgs/o2scl_mks::solar_mass);
663  insert_cache("dyne/cm^2","Msun/km^3",1.0e12/sol_cgs/
664  sol_cgs/o2scl_mks::solar_mass);
665 
666  insert_cache("1/fm^4","MeV/fm^3",hc);
667  insert_cache("MeV/fm^3","MeV^2/fm^2",hc);
668  insert_cache("MeV^2/fm^2","MeV^3/fm",hc);
669  insert_cache("MeV^3/fm","MeV^4",hc);
670 
671  insert_cache("1/fm^4","MeV^2/fm^2",hc*hc);
672  insert_cache("MeV/fm^3","MeV^3/fm",hc*hc);
673  insert_cache("MeV^2/fm^2","MeV^4",hc*hc);
674 
675  insert_cache("1/fm^4","MeV^3/fm",hc*hc*hc);
676  insert_cache("MeV/fm^3","MeV^4",hc*hc*hc);
677 
678  insert_cache("1/fm^4","MeV^4",pow(hc,4.0));
679 
680  insert_cache("1/fm^3","MeV/fm^2",hc);
681  insert_cache("MeV/fm^2","MeV^2/fm",hc);
682  insert_cache("MeV^2/fm","MeV^3",hc);
683 
684  insert_cache("1/fm^3","MeV^2/fm",hc*hc);
685  insert_cache("MeV/fm^2","MeV^3",hc*hc);
686 
687  insert_cache("1/fm^3","MeV^3",pow(hc,3.0));
688 
689  insert_cache("MeV/fm^3","Msun/km^3",
690  o2scl_cgs::electron_volt/sol_cgs/
691  sol_cgs/o2scl_mks::solar_mass*1.0e57);
692  insert_cache("1/fm^4","Msun/km^3",hc*
693  o2scl_cgs::electron_volt/sol_cgs/
694  sol_cgs/o2scl_mks::solar_mass*1.0e57);
695 
696  // Inverse volume conversions
697 
698  insert_cache("1/fm^3","1/cm^3",1.0e39);
699  insert_cache("1/fm^3","1/m^3",1.0e45);
700 
701  // Simple mass conversions
702 
704 
705  // Simple powers of length conversions
706 
708  insert_cache("kpc","m",o2scl_mks::parsec*1.0e3);
709  insert_cache("km","m",1.0e3);
710  insert_cache("cm","m",1.0e-2);
711  insert_cache("fm","m",1.0e-15);
712  insert_cache("mm","m",1.0e-3);
713  insert_cache("nm","m",1.0e-9);
715 
716  insert_cache("pc^2","m^2",pow(o2scl_mks::parsec,2.0));
717  insert_cache("kpc^2","m^2",pow(o2scl_mks::parsec*1.0e3,2.0));
718  insert_cache("km^2","m^2",1.0e6);
719  insert_cache("cm^2","m^2",1.0e-4);
720  insert_cache("fm^2","m^2",1.0e-30);
721  insert_cache("mm^2","m^2",1.0e-6);
722  insert_cache("nm^2","m^2",1.0e-18);
723  insert_cache("lyr^2","m^2",pow(o2scl_mks::light_year,2.0));
724 
725  insert_cache("pc^3","m^3",pow(o2scl_mks::parsec,3.0));
726  insert_cache("kpc^3","m^3",pow(o2scl_mks::parsec*1.0e3,3.0));
727  insert_cache("km^3","m^3",1.0e9);
728  insert_cache("cm^3","m^3",1.0e-6);
729  insert_cache("fm^3","m^3",1.0e-45);
730  insert_cache("mm^3","m^3",1.0e-9);
731  insert_cache("nm^3","m^3",1.0e-27);
732  insert_cache("lyr^3","m^3",pow(o2scl_mks::light_year,3.0));
733  return;
734  }
735 
736  /** \brief Make a GNU \c units.dat file from the GSL constants
737 
738  If \c c_1 is true, then the second is defined in terms of
739  meters so that the speed of light is unitless. If \c hbar_1 is
740  true, then the kilogram is defined in terms of <tt>s/m^2</tt>
741  so that \f$ \hbar \f$ is unitless.
742 
743  \note While convert() generally works with the OSX version
744  of 'units', the OSX version can't read units.dat files
745  created by this function.
746 
747  \note Not all of the GSL constants or the canonical GNU units
748  conversions are given here.
749  */
750  void make_units_dat(std::string fname, bool c_1=false,
751  bool hbar_1=false, bool K_1=false) const {
752 
753  std::ofstream fout(fname.c_str());
754  fout.precision(14);
755 
756  fp_t sol_mks=o2scl_const::speed_of_light_f<fp_t>(o2scl_const::o2scl_mks);
757  fp_t elem_charge=o2scl_const::elem_charge_f<fp_t>();
758 
759 #ifdef O2SCL_OSX
760  fout << "/ ----------------------------------------------"
761  << "--------------" << std::endl;
762  fout << "/ Fundamental units" << std::endl;
763 #else
764  fout << "################################################"
765  << "##############" << std::endl;
766  fout << "# Fundamental units" << std::endl;
767 #endif
768  fout << "m\t!" << std::endl;
769  fout << "meter\tm" << std::endl;
770  if (c_1==false) {
771  fout << "s\t!" << std::endl;
772  fout << "second\ts" << std::endl;
773  } else {
774  fout << "s\t" << sol_mks << " m" << std::endl;
775  fout << "second\ts" << std::endl;
776  }
777  if (hbar_1==false) {
778  fout << "kg\t!" << std::endl;
779  fout << "kilogram\tkg" << std::endl;
780  } else {
781  fout << "kg\t" << 1.0/o2scl_const::hbar_f<fp_t>(o2scl_const::o2scl_mks)
782  << " s / m^2" << std::endl;
783  fout << "kilogram\tkg" << std::endl;
784  }
785  fout << "A\t!" << std::endl;
786  fout << "ampere\tA" << std::endl;
787  fout << "amp\tA" << std::endl;
788  fout << "cd\t!" << std::endl;
789  fout << "candela\tcd" << std::endl;
790  fout << "mol\t!" << std::endl;
791  fout << "mole\tmol" << std::endl;
792  if (K_1==false) {
793  fout << "K\t!" << std::endl;
794  fout << "kelvin\tK" << std::endl;
795  } else {
796  fout << "K\t" << o2scl_mks::boltzmann << " kg m^2 / s^2" << std::endl;
797  fout << "kelvin\tK" << std::endl;
798  }
799  fout << "radian\t!" << std::endl;
800  fout << "sr\t!" << std::endl;
801  fout << "steradian\tsr" << std::endl;
802  fout << "US$\t!" << std::endl;
803  fout << "bit\t!" << std::endl;
804  fout << std::endl;
805 
806 #ifdef O2SCL_OSX
807  fout << "/ ----------------------------------------------"
808  << "--------------" << std::endl;
809  fout << "/ " << std::endl;
810 #else
811  fout << "################################################"
812  << "##############" << std::endl;
813  fout << "# SI and common prefixes" << std::endl;
814 #endif
815  fout << "yotta-\t\t1e24" << std::endl;
816  fout << "zetta-\t\t1e21" << std::endl;
817  fout << "exa-\t\t1e18" << std::endl;
818  fout << "peta-\t\t1e15" << std::endl;
819  fout << "tera-\t\t1e12" << std::endl;
820  fout << "giga-\t\t1e9" << std::endl;
821  fout << "mega-\t\t1e6" << std::endl;
822  fout << "myria-\t\t1e4" << std::endl;
823  fout << "kilo-\t\t1e3" << std::endl;
824  fout << "hecto-\t\t1e2" << std::endl;
825  fout << "deca-\t\t1e1" << std::endl;
826  fout << "deka-\t\tdeca" << std::endl;
827  fout << "deci-\t\t1e-1" << std::endl;
828  fout << "centi-\t\t1e-2" << std::endl;
829  fout << "milli-\t\t1e-3" << std::endl;
830  fout << "micro-\t\t1e-6" << std::endl;
831  fout << "nano-\t\t1e-9" << std::endl;
832  fout << "pico-\t\t1e-12" << std::endl;
833  fout << "femto-\t\t1e-15" << std::endl;
834  fout << "atto-\t\t1e-18" << std::endl;
835  fout << "zepto-\t\t1e-21" << std::endl;
836  fout << "yocto-\t\t1e-24" << std::endl;
837  fout << "quarter-\t1|4" << std::endl;
838  fout << "semi-\t\t0.5" << std::endl;
839  fout << "demi-\t\t0.5" << std::endl;
840  fout << "hemi-\t\t0.5" << std::endl;
841  fout << "half-\t\t0.5" << std::endl;
842  fout << "fp_t-\t\t2" << std::endl;
843  fout << "triple-\t\t3" << std::endl;
844  fout << "treble-\t\t3" << std::endl;
845  fout << std::endl;
846 
847 #ifdef O2SCL_OSX
848  fout << "/ ----------------------------------------------"
849  << "--------------" << std::endl;
850  fout << "/ " << std::endl;
851 #else
852  fout << "################################################"
853  << "##############" << std::endl;
854  fout << "# SI prefix abbreviations" << std::endl;
855 #endif
856  fout << "Y- yotta" << std::endl;
857  fout << "Z- zetta" << std::endl;
858  fout << "E- exa" << std::endl;
859  fout << "P- peta" << std::endl;
860  fout << "T- tera" << std::endl;
861  fout << "G- giga" << std::endl;
862  fout << "M- mega" << std::endl;
863  fout << "k- kilo" << std::endl;
864  fout << "h- hecto" << std::endl;
865  fout << "da- deka" << std::endl;
866  fout << "d- deci" << std::endl;
867  fout << "c- centi" << std::endl;
868  fout << "m- milli" << std::endl;
869  fout << "n- nano" << std::endl;
870  fout << "p- pico" << std::endl;
871  fout << "f- femto" << std::endl;
872  fout << "a- atto" << std::endl;
873  fout << "z- zepto" << std::endl;
874  fout << "y- yocto" << std::endl;
875  fout << std::endl;
876 
877 #ifdef O2SCL_OSX
878  fout << "/ ----------------------------------------------"
879  << "--------------" << std::endl;
880  fout << "/ " << std::endl;
881 #else
882  fout << "################################################"
883  << "##############" << std::endl;
884  fout << "# Basic numbers" << std::endl;
885 #endif
886  fout << "one 1" << std::endl;
887  fout << "two 2" << std::endl;
888  fout << "fp_t 2" << std::endl;
889  fout << "couple 2" << std::endl;
890  fout << "three 3" << std::endl;
891  fout << "triple 3" << std::endl;
892  fout << "four 4" << std::endl;
893  fout << "quadruple 4" << std::endl;
894  fout << "five 5" << std::endl;
895  fout << "quintuple 5" << std::endl;
896  fout << "six 6" << std::endl;
897  fout << "seven 7" << std::endl;
898  fout << "eight 8" << std::endl;
899  fout << "nine 9" << std::endl;
900  fout << "ten 10" << std::endl;
901  fout << "twenty 20" << std::endl;
902  fout << "thirty 30" << std::endl;
903  fout << "forty 40" << std::endl;
904  fout << "fifty 50" << std::endl;
905  fout << "sixty 60" << std::endl;
906  fout << "seventy 70" << std::endl;
907  fout << "eighty 80" << std::endl;
908  fout << "ninety 90" << std::endl;
909  fout << "hundred 100" << std::endl;
910  fout << "thousand 1000" << std::endl;
911  fout << "million 1e6" << std::endl;
912  fout << "billion 1e9" << std::endl;
913  fout << "trillion 1e12" << std::endl;
914  fout << "quadrillion 1e15" << std::endl;
915  fout << "quintillion 1e18" << std::endl;
916  fout << "sextillion 1e21" << std::endl;
917  fout << "septillion 1e24" << std::endl;
918  fout << "octillion 1e27" << std::endl;
919  fout << "nonillion 1e30" << std::endl;
920  fout << "noventillion nonillion" << std::endl;
921  fout << "decillion 1e33" << std::endl;
922  fout << "undecillion 1e36" << std::endl;
923  fout << "duodecillion 1e39" << std::endl;
924  fout << "tredecillion 1e42" << std::endl;
925  fout << "quattuordecillion 1e45" << std::endl;
926  fout << "quindecillion 1e48" << std::endl;
927  fout << "sexdecillion 1e51" << std::endl;
928  fout << "septendecillion 1e54" << std::endl;
929  fout << "octodecillion 1e57" << std::endl;
930  fout << "novemdecillion 1e60" << std::endl;
931  fout << "vigintillion 1e63" << std::endl;
932  fout << "googol 1e100" << std::endl;
933  fout << "centillion 1e303" << std::endl;
934  fout << std::endl;
935 
936 #ifdef O2SCL_OSX
937  fout << "/ ----------------------------------------------"
938  << "--------------" << std::endl;
939  fout << "/ " << std::endl;
940 #else
941  fout << "################################################"
942  << "##############" << std::endl;
943  fout << "# Basic SI units" << std::endl;
944 #endif
945  fout << "newton kg m / s^2 " << std::endl;
946  fout << "N newton" << std::endl;
947  fout << "pascal N/m^2 " << std::endl;
948  fout << "Pa pascal" << std::endl;
949  fout << "joule N m " << std::endl;
950  fout << "J joule" << std::endl;
951  fout << "watt J/s " << std::endl;
952  fout << "W watt" << std::endl;
953  fout << "coulomb A s " << std::endl;
954  fout << "C coulomb" << std::endl;
955  fout << "volt W/A " << std::endl;
956  fout << "V volt" << std::endl;
957  fout << "ohm V/A " << std::endl;
958  fout << "siemens A/V " << std::endl;
959  fout << "S siemens" << std::endl;
960  fout << "farad C/V " << std::endl;
961  fout << "F farad" << std::endl;
962  fout << "weber V s " << std::endl;
963  fout << "Wb weber" << std::endl;
964  fout << "henry Wb/A " << std::endl;
965  fout << "H henry" << std::endl;
966  fout << "tesla Wb/m^2 " << std::endl;
967  fout << "T tesla" << std::endl;
968  fout << "hertz 1/s " << std::endl;
969  fout << "Hz hertz" << std::endl;
970  fout << "gram millikg " << std::endl;
971  fout << "g gram" << std::endl;
972  fout << std::endl;
973 
974 #ifdef O2SCL_OSX
975  fout << "/ ----------------------------------------------"
976  << "--------------" << std::endl;
977  fout << "/ " << std::endl;
978 #else
979  fout << "################################################"
980  << "##############" << std::endl;
981  fout << "# Dimensional analysis units" << std::endl;
982 #endif
983  fout << "LENGTH meter" << std::endl;
984  fout << "AREA LENGTH^2" << std::endl;
985  fout << "VOLUME LENGTH^3" << std::endl;
986  fout << "MASS kilogram" << std::endl;
987  fout << "CURRENT ampere" << std::endl;
988  fout << "AMOUNT mole" << std::endl;
989  fout << "ANGLE radian" << std::endl;
990  fout << "SOLID_ANGLE steradian" << std::endl;
991  fout << "MONEY US$" << std::endl;
992  fout << "FORCE newton" << std::endl;
993  fout << "PRESSURE FORCE / AREA" << std::endl;
994  fout << "STRESS FORCE / AREA" << std::endl;
995  fout << "CHARGE coulomb" << std::endl;
996  fout << "CAPACITANCE farad" << std::endl;
997  fout << "RESISTANCE ohm" << std::endl;
998  fout << "CONDUCTANCE siemens" << std::endl;
999  fout << "INDUCTANCE henry" << std::endl;
1000  fout << "FREQUENCY hertz" << std::endl;
1001  fout << "VELOCITY LENGTH / TIME" << std::endl;
1002  fout << "ACCELERATION VELOCITY / TIME" << std::endl;
1003  fout << "DENSITY MASS / VOLUME" << std::endl;
1004  fout << "LINEAR_DENSITY MASS / LENGTH" << std::endl;
1005  fout << "VISCOSITY FORCE TIME / AREA" << std::endl;
1006  fout << "KINEMATIC_VISCOSITY VISCOSITY / DENSITY" << std::endl;
1007  fout << std::endl;
1008 
1009 #ifdef O2SCL_OSX
1010  fout << "/ ----------------------------------------------"
1011  << "--------------" << std::endl;
1012  fout << "/ " << std::endl;
1013 #else
1014  fout << "################################################"
1015  << "##############" << std::endl;
1016  fout << "# GSL constants" << std::endl;
1017 #endif
1018  fout << "schwarzchild_radius\t\t" << o2scl_mks::schwarzchild_radius
1019  << " m" << std::endl;
1020  fout << "Rschwarz\t\tschwarzchild_radius" << std::endl;
1021  fout << "speed_of_light\t\t" << sol_mks
1022  << " m / s" << std::endl;
1023  fout << "c\t\tspeed_of_light" << std::endl;
1024  fout << "gravitational_constant\t\t"
1026  << " m^3 / kg s^2" << std::endl;
1027  fout << "G\t\tgravitational_constant" << std::endl;
1028  fout << "plancks_constant_h\t\t"
1030  << " kg m^2 / s" << std::endl;
1031  fout << "h\t\tplancks_constant_h" << std::endl;
1032  fout << "plancks_constant_hbar\t\t"
1033  << o2scl_const::hbar_f<fp_t>(o2scl_const::o2scl_mks)
1034  << " kg m^2 / s" << std::endl;
1035  fout << "hbar\t\tplancks_constant_hbar" << std::endl;
1036  fout << "astronomical_unit\t\t" << o2scl_mks::astronomical_unit
1037  << " m" << std::endl;
1038  fout << "au\t\tastronomical_unit" << std::endl;
1039  fout << "light_year\t\t" << o2scl_mks::light_year
1040  << " m" << std::endl;
1041  fout << "lyr\t\tlight_year" << std::endl;
1042  fout << "parsec\t\t" << o2scl_mks::parsec
1043  << " m" << std::endl;
1044  fout << "pc\t\tparsec" << std::endl;
1045  fout << "grav_accel\t\t" << o2scl_mks::grav_accel
1046  << " m / s^2" << std::endl;
1047  fout << "electron_volt\t\t" << elem_charge
1048  << " kg m^2 / s^2" << std::endl;
1049  fout << "eV\t\telectron_volt" << std::endl;
1050  fout << "mass_electron\t\t" << o2scl_mks::mass_electron
1051  << " kg" << std::endl;
1052  fout << "mass_muon\t\t" << o2scl_mks::mass_muon
1053  << " kg" << std::endl;
1054  fout << "mass_proton\t\t" << o2scl_mks::mass_proton
1055  << " kg" << std::endl;
1056  fout << "mass_neutron\t\t" << o2scl_mks::mass_neutron
1057  << " kg" << std::endl;
1058  fout << "rydberg\t\t" << o2scl_mks::rydberg
1059  << " kg m^2 / s^2" << std::endl;
1060  fout << "boltzmann\t\t" << o2scl_mks::boltzmann
1061  << " kg m^2 / K s^2" << std::endl;
1062  fout << "bohr_magneton\t\t" << o2scl_mks::bohr_magneton
1063  << " A m^2" << std::endl;
1064  fout << "nuclear_magneton\t\t" << o2scl_mks::nuclear_magneton
1065  << " A m^2" << std::endl;
1066  fout << "electron_magnetic_moment\t\t"
1068  << " A m^2" << std::endl;
1069  fout << "proton_magnetic_moment\t\t"
1071  << " A m^2" << std::endl;
1072  fout << "molar_gas\t\t" << o2scl_mks::molar_gas
1073  << " kg m^2 / K mol s^2" << std::endl;
1074  fout << "standard_gas_volume\t\t" << o2scl_mks::standard_gas_volume
1075  << " m^3 / mol" << std::endl;
1076  fout << "minute\t\t" << o2scl_mks::minute
1077  << " s" << std::endl;
1078  fout << "min\t\tminute" << std::endl;
1079  fout << "hour\t\t" << o2scl_mks::hour
1080  << " s" << std::endl;
1081  fout << "day\t\t" << o2scl_mks::day
1082  << " s" << std::endl;
1083  fout << "week\t\t" << o2scl_mks::week
1084  << " s" << std::endl;
1085  fout << "inch\t\t" << o2scl_mks::inch
1086  << " m" << std::endl;
1087  fout << "foot\t\t" << o2scl_mks::foot
1088  << " m" << std::endl;
1089  fout << "yard\t\t" << o2scl_mks::yard
1090  << " m" << std::endl;
1091  fout << "mile\t\t" << o2scl_mks::mile
1092  << " m" << std::endl;
1093  fout << "nautical_mile\t\t" << o2scl_mks::nautical_mile
1094  << " m" << std::endl;
1095  fout << "fathom\t\t" << o2scl_mks::fathom
1096  << " m" << std::endl;
1097  fout << "mil\t\t" << o2scl_mks::mil
1098  << " m" << std::endl;
1099  fout << "point\t\t" << o2scl_mks::point
1100  << " m" << std::endl;
1101  fout << "texpoint\t\t" << o2scl_mks::texpoint
1102  << " m" << std::endl;
1103  fout << "micron\t\t" << o2scl_mks::micron
1104  << " m" << std::endl;
1105  fout << "angstrom\t\t" << o2scl_mks::angstrom
1106  << " m" << std::endl;
1107  fout << "hectare\t\t" << o2scl_mks::hectare
1108  << " m^2" << std::endl;
1109  fout << "acre\t\t" << o2scl_mks::acre
1110  << " m^2" << std::endl;
1111  fout << "barn\t\t" << o2scl_mks::barn
1112  << " m^2" << std::endl;
1113  fout << "liter\t\t" << o2scl_mks::liter
1114  << " m^3" << std::endl;
1115  fout << "us_gallon\t\t" << o2scl_mks::us_gallon
1116  << " m^3" << std::endl;
1117  fout << "gallon\t\tus_gallon" << std::endl;
1118  fout << "quart\t\t" << o2scl_mks::quart
1119  << " m^3" << std::endl;
1120  fout << "pint\t\t" << o2scl_mks::pint
1121  << " m^3" << std::endl;
1122  fout << "cup\t\t" << o2scl_mks::cup
1123  << " m^3" << std::endl;
1124  fout << "fluid_ounce\t\t" << o2scl_mks::fluid_ounce
1125  << " m^3" << std::endl;
1126  fout << "tablespoon\t\t" << o2scl_mks::tablespoon
1127  << " m^3" << std::endl;
1128  fout << "teaspoon\t\t" << o2scl_mks::teaspoon
1129  << " m^3" << std::endl;
1130  fout << "canadian_gallon\t\t" << o2scl_mks::canadian_gallon
1131  << " m^3" << std::endl;
1132  fout << "uk_gallon\t\t" << o2scl_mks::uk_gallon
1133  << " m^3" << std::endl;
1134  fout << "miles_per_hour\t\t" << o2scl_mks::miles_per_hour
1135  << " m / s" << std::endl;
1136  fout << "mph\t\tmiles_per_hour" << std::endl;
1137  fout << "kilometers_per_hour\t\t" << o2scl_mks::kilometers_per_hour
1138  << " m / s" << std::endl;
1139  fout << "kph\t\tkilometers_per_hour" << std::endl;
1140  fout << "knot\t\t" << o2scl_mks::knot
1141  << " m / s" << std::endl;
1142  fout << "pound_mass\t\t" << o2scl_mks::pound_mass
1143  << " kg" << std::endl;
1144  fout << "ounce_mass\t\t" << o2scl_mks::ounce_mass
1145  << " kg" << std::endl;
1146  fout << "ton\t\t" << o2scl_mks::ton
1147  << " kg" << std::endl;
1148  fout << "metric_ton\t\t" << o2scl_mks::metric_ton
1149  << " kg" << std::endl;
1150  fout << "uk_ton\t\t" << o2scl_mks::uk_ton
1151  << " kg" << std::endl;
1152  fout << "troy_ounce\t\t" << o2scl_mks::troy_ounce
1153  << " kg" << std::endl;
1154  fout << "carat\t\t" << o2scl_mks::carat
1155  << " kg" << std::endl;
1156  fout << "unified_atomic_mass\t\t" << o2scl_mks::unified_atomic_mass
1157  << " kg" << std::endl;
1158  fout << "gram_force\t\t" << o2scl_mks::gram_force
1159  << " kg m / s^2" << std::endl;
1160  fout << "pound_force\t\t" << o2scl_mks::pound_force
1161  << " kg m / s^2" << std::endl;
1162  fout << "kilopound_force\t\t" << o2scl_mks::kilopound_force
1163  << " kg m / s^2" << std::endl;
1164  fout << "poundal\t\t" << o2scl_mks::poundal
1165  << " kg m / s^2" << std::endl;
1166  fout << "calorie\t\t" << o2scl_mks::calorie
1167  << " kg m^2 / s^2" << std::endl;
1168  fout << "btu\t\t" << o2scl_mks::btu
1169  << " kg m^2 / s^2" << std::endl;
1170  fout << "therm\t\t" << o2scl_mks::therm
1171  << " kg m^2 / s^2" << std::endl;
1172  fout << "horsepower\t\t" << o2scl_mks::horsepower
1173  << " kg m^2 / s^3" << std::endl;
1174  fout << "hp\t\thorsepower" << std::endl;
1175  fout << "bar\t\t" << o2scl_mks::bar
1176  << " kg / m s^2" << std::endl;
1177  fout << "std_atmosphere\t\t" << o2scl_mks::std_atmosphere
1178  << " kg / m s^2" << std::endl;
1179  fout << "torr\t\t" << o2scl_mks::torr
1180  << " kg / m s^2" << std::endl;
1181  fout << "meter_of_mercury\t\t" << o2scl_mks::meter_of_mercury
1182  << " kg / m s^2" << std::endl;
1183  fout << "inch_of_mercury\t\t" << o2scl_mks::inch_of_mercury
1184  << " kg / m s^2" << std::endl;
1185  fout << "inch_of_water\t\t" << o2scl_mks::inch_of_water
1186  << " kg / m s^2" << std::endl;
1187  fout << "psi\t\t" << o2scl_mks::psi
1188  << " kg / m s^2" << std::endl;
1189  fout << "poise\t\t" << o2scl_mks::poise
1190  << " kg / m s " << std::endl;
1191  fout << "stokes\t\t" << o2scl_mks::stokes
1192  << " m^2 / s" << std::endl;
1193  fout << "faraday\t\t" << o2scl_mks::faraday
1194  << " A s / mol" << std::endl;
1195  fout << "electron_charge\t\t" << o2scl_mks::electron_charge
1196  << " A s" << std::endl;
1197  fout << "gauss\t\t" << o2scl_mks::gauss
1198  << " kg / A s^2" << std::endl;
1199  fout << "stilb\t\t" << o2scl_mks::stilb
1200  << " cd / m^2" << std::endl;
1201  fout << "lumen\t\t" << o2scl_mks::lumen
1202  << " cd sr" << std::endl;
1203  fout << "lux\t\t" << o2scl_mks::lux
1204  << " cd sr / m^2" << std::endl;
1205  fout << "phot\t\t" << o2scl_mks::phot
1206  << " cd sr / m^2" << std::endl;
1207  fout << "footcandle\t\t" << o2scl_mks::footcandle
1208  << " cd sr / m^2" << std::endl;
1209  fout << "lambert\t\t" << o2scl_mks::lambert
1210  << " cd sr / m^2" << std::endl;
1211  fout << "footlambert\t\t" << o2scl_mks::footlambert
1212  << " cd sr / m^2" << std::endl;
1213  fout << "curie\t\t" << o2scl_mks::curie
1214  << " 1 / s" << std::endl;
1215  fout << "roentgen\t\t" << o2scl_mks::roentgen
1216  << " A s / kg" << std::endl;
1217  fout << "rad\t\t" << o2scl_mks::rad
1218  << " m^2 / s^2" << std::endl;
1219  fout << "solar_mass\t\t" << o2scl_mks::solar_mass
1220  << " kg" << std::endl;
1221  fout << "Msun\t\tsolar_mass" << std::endl;
1222  fout << "bohr_radius\t\t" << o2scl_mks::bohr_radius
1223  << " m" << std::endl;
1224  fout << "dyne\t\t" << o2scl_mks::dyne
1225  << " kg m / s^2" << std::endl;
1226  fout << "erg\t\t" << o2scl_mks::erg
1227  << " kg m^2 / s^2" << std::endl;
1228  fout << "stefan_boltzmann_constant\t\t"
1230  << " kg / K^4 s^3" << std::endl;
1231  fout << "thomson_cross_section\t\t"
1233  << " m^2" << std::endl;
1234  fout << "vacuum_permittivity\t\t" << o2scl_mks::vacuum_permittivity
1235  << " A^2 s^4 / kg m^3" << std::endl;
1236  fout << "vacuum_permeability\t\t" << o2scl_mks::vacuum_permeability
1237  << " kg m / A^2 s^2" << std::endl;
1238  fout.close();
1239 
1240  return;
1241  }
1242 
1243 
1244  /** \brief Exhaustive test the cache against GNU units
1245  */
1246  int test_cache() {
1247  err_on_fail=false;
1248  mciter m, m2;
1249  std::cout << "units_cmd_string: " << units_cmd_string << std::endl;
1250  for (m=mcache.begin();m!=mcache.end();m++) {
1251  for (m2=m;m2!=mcache.end();m2++) {
1252  std::string from=m->second.f;
1253  std::string to=m2->second.t;
1254  if (from!=to) {
1255  fp_t v=1.0, c, f1, f2=0.0;
1256  int cret=convert_cache(from,to,v,c,f1);
1257  if (cret==0) {
1258  bool new_conv;
1259  int gret=convert_gnu_units(from,to,v,c,f2,new_conv);
1260  if (gret==0) {
1261  if (fabs(f1-f2)/f1>1.0e-6) {
1262  std::cout << "* ";
1263  } else {
1264  std::cout << " ";
1265  }
1266  std::cout.width(10);
1267  std::cout << from << " ";
1268  std::cout.width(10);
1269  std::cout << to << " " << f1 << " " << f2 << " "
1270  << fabs(f1-f2)/f1 << std::endl;
1271  }
1272  }
1273  }
1274  to=m2->second.f;
1275  if (from!=to) {
1276  fp_t v=1.0, c, f1, f2;
1277  int cret=convert_cache(from,to,v,c,f1);
1278  if (cret==0) {
1279  bool new_conv;
1280  int gret=convert_gnu_units(from,to,v,c,f2,new_conv);
1281  if (gret==0) {
1282  if (fabs(f1-f2)/f1>1.0e-6) {
1283  std::cout << "* ";
1284  } else {
1285  std::cout << " ";
1286  }
1287  std::cout.width(10);
1288  std::cout << from << " ";
1289  std::cout.width(10);
1290  std::cout << to << " " << f1 << " " << f2 << " "
1291  << fabs(f1-f2)/f1 << std::endl;
1292  }
1293  }
1294  }
1295  }
1296  }
1297  return 0;
1298  }
1299  //@}
1300 
1301  };
1302 
1303 #ifndef DOXYGEN_NO_O2NS
1304 }
1305 #endif
1306 
1307 #endif
o2scl_mks::parsec
const double parsec
Parsec in m.
Definition: constants.h:693
o2scl_mks::cup
const double cup
m^3
Definition: constants.h:797
o2scl::convert_units::miter
std::map< std::string, unit_t, std::greater< std::string > >::iterator miter
The iterator type.
Definition: convert_units.h:126
o2scl::convert_units::convert_ret
virtual int convert_ret(std::string from, std::string to, fp_t val, fp_t &converted)
Return the value val after converting using units from and to, returning a non-zero value on failure.
Definition: convert_units.h:501
o2scl::convert_units::convert_ret_const
virtual int convert_ret_const(std::string from, std::string to, fp_t val, fp_t &converted) const
Return the value val after converting using units from and to, returning a non-zero value on failure ...
Definition: convert_units.h:525
o2scl_mks::uk_ton
const double uk_ton
kg
Definition: constants.h:823
o2scl_mks::texpoint
const double texpoint
m
Definition: constants.h:777
o2scl_mks::kilometers_per_hour
const double kilometers_per_hour
m / s
Definition: constants.h:811
o2scl_mks::grav_accel
const double grav_accel
Acceleration due to gravity in m / s^2.
Definition: constants.h:695
o2scl_mks::erg
const double erg
kg m^2 / s^2
Definition: constants.h:889
o2scl_mks::tablespoon
const double tablespoon
m^3
Definition: constants.h:801
o2scl_mks::minute
const double minute
s
Definition: constants.h:753
o2scl_mks::proton_magnetic_moment
const double proton_magnetic_moment
A m^2.
Definition: constants.h:898
o2scl_mks::pound_mass
const double pound_mass
kg
Definition: constants.h:815
o2scl_mks::uk_gallon
const double uk_gallon
m^3
Definition: constants.h:807
o2scl::convert_units::mciter
std::map< std::string, unit_t, std::greater< std::string > >::const_iterator mciter
The const iterator type.
Definition: convert_units.h:130
o2scl_mks::stilb
const double stilb
cd / m^2
Definition: constants.h:865
o2scl::exc_efailed
@ exc_efailed
generic failure
Definition: err_hnd.h:61
o2scl_mks::astronomical_unit
const double astronomical_unit
Astronomical unit in m.
Definition: constants.h:691
o2scl_mks::inch
const double inch
m
Definition: constants.h:761
O2SCL_ERR2
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
o2scl_mks::standard_gas_volume
const double standard_gas_volume
m^3 / mol
Definition: constants.h:747
o2scl_mks::quart
const double quart
m^3
Definition: constants.h:793
o2scl_mks::angstrom
const double angstrom
m
Definition: constants.h:781
o2scl::convert_units::convert_internal
int convert_internal(std::string from, std::string to, fp_t val, fp_t &converted, fp_t &factor, bool &new_conv) const
The internal conversion function which tries the cache first and, if that failed, tries GNU units.
Definition: convert_units.h:144
o2scl_mks::therm
const double therm
kg m^2 / s^2
Definition: constants.h:841
o2scl_mks::point
const double point
m
Definition: constants.h:775
o2scl_mks::gram_force
const double gram_force
kg m / s^2
Definition: constants.h:829
o2scl_mks::ounce_mass
const double ounce_mass
kg
Definition: constants.h:817
o2scl
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
Definition: anneal.h:42
o2scl_mks::ton
const double ton
kg
Definition: constants.h:819
o2scl::exc_enotfound
@ exc_enotfound
Generic "not found" result.
Definition: err_hnd.h:117
o2scl_mks::miles_per_hour
const double miles_per_hour
m / s
Definition: constants.h:809
o2scl_mks::electron_magnetic_moment
const double electron_magnetic_moment
A m^2.
Definition: constants.h:895
o2scl_mks::mass_electron
const double mass_electron
Electron mass in kg.
Definition: constants.h:715
o2scl_mks::gauss
const double gauss
kg / A s^2
Definition: constants.h:863
o2scl_mks::unified_atomic_mass
const double unified_atomic_mass
Atomic mass constant in kg.
Definition: constants.h:737
o2scl_mks::fluid_ounce
const double fluid_ounce
m^3
Definition: constants.h:799
o2scl::convert_units::unit_t::t
std::string t
The output unit.
Definition: convert_units.h:116
o2scl_mks::std_atmosphere
const double std_atmosphere
kg / m s^2
Definition: constants.h:847
o2scl_mks::curie
const double curie
1 / s
Definition: constants.h:879
o2scl_mks::rydberg
const double rydberg
Rydberg constant in kg m^2 / s^2.
Definition: constants.h:743
o2scl_mks::btu
const double btu
kg m^2 / s^2
Definition: constants.h:839
o2scl_mks::thomson_cross_section
const double thomson_cross_section
Thomson cross section in m^2.
Definition: constants.h:681
o2scl_mks::knot
const double knot
m / s
Definition: constants.h:813
o2scl_mks::carat
const double carat
kg
Definition: constants.h:827
o2scl::remove_whitespace
void remove_whitespace(std::string &s)
Remove all whitespace from the string s.
o2scl_mks::bohr_magneton
const double bohr_magneton
Bohr magneton in A m^2.
Definition: constants.h:903
o2scl_mks::boltzmann
const double boltzmann
Boltzmann constant in kg m^2 / K s^2.
Definition: constants.h:685
o2scl_mks::lux
const double lux
cd sr / m^2
Definition: constants.h:869
o2scl_mks::schwarzchild_radius
const double schwarzchild_radius
Schwarzchild radius in m.
Definition: constants.h:701
o2scl::convert_units::default_conversions
void default_conversions()
Add default conversions.
Definition: convert_units.h:618
o2scl_mks::light_year
const double light_year
Light year in .
Definition: constants.h:709
o2scl_mks::troy_ounce
const double troy_ounce
kg
Definition: constants.h:825
o2scl_mks::electron_charge
const double electron_charge
A s (derived)
Definition: constants.h:916
o2scl_mks::molar_gas
const double molar_gas
kg m^2 / K mol s^2
Definition: constants.h:745
o2scl_mks::inch_of_water
const double inch_of_water
kg / m s^2
Definition: constants.h:855
o2scl_mks::mass_muon
const double mass_muon
Muon mass in kg.
Definition: constants.h:717
o2scl::convert_units::units_cmd_string
std::string units_cmd_string
Command string to call units (default "units")
Definition: convert_units.h:493
o2scl_mks::pint
const double pint
m^3
Definition: constants.h:795
o2scl::convert_units::test_cache
int test_cache()
Exhaustive test the cache against GNU units.
Definition: convert_units.h:1246
o2scl::convert_units::mcache
std::map< std::string, unit_t, std::greater< std::string > > mcache
The cache where unit conversions are stored.
Definition: convert_units.h:122
o2scl_mks::faraday
const double faraday
A s / mol.
Definition: constants.h:914
o2scl_cgs::electron_volt
const double electron_volt
Electron volt in g cm^2 / s^2 (CODATA 2018; exact)
Definition: constants.h:162
o2scl_mks::mile
const double mile
m
Definition: constants.h:767
o2scl::convert_units::convert_units
convert_units()
Create a unit-conversion object.
Definition: convert_units.h:423
o2scl::convert_units::convert_cache
int convert_cache(std::string from, std::string to, fp_t val, fp_t &converted, fp_t &factor) const
Attempt to construct a conversion from the internal unit cache.
Definition: convert_units.h:301
o2scl_mks::week
const double week
s
Definition: constants.h:759
o2scl_mks::pound_force
const double pound_force
kg m / s^2
Definition: constants.h:831
o2scl_mks::solar_mass
const double solar_mass
Mass of the sun in kg.
Definition: constants.h:699
o2scl::convert_units::verbose
int verbose
Verbosity (default 0)
Definition: convert_units.h:477
o2scl::convert_units::convert
virtual fp_t convert(std::string from, std::string to, fp_t val)
Return the value val after converting using units from and to.
Definition: convert_units.h:439
o2scl_mks::hour
const double hour
s
Definition: constants.h:755
o2scl_mks::hectare
const double hectare
m^2
Definition: constants.h:783
o2scl_mks::bar
const double bar
kg / m s^2
Definition: constants.h:845
o2scl_mks::nuclear_magneton
const double nuclear_magneton
A m^2.
Definition: constants.h:905
o2scl_mks::calorie
const double calorie
kg m^2 / s^2
Definition: constants.h:837
o2scl_mks::footlambert
const double footlambert
cd sr / m^2
Definition: constants.h:877
o2scl_mks::stokes
const double stokes
m^2 / s
Definition: constants.h:861
o2scl_mks::inch_of_mercury
const double inch_of_mercury
kg / m s^2
Definition: constants.h:853
o2scl::convert_units::convert_const
virtual fp_t convert_const(std::string from, std::string to, fp_t val) const
Return the value val after converting using units from and to (const version)
Definition: convert_units.h:461
o2scl::convert_units::remove_cache
void remove_cache(std::string from, std::string to)
Manually remove a unit conversion into the cache.
Definition: convert_units.h:590
o2scl_mks::mass_neutron
const double mass_neutron
Neutron mass in kg.
Definition: constants.h:723
o2scl_mks::kilopound_force
const double kilopound_force
kg m / s^2
Definition: constants.h:833
o2scl_mks::vacuum_permeability
const double vacuum_permeability
Vacuum permeability in kg m / A^2 s^2 (being redefined as of 5/20, this value is from Wikipedia)
Definition: constants.h:912
o2scl_mks::mil
const double mil
m
Definition: constants.h:773
o2scl_const::o2scl_cgs
static const size_t o2scl_cgs
CGS units.
Definition: constants.h:87
o2scl_mks::lambert
const double lambert
cd sr / m^2
Definition: constants.h:875
o2scl_mks::gravitational_constant
const double gravitational_constant
Newtonian constant of gravitation in m^3 / kg s^2.
Definition: constants.h:668
o2scl::convert_units::print_cache
void print_cache() const
Print the present unit cache to std::cout.
Definition: convert_units.h:569
o2scl::exc_efilenotfound
@ exc_efilenotfound
File not found.
Definition: err_hnd.h:121
o2scl_mks::vacuum_permittivity
const double vacuum_permittivity
A^2 s^4 / kg m^3 (derived)
Definition: constants.h:907
o2scl_mks::rad
const double rad
m^2 / s^2
Definition: constants.h:881
o2scl_mks::bohr_radius
const double bohr_radius
Bohr radius in m.
Definition: constants.h:676
o2scl_mks::mass_proton
const double mass_proton
Proton mass in kg.
Definition: constants.h:721
o2scl_mks::foot
const double foot
m
Definition: constants.h:763
o2scl_mks::acre
const double acre
m^2
Definition: constants.h:785
o2scl::stod_nothrow
int stod_nothrow(std::string s, double &result)
Convert a string to a double returning non-zero value for failure.
o2scl_mks::roentgen
const double roentgen
A s / kg.
Definition: constants.h:901
o2scl_mks::meter_of_mercury
const double meter_of_mercury
kg / m s^2
Definition: constants.h:851
o2scl_mks::poise
const double poise
kg m^-1 s^-1
Definition: constants.h:859
o2scl_mks::fathom
const double fathom
m
Definition: constants.h:771
o2scl::convert_units::combine_two_conv
bool combine_two_conv
If true, allow combinations of two conversions (default true)
Definition: convert_units.h:490
o2scl::convert_units::unit_t::c
fp_t c
The conversion factor.
Definition: convert_units.h:118
o2scl_mks::nautical_mile
const double nautical_mile
m
Definition: constants.h:769
o2scl::convert_units
Convert units.
Definition: convert_units.h:105
O2SCL_ERR
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
o2scl::convert_units::convert_gnu_units
int convert_gnu_units(std::string from, std::string to, fp_t val, fp_t &converted, fp_t &factor, bool &new_conv) const
Attempt to use GNU units to perform a conversion.
Definition: convert_units.h:203
o2scl_mks::dyne
const double dyne
kg m / s^2
Definition: constants.h:885
o2scl_mks::phot
const double phot
cd sr / m^2
Definition: constants.h:871
o2scl_mks::plancks_constant_h
const double plancks_constant_h
Planck constant in kg m^2 / s.
Definition: constants.h:670
o2scl_mks::lumen
const double lumen
cd sr
Definition: constants.h:867
o2scl::convert_units::err_on_fail
bool err_on_fail
If true, throw an exception when a conversion fails (default true)
Definition: convert_units.h:487
o2scl_mks::yard
const double yard
m
Definition: constants.h:765
o2scl_mks::micron
const double micron
m
Definition: constants.h:779
o2scl_mks::teaspoon
const double teaspoon
m^3
Definition: constants.h:803
o2scl_const::o2scl_mks
static const size_t o2scl_mks
MKS units.
Definition: constants.h:85
o2scl::convert_units::unit_t
The type for caching unit conversions.
Definition: convert_units.h:112
o2scl_mks::torr
const double torr
kg / m s^2
Definition: constants.h:849
o2scl::convert_units::use_gnu_units
bool use_gnu_units
If true, use a system call to units to derive new conversions (default true)
Definition: convert_units.h:484
o2scl_mks::psi
const double psi
kg / m s^2
Definition: constants.h:857
o2scl_mks::metric_ton
const double metric_ton
kg
Definition: constants.h:821
o2scl::convert_units::insert_cache
void insert_cache(std::string from, std::string to, fp_t conv)
Manually insert a unit conversion into the cache.
Definition: convert_units.h:538
o2scl_mks::poundal
const double poundal
kg m / s^2
Definition: constants.h:835
o2scl::convert_units::unit_t::f
std::string f
The input unit.
Definition: convert_units.h:114
o2scl_mks::us_gallon
const double us_gallon
m^3
Definition: constants.h:791
o2scl_mks::liter
const double liter
m^3
Definition: constants.h:789
o2scl_cgs::solar_mass
const double solar_mass
Mass of the sun in g (from navy.mil)
Definition: constants.h:197
o2scl_mks::horsepower
const double horsepower
kg m^2 / s^3
Definition: constants.h:843
o2scl_mks::canadian_gallon
const double canadian_gallon
m^3
Definition: constants.h:805
o2scl_mks::footcandle
const double footcandle
cd sr / m^2
Definition: constants.h:873
o2scl_mks::barn
const double barn
m^2
Definition: constants.h:787
o2scl_mks::day
const double day
s
Definition: constants.h:757
o2scl_mks::stefan_boltzmann_constant
const double stefan_boltzmann_constant
Stefan-Boltzmann constant in kg / K^4 s^3.
Definition: constants.h:678
o2scl::convert_units::make_units_dat
void make_units_dat(std::string fname, bool c_1=false, bool hbar_1=false, bool K_1=false) const
Make a GNU units.dat file from the GSL constants.
Definition: convert_units.h:750

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).