Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input parsing cleaning and PhysConsts from QCelemental #404

Merged
merged 75 commits into from
Apr 27, 2022

Conversation

Brakjen
Copy link
Contributor

@Brakjen Brakjen commented Mar 25, 2022

Summary of changes

On the Python side

  • Moved the molecule validations out from python/mrchem/api.py to a separate class MoleculeValidator in python/mrchem/validators.py. I think this makes the structure and flow of the input parsing a bit clearer and readable, and cleans the responsibility of api.py to converting from user.json to program.json (with some help from helpers.py)
  • Added support for reading physical constants from qcelemental. Now (almost) all constants are derived directly from NIST constants collected in CODATA2018.
  • The constants are added to the template file via the utility script python/mrchem/update_input_parser.py, which also runs parselglossy and syncs the user ref file. The user can therefore overwrite the constant defaults in the input file for their calculation.
  • The constants are passed to program.json in the constants field, so that the c++ code gains access to these
  • Notable differences in how the constants are defined in QCElemental and (old) MRChem:
    - electron g factor        : CODATA: -2.00231930436256
                                 MRChem:  2.0023193043618

    - fine structure constant  : CODATA: 7.2973525693e-3
                                 MRChem: 7.2973525664

    - au -> wavenumbers        : CODATA: 219474.6313632
                                 MRChem: 219471.5125976648

    - au -> debye              : CODATA: 2.5417464739297717
                               : MRChem: 2.54174623105

On the c++ side

  • Update the interface to physical constants. A new singleton class chemistry/PhysicalConstants has been created that stores the constants from program.json in a nlohmann::json object.

ToDo

  • Add set of constants to c++ so that unit tests pass

@stigrj
Copy link
Contributor

stigrj commented Mar 25, 2022

I believe this file python/mrchem/input_parser/plumbing/init.py should not be committed. It was the one causing problems before (reason still unknown). Are you now able to run with file in source?

@Brakjen
Copy link
Contributor Author

Brakjen commented Mar 25, 2022

Ah, that one slipped through. Very annoying. Why has this file started causing problems?

Another thing. The ANG_2_BOHR conversion factor is present both in helpers.py and CUBEparser.py. The cube parser cannot import from helpers due to circular import errors. A simple fix solution could be to collect the constants we use during input parsing in its own file, and import from there. Perhaps ideally python and c++ should access the same set of constants (this is perhaps what you mentioned in #171)

@Gabrielgerez
Copy link
Contributor

That li_solv has always had weird behavior, I'll check it out

@stigrj
Copy link
Contributor

stigrj commented Mar 25, 2022

@robertodr do you know why this file suddenly started to appear?

I think one nice way to handle the constants is to let Python define them and feed them into the C++ program through the JSON input. Then we also have complete control and can tweak the parameters without recompiling, by intercepting the input parser and edit the JSON file before execution.

@robertodr
Copy link
Contributor

@Andersmb Which version of pyparsing is installed locally? parselglossy cannot yet deal with v3 of that library, I think that's what you're seeing. I opened a PR sometime ago to fix that dev-cafe/parselglossy#109 Didn't get around to finishing it.

@robertodr
Copy link
Contributor

The quick solution is to ignore any change in that plumbing when committing.

@Brakjen
Copy link
Contributor Author

Brakjen commented Mar 25, 2022

The quick solution is to ignore any change in that plumbing when committing.

I have version 3.0.7 installed...

@robertodr
Copy link
Contributor

The quick solution is to ignore any change in that plumbing when committing.

I have version 3.0.7 installed...

Mystery understood then.

@Brakjen Brakjen added the WIP Work in progress label Mar 25, 2022
@Brakjen Brakjen marked this pull request as draft March 25, 2022 10:25
@Brakjen Brakjen force-pushed the molecule-class-cleanup-input-parser branch from 0aeaeb5 to 7960907 Compare March 28, 2022 07:05
@Brakjen
Copy link
Contributor Author

Brakjen commented Mar 28, 2022

@Gabrielgerez I discovered why the li_solv was failing. The Molecule.cavity_coords section had a duplicated sphere

"cavity_coords": [
        {
          "center": [
            0.0,
            0.0,
            0.0
          ],
          "radius": 4.0
        },
        {
          "center": [
            0.0,
            0.0,
            0.0
          ],
          "radius": 4.0
        }
      ]

Just deleting the extra sphere lead to a passing test.

@codecov
Copy link

codecov bot commented Mar 28, 2022

Codecov Report

Merging #404 (d135280) into master (c1959c6) will decrease coverage by 0.09%.
The diff coverage is 52.11%.

@@            Coverage Diff             @@
##           master     #404      +/-   ##
==========================================
- Coverage   68.14%   68.04%   -0.10%     
==========================================
  Files         180      182       +2     
  Lines       15170    15208      +38     
==========================================
+ Hits        10337    10349      +12     
- Misses       4833     4859      +26     
Impacted Files Coverage Δ
src/properties/Magnetizability.h 0.00% <0.00%> (ø)
src/qmoperators/one_electron/H_BM_dia.h 0.00% <0.00%> (ø)
src/qmoperators/one_electron/H_MB_dia.h 0.00% <0.00%> (ø)
src/qmoperators/one_electron/H_M_pso.h 0.00% <0.00%> (ø)
src/utils/print_utils.cpp 76.02% <0.00%> (-12.07%) ⬇️
src/chemistry/PhysicalConstants.cpp 50.00% <50.00%> (ø)
src/scf_solver/HelmholtzVector.cpp 92.98% <50.00%> (ø)
src/chemistry/PhysicalConstants.h 71.42% <71.42%> (ø)
src/analyticfunctions/HarmonicOscillatorFunction.h 100.00% <100.00%> (ø)
src/analyticfunctions/HydrogenFunction.cpp 61.34% <100.00%> (ø)
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c1959c6...d135280. Read the comment docs.

@Brakjen Brakjen marked this pull request as ready for review March 28, 2022 13:09
@stigrj
Copy link
Contributor

stigrj commented Apr 7, 2022

I see MRCPP's pi is used once in tests/qmfunctions/orbital_vector.cpp. Can you just replace all the pi's with mrcpp::pi and remove it from MRChem's constants?

@Brakjen
Copy link
Contributor Author

Brakjen commented Apr 7, 2022

Btw, I also added a PhysicalConstants::Print(int plevel) method (being called right after initialization in mrchem.cpp). I set the print threshold to zero, but I can increase it to 1.... The printout looks like this

===========================================================================
                 Physical Constants (truncated precision)
---------------------------------------------------------------------------
angstrom2bohrs                        =  1.88972612e+00
dipmom_au2debye                       =  2.54174647e+00
electron_g_factor                     = -2.00231930e+00
fine_structure_constant               =  7.29735257e-03
hartree2ev                            =  2.72113862e+01
hartree2kcalmol                       =  6.27509474e+02
hartree2kjmol                         =  2.62549964e+03
hartree2simagnetizability             =  7.89451185e+01
hartree2wavenumbers                   =  2.19474631e+05
light_speed                           =  1.37035999e+02
===========================================================================

@Brakjen Brakjen marked this pull request as ready for review April 7, 2022 15:11
@Brakjen Brakjen mentioned this pull request Apr 8, 2022
Comment on lines 56 to 57
"light_speed": user_dict["Constants"]["light_speed"],
"derivative": user_dict["Derivatives"]["zora"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not used in mrchem.x, light_speed is fetched directly form PhysicalConstants::get("ligth_speed") and derivative is taken as the MomentumOperator in the kinetic energy. So just remove these two parameters.

Comment on lines 145 to 164
First boundary vector for plot.
- name: B
type: List[float]
default: [0.0, 1.0, 0.0]
predicates:
- len(value) == 3
docstring: |
Second boundary vector for plot.
- name: C
type: List[float]
default: [0.0, 0.0, 1.0]
predicates:
- len(value) == 3
docstring: |
Third boundary vector for plot.
- name: MPI
docstring: |
Define MPI related parameters.
keywords:
- name: numerically_exact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the indentation has changed in the entire template.yml file, is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this must be an effect of the yaml->dict->yaml roundtrip with ruamel.yaml. There are some options for setting indentation - I can see if I can reproduce the original indentation scheme.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the following gets the old indentation (source: https://yaml.readthedocs.io/en/latest/detail.html#:~:text=yaml.indent(mapping%3D2%2C%20sequence%3D4%2C%20offset%3D2))

yaml.indent(sequence=4, mapping=2, offset=2)

Excerpt:

keywords:
  - name: world_prec
    type: float
    predicates:
      - 1.0e-10 < value < 1.0
    docstring: |
      Overall relative precision in the calculation.
  - name: world_size
    type: int
    default: -1
    predicates:
      - value <= 10
    docstring: |
      Total size of computational domain given as 2**(``world_size``). Always cubic
      and symmetric around the origin. Negative value means it will be computed
      from the molecular geometry.
  - name: world_unit
    type: str
    default: bohr
    predicates:
      - value.lower() in ["bohr", "angstrom"]
    docstring: |
      Length unit for *all* coordinates given in user input. Everything will be
      converted to atomic units (bohr) before the main executable is launched,
      so the JSON input is *always* given in bohrs.
  - name: world_origin
    type: List[float]
    default: [0.0, 0.0, 0.0]
    predicates:
      - len(value) == 3
    docstring: |
      Global gauge origin of the calculation.
sections:
  - name: Precisions
    docstring: |
      Define specific precision parameters.
    keywords:
      - name: nuclear_prec
        type: float
        default: user['world_prec']
        predicates:
          - 1.0e-10 < value < 1.0
        docstring: |
          Precision parameter used in smoothing and projection of nuclear potential.
      - name: poisson_prec
        type: float
        default: user['world_prec']
        predicates:
          - 1.0e-10 < value < 1.0
        docstring: |
          Precision parameter used in construction of Poisson operators.
      - name: exchange_prec
        type: float
        default: -1.0
        docstring: |
          Precision parameter used in construction of Exchange operators.
          Negative value means it will follow the dynamic precision in SCF.
      - name: helmholtz_prec
        type: float
        default: -1.0
        docstring: |
          Precision parameter used in construction of Helmholtz operators.
          Negative value means it will follow the dynamic precision in SCF.

src/mrchem.cpp Outdated
// Instantiate the physical constants singleton
PhysicalConstants::Initialize(con_inp);
int print_prec = json_inp["printer"]["print_prec"];
if (json_inp["printer"]["print_constants"]) PhysicalConstants::Print(print_prec);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the print_prec for this output. If you want to print it (print_constants == true), then you probably want the exact value that is used? There's also plenty of space on the line here, so I suggest we just fix it to print_prec = 14 decimal places here.

double val = item.value().get<double>();
print_utils::scalar(0, key, val, "", pprec, true);
}
mrcpp::print::separator(0, '=');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some more space between this output and the next:

mrcpp::print::separator(0, '=', 2);

@@ -122,7 +122,7 @@ void print_utils::coord(int level, const std::string &txt, const mrcpp::Coord<3>
void print_utils::scalar(int level, const std::string &txt, double val, const std::string &unit, int p, bool s) {
if (p < 0) p = Printer::getPrecision();
int w0 = Printer::getWidth() - 2;
int w1 = w0 * 2 / 9;
int w1 = w0 * 2 / 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This misaligned some of the :'s in the output, but with the old value the name hartree2simagnetizability becomes too long... Perhaps abbreviate magnetizability?



from pathlib import Path
from ruamel.yaml import YAML
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruamel.yaml not listed in dev-packages

@Brakjen
Copy link
Contributor Author

Brakjen commented Apr 25, 2022

I think all the suggested edits have been made.

Copy link
Contributor

@stigrj stigrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good to go now. I'm going to squash merge due to the large number of commits

@stigrj stigrj merged commit 82ee2b5 into MRChemSoft:master Apr 27, 2022
@Brakjen Brakjen deleted the molecule-class-cleanup-input-parser branch May 19, 2022 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants