diff --git a/docs/methods/machine_learning/mace.md b/docs/methods/machine_learning/mace.md index 25f8942b1e..7e3bf66da5 100644 --- a/docs/methods/machine_learning/mace.md +++ b/docs/methods/machine_learning/mace.md @@ -22,7 +22,6 @@ python create_cp2k_model.py my_mace.model --dtype float64 ``` This conversion only needs to be performed once on a machine with both `torch` and `mace` installed. - The resulting `*.pth` file uses the same tensor and metadata format as the NequIP interface (inputs `pos`, `edge_index`, `edge_cell_shift`, `cell`, `atom_types`; outputs `atomic_energy`, `forces`, `virial`) and embeds the metadata (`num_types`, `r_max`, `type_names`, `model_dtype`) that CP2K @@ -40,9 +39,6 @@ section within the `&NONBONDED` forcefield parameters: &MACE ATOMS Cu POT_FILE_NAME MACE/my_mace.model-cp2k.pth - UNIT_ENERGY eV - UNIT_FORCES eV*angstrom^-1 - UNIT_LENGTH angstrom &END MACE &END NONBONDED &END FORCEFIELD @@ -52,8 +48,6 @@ section within the `&NONBONDED` forcefield parameters: mapping to the model type list must be consistent with the coordinates in `&COORDS`/`&TOPOLOGY`. - [POT_FILE_NAME](#CP2K_INPUT.FORCE_EVAL.MM.FORCEFIELD.NONBONDED.MACE.POT_FILE_NAME): path to the exported MACE model. -- **`UNIT_*`**: define the units of the model's internal lengths, energies, and forces (standard - MACE models use eV / Angstrom). MACE is a message-passing model with a non-local receptive field. As with NequIP, the interface evaluates the full system on every MPI rank and divides the energy, forces, and virial by the number diff --git a/src/force_fields_input.F b/src/force_fields_input.F index aad8de2a90..1df71ce40d 100644 --- a/src/force_fields_input.F +++ b/src/force_fields_input.F @@ -135,9 +135,11 @@ CONTAINS SELECT CASE (ff_type%ff_type) CASE (do_ff_charmm, do_ff_amber, do_ff_g96, do_ff_g87) CALL section_vals_val_get(ff_section, "PARM_FILE_NAME", c_val=ff_type%ff_file_name) + IF (TRIM(ff_type%ff_file_name) == "") THEN CPABORT("Force Field Parameter's filename is empty! Please check your input file.") END IF + CASE (do_ff_undef) ! Do Nothing CASE DEFAULT @@ -554,6 +556,7 @@ CONTAINS ipbv%a(15) = 12917180227.21_dp ELSE IF (((at1(1:1) == 'O') .AND. (at2(1:1) == 'H')) .OR. & ((at1(1:1) == 'H') .AND. (at2(1:1) == 'O'))) THEN + ipbv%rcore = 2.95_dp ! a.u. ipbv%m = -0.004025691139759147_dp ! Hartree/a.u. @@ -615,6 +618,7 @@ CONTAINS ft%d = cp_unit_to_cp2k(0.499_dp, "eV*angstrom^8") ELSE IF (((at1(1:2) == 'NA') .AND. (at2(1:2) == 'CL')) .OR. & ((at1(1:2) == 'CL') .AND. (at2(1:2) == 'NA'))) THEN + ft%a = cp_unit_to_cp2k(1256.31_dp, "eV") ft%c = cp_unit_to_cp2k(7.00_dp, "eV*angstrom^6") ft%d = cp_unit_to_cp2k(8.676_dp, "eV*angstrom^8") @@ -851,8 +855,7 @@ CONTAINS TYPE(section_vals_type), POINTER :: section INTEGER, INTENT(IN) :: start - CHARACTER(LEN=default_string_length) :: pot_file_name, unit_energy, unit_forces, & - unit_length + CHARACTER(LEN=default_string_length) :: pot_file_name CHARACTER(LEN=default_string_length), & DIMENSION(:), POINTER :: atm_names INTEGER :: isec, jsec, n_items @@ -863,14 +866,12 @@ CONTAINS n_items = isec*n_items CALL section_vals_val_get(section, "ATOMS", c_vals=atm_names) CALL section_vals_val_get(section, "POT_FILE_NAME", c_val=pot_file_name) - CALL section_vals_val_get(section, "UNIT_LENGTH", c_val=unit_length) - CALL section_vals_val_get(section, "UNIT_ENERGY", c_val=unit_energy) - CALL section_vals_val_get(section, "UNIT_FORCES", c_val=unit_forces) mace%pot_file_name = discover_file(pot_file_name) - mace%unit_length = unit_length - mace%unit_forces = unit_forces - mace%unit_energy = unit_energy + ! MACE models use standardized units: Angstrom, eV and eV/Angstrom + mace%unit_length = "angstrom" + mace%unit_energy = "eV" + mace%unit_forces = "eV/Angstrom" ! MACE models are exported to speak the same metadata/tensor dialect as NequIP CALL read_nequip_data(mace) CALL check_cp2k_atom_names_in_torch(atm_names, mace%type_names_torch) @@ -1336,11 +1337,13 @@ CONTAINS ! Calculate p_inv the inverse of the matrix p p_inv(:, :) = 0.0_dp CALL invert_matrix(p, p_inv, eval_error) + IF (eval_error >= 1.0E-8_dp) THEN CALL cp_warn(__LOCATION__, & "The polynomial fit for the BUCK4RANGES potential is only accurate to "// & TRIM(cp_to_string(eval_error))) END IF + ! Get the 6 coefficients of the 5th-order polynomial -> x(1:6) ! and the 4 coefficients of the 3rd-order polynomial -> x(7:10) x(:) = MATMUL(p_inv(:, :), v(:)) diff --git a/src/input_cp2k_mm.F b/src/input_cp2k_mm.F index 4dbc348208..4938f9cfea 100644 --- a/src/input_cp2k_mm.F +++ b/src/input_cp2k_mm.F @@ -1520,35 +1520,13 @@ CONTAINS CALL keyword_create(keyword, __LOCATION__, name="POT_FILE_NAME", & variants=["MODEL_FILE_NAME"], & - description="Specifies the filename that contains the exported MACE model.", & + description="Specifies the filename that contains the exported MACE model. "// & + "MACE models use standardized units (Angstrom for length, eV for energy, "// & + "eV/Angstrom for forces), so no unit keywords are required.", & usage="POT_FILE_NAME {FILENAME}", default_lc_val=" ") CALL section_add_keyword(section, keyword) CALL keyword_release(keyword) - CALL keyword_create(keyword, __LOCATION__, name="UNIT_LENGTH", & - description="Units of length in the MACE model file. "// & - "The units of positions, cell, energies and forces must be self-consistent: "// & - "e.g. coordinates in Angstrom, energies in eV, forces in eV/Angstrom. ", & - usage="UNIT_LENGTH angstrom", default_c_val="angstrom") - CALL section_add_keyword(section, keyword) - CALL keyword_release(keyword) - - CALL keyword_create(keyword, __LOCATION__, name="UNIT_ENERGY", & - description="Units of energy in the MACE model file. "// & - "The units of positions, energies and forces must be self-consistent: "// & - "e.g. coordinates in Angstrom, energies in eV, forces in eV/Angstrom. ", & - usage="UNIT_ENERGY hartree", default_c_val="eV") - CALL section_add_keyword(section, keyword) - CALL keyword_release(keyword) - - CALL keyword_create(keyword, __LOCATION__, name="UNIT_FORCES", & - description="Units of the forces in the MACE model file. "// & - "The units of positions, energies and forces must be self-consistent: "// & - "e.g. coordinates in Angstrom, energies in eV, forces in eV/Angstrom. ", & - usage="UNIT_FORCES hartree/bohr", default_c_val="eV/Angstrom") - CALL section_add_keyword(section, keyword) - CALL keyword_release(keyword) - END SUBROUTINE create_MACE_section ! ************************************************************************************************** diff --git a/tests/Fist/regtest-mace/mace_test.inp b/tests/Fist/regtest-mace/mace_test.inp index f0778b0397..feabc680c5 100644 --- a/tests/Fist/regtest-mace/mace_test.inp +++ b/tests/Fist/regtest-mace/mace_test.inp @@ -13,9 +13,6 @@ &MACE ATOMS Cu POT_FILE_NAME MACE/MACE_scratch_run-3.model-cp2k.pth - UNIT_ENERGY eV - UNIT_FORCES eV*angstrom^-1 - UNIT_LENGTH angstrom &END MACE &END NONBONDED &END FORCEFIELD @@ -33,7 +30,8 @@ &END PRINT &SUBSYS &CELL - ABC 7.230000 7.230000 7.230000 + CELL_FILE_FORMAT XYZ + CELL_FILE_NAME ./mace-test.xyz &END CELL &TOPOLOGY COORD_FILE_FORMAT XYZ