Physical constants

QCElemental handles the precision by reading the NIST string into a Python Decimal object, which preserves the input decimal places. The resulting C and Fortran headers are thus consistent with NIST (psi4/physconst.h at master · psi4/psi4 · GitHub). Uncertainty is not used, except in the comment. I’m not finding specific notation, but ... indicates exact values. qcel does register constants with the Python units module pint, but that’s an effort to have self-consistent unit conversions w/i the CODATA set, rather than handling exact/derived.

I’ve supposed that the reason CODATA contains so many variations on derived constants is to guide users toward the number of sigfigs that NIST’s analysis of experimental precision and constants coupling (CODATA Values of the Fundamental Constants) indicates.

1 Like

Thank you for your reply @loriab ,

Thus with the molar gas constant case, any idea why https://github.com/psi4/psi4/blob/master/psi4/include/psi4/physconst.h#L394 shows in the C header:

but with the Fortran module, it has:

Psi4 is using codata 2014.

I generated the Fortran include for codata 2018.

Somehow, you are right (I’m doing something similar, in my physical constant module).
However, the exact fundamental constants change time to time. In 2018, the Avogadro number, NA, is exact, while in 2014 it was not exact …

Yes, the Avogadro number was (Avogadro constant - Wikipedia):

the number of particles that are contained in one mole

But now:

However, in its 26th Conference, the BIPM adopted a different approach: effective 20 May 2019, it defined the Avogadro number as the exact value N = 6.02214076×10^23, and redefined the mole as the amount of a substance under consideration that contains N constituent particles of the substance.

So, it was derived from the mole, and now the mole is derived from Avogadro’s number.

1 Like

From IUPAC

1 Like

@gardhor , do you agree with the following correction?
It seems you forgot to update b with the b-aint(b) result (it was just calculated in the test).

    pure integer function number_of_digits(a)
        real (kind=wp), intent(in) :: a
        real (kind=wp) :: b, c
        integer        :: i

        b = a
        i = 0
        do
            c = b-aint(b)
            if (c < 0.01_wp) exit
            i = i + 1
            b = c * 10._wp
        end do

        number_of_digits = i
    end function number_of_digits

I have incorporated your code in my local branch. And my Python script is now generating automatically a test.f90 file which tries to print the two first columns of the NIST file using the constants from the Fortran module. We must now validate the other part of your code.

Thanks, I though the update was not necessary. However as the old one, the new function fails for 5.142206747 63e11!

1 Like

With “ANINT”, instead of “AINT”, the function works better. However, it still has problems for number close to one (such, conventional_value_of_farad_90 and conventional_value_of_henry_90).

1 Like

On my side, number_of_digits() does not work with ANINT().

Anyway, if you add a print *, b statement in the loop, you see that rounding errors are propagating and it can be catastrophic.

conventional value of farad-90  0.999 999 982 20...      (exact)   F
conventional value of henry-90  1.000 000 017 79...

For the farad-90, the problem is that the nearest number in the IEEE-754 representation is:
0.99999998219999997...
In that case the nearest() function is helpful: nearest(0.99999998219999997d0, 1d0) yields 0.99999998220000008... (next IEEE 754 real) and the number_of_digits() function will stop because there is many trailing zeros.

Concerning henry-90 the problem is that the same function will also be stopped by the 7 zeros after the decimal point: 1.000 000 017 79

Oups… Corrected!
I wanted to write nearest(0.99999998219999997d0, 1d0) yields 0.99999998220000008.

You’re right. The print statement prints only 17 digits of those exact numbers. I’ve updated my original message with “…”

With those rounding effects, I think the Python script should give to the Fortran program two infos on each constants: for example numbers of digits to print at the left and at the right of the decimal point, or number of decimals and value of the exponent.

17 decimal digits are enough to unambiguously specify any IEEE-754 binary64 number.

3 Likes

I have pushed a v0.2 of my project. The Python script now writes a test.f90 which tries to print all constants using the CODATA format (two first columns). The Python script analyzes the format of each constant and test.f90 know of many decimals to print, and what exponent to use. The output is now very close to the CODATA style:

alpha particle-electron mass ratio                          7294.29954142            
alpha particle mass                                         6.6446573357E-27         
alpha particle mass energy equivalent                       5.9719201914E-10         
alpha particle mass energy equivalent in MeV                3727.3794066             
alpha particle mass in u                                    4.001506179127           
alpha particle molar mass                                   4.0015061777E-03
...

Most of the constants are written correctly. Very few problems remain, for example:

conventional value of Josephson constant                    4.8E+09

should be 483597.9e9. Let me know if you find others.

We need now a subroutine receiving a 25 characters string with the number and inserting spaces between groups of 3 digits, except when a digit would then be alone. The idea is to start from the decimal point and to scan firstly toward the left. Then scan toward the right. And before inserting a space, we must verify that there will be at least two digits after. A subroutine insert_space(string, position) which insert one space at the given position has already been pushed.

Updated 2021-03-20:
I am now very near my goal (not yet pushed on GitHub):

alpha particle-electron mass ratio                          7294.299 541 42          
alpha particle mass                                         6.644 657 3357 e-27      
alpha particle mass energy equivalent                       5.971 920 1914 e-10      
alpha particle mass energy equivalent in MeV                3727.379 4066            
alpha particle mass in u                                    4.001 506 179 127        
alpha particle molar mass                                   4.001 506 1777 e-03  

The Fortran program must now delete the zeros beginning the exponent: e-3 instead of e-03.
And a diff shows that all values are identical to the NIST file except for 6 constants (over 354). Need further analyze for those 6…

1 Like

I have released the v1.0:

The fortran_generated_????.txt file generated with fpm test is now nearly identical (concerning the first two columns) to the NIST file. A few constants are written differently because the NIST file don’t use the classical scientific format: for example, the molar mass of carbon-12 is written 1.199 999 999 58 e-2 in our file but 11.99 999 999 58 e-3 in the NIST file. But it is quick to verify that those values are correct. Some of the values in the NIST file can be calculated from other constants and are terminated by “…” in the NIST file: note that their values in the Fortran module are not calculated, but have the same number of digits as in the NIST file.

Finally I have used a graphical diff tool, meld, to compare the Fortran text files with the NIST files, in order to validate the Fortran modules. And I put the 2010, 2014 and 2018 modules in the directory:
https://github.com/vmagnin/fundamental_constants/tree/main/validated_modules

4 Likes

Does this mean I should start using this for the conversion factors and constants in my units system project?

1 Like

Fantastic! Here’s also Bob Apthorpe’s repo, with similar approach and result. One way or another, we’ll have a good candidate for physical constants in stdlib. :slight_smile:

2 Likes

I believe yes. I’ve seen so many scientific publications with wrong or too approximated physical conversion constants.

1 Like

Great job, I’ll use them in my codes.

1 Like