diff --git a/data/Allegro/si-deployed.pth b/data/Allegro/si-deployed.pth new file mode 100644 index 0000000000..1cd95d2d63 Binary files /dev/null and b/data/Allegro/si-deployed.pth differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d871fe2aca..1a22c70205 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -295,6 +295,7 @@ list( manybody_eam.F manybody_gal21.F manybody_gal.F + manybody_allegro.F manybody_nequip.F manybody_potential.F manybody_quip.F diff --git a/src/common/bibliography.F b/src/common/bibliography.F index 96e7bb2670..3c7b52f3a5 100644 --- a/src/common/bibliography.F +++ b/src/common/bibliography.F @@ -90,7 +90,7 @@ MODULE bibliography Behler2007, Behler2011, Schran2020a, Schran2020b, & Rycroft2009, Thomas2015, Brehm2018, Brehm2020, Shigeta2001, Heinecke2016, & Brehm2021, Bussy2021a, Bussy2021b, Ditler2021, Ditler2022, Mattiat2019, Mattiat2022, & - Belleflamme2023, Knizia2013 + Belleflamme2023, Knizia2013, Musaelian2023 CONTAINS @@ -224,7 +224,7 @@ CONTAINS "SO Nature Communications", & "PY 2022", & "VL 13", & - "IS 1", & + "AR 2453", & "ER"), & DOI="10.1038/s41467-022-29939-5") @@ -4822,6 +4822,24 @@ CONTAINS "ER"), & DOI="10.1021/ct400687b") + CALL add_reference(key=Musaelian2023, ISI_record=s2a( & + "PT J", & + " Musaelian, A", & + " Batzner, S", & + " Johansson, A", & + " Sun, L", & + " Owen, CJ", & + " Kornbluth, M", & + " Kozinsky, B", & + "TI Learning local equivariant representations for large-scale", & + " atomistic dynamice", & + "SO Nature Communications", & + "PY 2023", & + "VL 14", & + "AR 579", & + "ER"), & + DOI="10.1038/s41467-023-36329-y") + END SUBROUTINE add_all_references END MODULE bibliography diff --git a/src/fist_neighbor_list_control.F b/src/fist_neighbor_list_control.F index e590690946..9491d90b62 100644 --- a/src/fist_neighbor_list_control.F +++ b/src/fist_neighbor_list_control.F @@ -39,7 +39,8 @@ MODULE fist_neighbor_list_control section_vals_val_get USE kinds, ONLY: dp USE message_passing, ONLY: mp_para_env_type - USE pair_potential_types, ONLY: gal21_type,& + USE pair_potential_types, ONLY: allegro_type,& + gal21_type,& gal_type,& nequip_type,& pair_potential_pp_type,& @@ -231,6 +232,9 @@ CONTAINS IF (ANY(potparm%pot(ikind, jkind)%pot%type == nequip_type)) THEN full_nl(ikind, jkind) = .TRUE. END IF + IF (ANY(potparm%pot(ikind, jkind)%pot%type == allegro_type)) THEN + full_nl(ikind, jkind) = .TRUE. + END IF full_nl(jkind, ikind) = full_nl(ikind, jkind) END DO END DO diff --git a/src/fist_nonbond_env_types.F b/src/fist_nonbond_env_types.F index 72645910f5..645ccaba5c 100644 --- a/src/fist_nonbond_env_types.F +++ b/src/fist_nonbond_env_types.F @@ -36,7 +36,7 @@ MODULE fist_nonbond_env_types PUBLIC :: fist_nonbond_env_type, fist_nonbond_env_set, & fist_nonbond_env_get, fist_nonbond_env_create, & fist_nonbond_env_release, pos_type, eam_type, & - quip_data_type, nequip_data_type + quip_data_type, nequip_data_type, allegro_data_type ! ************************************************************************************************** TYPE pos_type @@ -60,6 +60,13 @@ MODULE fist_nonbond_env_types TYPE(torch_model_type) :: model END TYPE + TYPE allegro_data_type + INTEGER, POINTER :: use_indices(:) + REAL(KIND=dp), POINTER :: force(:, :) + REAL(KIND=dp) :: virial(3, 3) + TYPE(torch_model_type) :: model + END TYPE + ! ************************************************************************************************** TYPE fist_nonbond_env_type INTEGER :: natom_types @@ -80,6 +87,7 @@ MODULE fist_nonbond_env_types TYPE(eam_type), DIMENSION(:), POINTER :: eam_data TYPE(quip_data_type), POINTER :: quip_data TYPE(nequip_data_type), POINTER :: nequip_data + TYPE(allegro_data_type), POINTER :: allegro_data END TYPE fist_nonbond_env_type CONTAINS @@ -111,6 +119,7 @@ CONTAINS !> \param eam_data ... !> \param quip_data ... !> \param nequip_data ... +!> \param allegro_data ... !> \param charges ... !> \par History !> 12.2002 created [fawzi] @@ -121,7 +130,7 @@ CONTAINS shift_cutoff, r_last_update, r_last_update_pbc, rshell_last_update_pbc, & rcore_last_update_pbc, cell_last_update, num_update, last_update, & counter, natom_types, long_range_correction, ij_kind_full_fac, eam_data, & - quip_data, nequip_data, charges) + quip_data, nequip_data, allegro_data, charges) TYPE(fist_nonbond_env_type), INTENT(IN) :: fist_nonbond_env TYPE(pair_potential_pp_type), OPTIONAL, POINTER :: potparm14, potparm @@ -140,6 +149,7 @@ CONTAINS TYPE(eam_type), DIMENSION(:), OPTIONAL, POINTER :: eam_data TYPE(quip_data_type), OPTIONAL, POINTER :: quip_data TYPE(nequip_data_type), OPTIONAL, POINTER :: nequip_data + TYPE(allegro_data_type), OPTIONAL, POINTER :: allegro_data REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: charges IF (PRESENT(charges)) charges => fist_nonbond_env%charges @@ -147,6 +157,7 @@ CONTAINS IF (PRESENT(eam_data)) eam_data => fist_nonbond_env%eam_data IF (PRESENT(quip_data)) quip_data => fist_nonbond_env%quip_data IF (PRESENT(nequip_data)) nequip_data => fist_nonbond_env%nequip_data + IF (PRESENT(allegro_data)) allegro_data => fist_nonbond_env%allegro_data IF (PRESENT(potparm)) potparm => fist_nonbond_env%potparm IF (PRESENT(rlist_cut)) rlist_cut => fist_nonbond_env%rlist_cut IF (PRESENT(rlist_lowsq)) rlist_lowsq => fist_nonbond_env%rlist_lowsq @@ -202,6 +213,7 @@ CONTAINS !> \param eam_data ... !> \param quip_data ... !> \param nequip_data ... +!> \param allegro_data ... !> \param charges ... !> \par History !> 12.2002 created [fawzi] @@ -212,7 +224,7 @@ CONTAINS shift_cutoff, r_last_update, r_last_update_pbc, rshell_last_update_pbc, & rcore_last_update_pbc, cell_last_update, num_update, last_update, & counter, natom_types, long_range_correction, eam_data, quip_data, & - nequip_data, charges) + nequip_data, allegro_data, charges) TYPE(fist_nonbond_env_type), INTENT(INOUT) :: fist_nonbond_env TYPE(pair_potential_pp_type), OPTIONAL, POINTER :: potparm14, potparm @@ -230,12 +242,14 @@ CONTAINS TYPE(eam_type), DIMENSION(:), OPTIONAL, POINTER :: eam_data TYPE(quip_data_type), OPTIONAL, POINTER :: quip_data TYPE(nequip_data_type), OPTIONAL, POINTER :: nequip_data + TYPE(allegro_data_type), OPTIONAL, POINTER :: allegro_data REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: charges IF (PRESENT(potparm14)) fist_nonbond_env%potparm14 => potparm14 IF (PRESENT(eam_data)) fist_nonbond_env%eam_data => eam_data IF (PRESENT(quip_data)) fist_nonbond_env%quip_data => quip_data IF (PRESENT(nequip_data)) fist_nonbond_env%nequip_data => nequip_data + IF (PRESENT(allegro_data)) fist_nonbond_env%allegro_data => allegro_data IF (PRESENT(potparm)) fist_nonbond_env%potparm => potparm IF (PRESENT(rlist_cut)) fist_nonbond_env%rlist_cut => rlist_cut IF (PRESENT(charges)) fist_nonbond_env%charges => charges @@ -306,6 +320,7 @@ CONTAINS NULLIFY (fist_nonbond_env%eam_data) NULLIFY (fist_nonbond_env%quip_data) NULLIFY (fist_nonbond_env%nequip_data) + NULLIFY (fist_nonbond_env%allegro_data) NULLIFY (fist_nonbond_env%charges) CALL init_fist_nonbond_env(fist_nonbond_env, atomic_kind_set, potparm14, & potparm, do_nonbonded, verlet_skin, ewald_rcut, ei_scale14, vdw_scale14, & @@ -499,6 +514,16 @@ CONTAINS CALL torch_model_release(fist_nonbond_env%nequip_data%model) DEALLOCATE (fist_nonbond_env%nequip_data) END IF + IF (ASSOCIATED(fist_nonbond_env%allegro_data)) THEN + IF (ASSOCIATED(fist_nonbond_env%allegro_data%force)) THEN + DEALLOCATE (fist_nonbond_env%allegro_data%force) + END IF + IF (ASSOCIATED(fist_nonbond_env%allegro_data%use_indices)) THEN + DEALLOCATE (fist_nonbond_env%allegro_data%use_indices) + END IF + CALL torch_model_release(fist_nonbond_env%allegro_data%model) + DEALLOCATE (fist_nonbond_env%allegro_data) + END IF IF (ASSOCIATED(fist_nonbond_env%rshell_last_update_pbc)) THEN DEALLOCATE (fist_nonbond_env%rshell_last_update_pbc) END IF diff --git a/src/fist_nonbond_force.F b/src/fist_nonbond_force.F index 915f5efa1c..87b91f27cf 100644 --- a/src/fist_nonbond_force.F +++ b/src/fist_nonbond_force.F @@ -38,8 +38,8 @@ MODULE fist_nonbond_force USE message_passing, ONLY: mp_comm_type USE pair_potential_coulomb, ONLY: potential_coulomb USE pair_potential_types, ONLY: & - gal21_type, gal_type, nequip_type, nosh_nosh, nosh_sh, pair_potential_pp_type, & - pair_potential_single_type, sh_sh, siepmann_type, tersoff_type + allegro_type, gal21_type, gal_type, nequip_type, nosh_nosh, nosh_sh, & + pair_potential_pp_type, pair_potential_single_type, sh_sh, siepmann_type, tersoff_type USE particle_types, ONLY: particle_type USE shell_potential_types, ONLY: get_shell,& shell_kind_type @@ -229,7 +229,7 @@ CONTAINS fac_vdw = fac_kind full_nl = ANY(pot%type == tersoff_type) .OR. ANY(pot%type == siepmann_type) & .OR. ANY(pot%type == gal_type) .OR. ANY(pot%type == gal21_type) & - .OR. ANY(pot%type == nequip_type) + .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) IF ((.NOT. full_nl) .AND. (atom_a == atom_b)) THEN fac_ei = 0.5_dp*fac_ei fac_vdw = 0.5_dp*fac_vdw @@ -728,7 +728,7 @@ CONTAINS fac_ei = ij_kind_full_fac(kind_a, kind_b) full_nl = ANY(pot%type == tersoff_type) .OR. ANY(pot%type == siepmann_type) & .OR. ANY(pot%type == gal_type) .OR. ANY(pot%type == gal21_type) & - .OR. ANY(pot%type == nequip_type) + .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) IF ((.NOT. full_nl) .AND. (atom_a == atom_b)) THEN fac_ei = fac_ei*0.5_dp END IF diff --git a/src/force_fields_all.F b/src/force_fields_all.F index c4af99136b..3a06f1375c 100644 --- a/src/force_fields_all.F +++ b/src/force_fields_all.F @@ -64,7 +64,7 @@ MODULE force_fields_all spline_nonbond_control USE pair_potential_coulomb, ONLY: potential_coulomb USE pair_potential_types, ONLY: & - ea_type, lj_charmm_type, lj_type, nequip_type, nn_type, nosh_nosh, nosh_sh, & + allegro_type, ea_type, lj_charmm_type, lj_type, nequip_type, nn_type, nosh_nosh, nosh_sh, & pair_potential_lj_create, pair_potential_pp_create, pair_potential_pp_type, & pair_potential_single_add, pair_potential_single_clean, pair_potential_single_copy, & pair_potential_single_type, quip_type, sh_sh, siepmann_type, tersoff_type @@ -2040,7 +2040,8 @@ CONTAINS IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. & atmname == inp_info%nonbonded%pot(j)%pot%at2) THEN SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1)) - CASE (ea_type, tersoff_type, siepmann_type, quip_type, nequip_type) + CASE (ea_type, tersoff_type, siepmann_type, quip_type, nequip_type, & + allegro_type) ! Charge is zero for EAM, TERSOFF and SIEPMANN type potential ! Do nothing.. CASE DEFAULT diff --git a/src/force_fields_input.F b/src/force_fields_input.F index 6e2bb080ca..d45bff8a8c 100644 --- a/src/force_fields_input.F +++ b/src/force_fields_input.F @@ -65,11 +65,12 @@ MODULE force_fields_input USE memory_utilities, ONLY: reallocate USE message_passing, ONLY: mp_para_env_type USE pair_potential_types, ONLY: & - b4_type, bm_type, do_potential_single_allocation, ea_type, eam_pot_type, ft_pot_type, & - ft_type, ftd_type, gal21_type, gal_type, gp_type, gw_type, ip_type, ipbv_pot_type, & - lj_charmm_type, nequip_pot_type, nequip_type, no_potential_single_allocation, & - pair_potential_p_type, pair_potential_reallocate, potential_single_allocation, quip_type, & - siepmann_type, tab_pot_type, tab_type, tersoff_type, wl_type + allegro_pot_type, allegro_type, b4_type, bm_type, do_potential_single_allocation, ea_type, & + eam_pot_type, ft_pot_type, ft_type, ftd_type, gal21_type, gal_type, gp_type, gw_type, & + ip_type, ipbv_pot_type, lj_charmm_type, nequip_pot_type, nequip_type, & + no_potential_single_allocation, pair_potential_p_type, pair_potential_reallocate, & + potential_single_allocation, quip_type, siepmann_type, tab_pot_type, tab_type, & + tersoff_type, wl_type USE shell_potential_types, ONLY: shell_p_create,& shell_p_type USE string_utilities, ONLY: uppercase @@ -105,9 +106,9 @@ CONTAINS CHARACTER(LEN=default_string_length), & DIMENSION(:), POINTER :: atm_names - INTEGER :: nb4, nbends, nbm, nbmhft, nbmhftd, nbonds, nchg, neam, ngal, ngal21, ngd, ngp, & - nimpr, nipbv, nlj, nnequip, nopbend, nquip, nshell, nsiepmann, ntab, ntersoff, ntors, & - ntot, nubs, nwl + INTEGER :: nallegro, nb4, nbends, nbm, nbmhft, nbmhftd, nbonds, nchg, neam, ngal, ngal21, & + ngd, ngp, nimpr, nipbv, nlj, nnequip, nopbend, nquip, nshell, nsiepmann, ntab, ntersoff, & + ntors, ntot, nubs, nwl LOGICAL :: explicit, unique_spline REAL(KIND=dp) :: min_eps_spline_allowed TYPE(input_info_type), POINTER :: inp_info @@ -296,10 +297,22 @@ CONTAINS CALL read_nequip_section(inp_info%nonbonded, tmp_section2, ntot) END IF + tmp_section2 => section_vals_get_subs_vals(tmp_section, "allegro") + CALL section_vals_get(tmp_section2, explicit=explicit, n_repetition=nallegro) + ntot = nlj + nwl + neam + ngd + nipbv + nbmhft + nbmhftd + nb4 + nbm + ngp + ntersoff + ngal + ngal21 + nsiepmann + & + nquip + nnequip + IF (explicit) THEN + ! avoid repeating the allegro section for each pair + CALL section_vals_val_get(tmp_section2, "ATOMS", c_vals=atm_names) + nallegro = nallegro - 1 + SIZE(atm_names) + (SIZE(atm_names)*SIZE(atm_names) - SIZE(atm_names))/2 + CALL pair_potential_reallocate(inp_info%nonbonded, 1, ntot + nallegro, allegro=.TRUE.) + CALL read_allegro_section(inp_info%nonbonded, tmp_section2, ntot) + END IF + tmp_section2 => section_vals_get_subs_vals(tmp_section, "TABPOT") CALL section_vals_get(tmp_section2, explicit=explicit, n_repetition=ntab) ntot = nlj + nwl + neam + ngd + nipbv + nbmhft + nbmhftd + nb4 + nbm + ngp + ntersoff + ngal + ngal21 + nsiepmann + & - nquip + nnequip + nquip + nnequip + nallegro IF (explicit) THEN CALL pair_potential_reallocate(inp_info%nonbonded, 1, ntot + ntab, tab=.TRUE.) CALL read_tabpot_section(inp_info%nonbonded, tmp_section2, ntot, para_env, mm_section) @@ -737,6 +750,54 @@ CONTAINS END SUBROUTINE read_nequip_section +! ************************************************************************************************** +!> \brief Reads the ALLEGRO section +!> \param nonbonded ... +!> \param section ... +!> \param start ... +!> \author teo +! ************************************************************************************************** + SUBROUTINE read_allegro_section(nonbonded, section, start) + TYPE(pair_potential_p_type), POINTER :: nonbonded + TYPE(section_vals_type), POINTER :: section + INTEGER, INTENT(IN) :: start + + CHARACTER(LEN=default_string_length) :: allegro_file_name, unit_cell, & + unit_coords, unit_energy, unit_forces + CHARACTER(LEN=default_string_length), & + DIMENSION(:), POINTER :: atm_names + INTEGER :: isec, jsec, n_items + + n_items = 1 + isec = 1 + n_items = isec*n_items + CALL section_vals_val_get(section, "ATOMS", c_vals=atm_names) + CALL section_vals_val_get(section, "PARM_FILE_NAME", c_val=allegro_file_name) + CALL section_vals_val_get(section, "UNIT_COORDS", c_val=unit_coords) + CALL section_vals_val_get(section, "UNIT_ENERGY", c_val=unit_energy) + CALL section_vals_val_get(section, "UNIT_FORCES", c_val=unit_forces) + CALL section_vals_val_get(section, "UNIT_CELL", c_val=unit_cell) + + DO isec = 1, SIZE(atm_names) + DO jsec = isec, SIZE(atm_names) + nonbonded%pot(start + n_items)%pot%type = allegro_type + nonbonded%pot(start + n_items)%pot%at1 = atm_names(isec) + nonbonded%pot(start + n_items)%pot%at2 = atm_names(jsec) + CALL uppercase(nonbonded%pot(start + n_items)%pot%at1) + CALL uppercase(nonbonded%pot(start + n_items)%pot%at2) + nonbonded%pot(start + n_items)%pot%set(1)%allegro%allegro_file_name = discover_file(allegro_file_name) + nonbonded%pot(start + n_items)%pot%set(1)%allegro%unit_coords = unit_coords + nonbonded%pot(start + n_items)%pot%set(1)%allegro%unit_forces = unit_forces + nonbonded%pot(start + n_items)%pot%set(1)%allegro%unit_energy = unit_energy + nonbonded%pot(start + n_items)%pot%set(1)%allegro%unit_cell = unit_cell + CALL read_allegro_data(nonbonded%pot(start + n_items)%pot%set(1)%allegro) + nonbonded%pot(start + n_items)%pot%rcutsq = nonbonded%pot(start + n_items)%pot%set(1)%allegro%rcutsq + n_items = n_items + 1 + END DO + END DO + + END SUBROUTINE read_allegro_section + ! ************************************************************************************************** !> \brief Reads the LJ section !> \param nonbonded ... @@ -2338,6 +2399,37 @@ CONTAINS CALL timestop(handle) END SUBROUTINE read_nequip_data +! ************************************************************************************************** +!> \brief reads ALLEGRO potential from .pth file +!> \param allegro ... +! ************************************************************************************************** + SUBROUTINE read_allegro_data(allegro) + TYPE(allegro_pot_type), POINTER :: allegro + + CHARACTER(len=*), PARAMETER :: routineN = 'read_allegro_data' + + CHARACTER(LEN=default_path_length) :: cutoff_str + INTEGER :: handle + + CALL timeset(routineN, handle) + + allegro%allegro_version = torch_model_read_metadata(allegro%allegro_file_name, "nequip_version") + cutoff_str = torch_model_read_metadata(allegro%allegro_file_name, "r_max") + READ (cutoff_str, *) allegro%rcutsq + allegro%rcutsq = cp_unit_to_cp2k(allegro%rcutsq, allegro%unit_coords) + allegro%rcutsq = allegro%rcutsq*allegro%rcutsq + allegro%unit_coords_val = 1.0_dp + allegro%unit_coords_val = cp_unit_to_cp2k(allegro%unit_coords_val, allegro%unit_coords) + allegro%unit_forces_val = 1.0_dp + allegro%unit_forces_val = cp_unit_to_cp2k(allegro%unit_forces_val, allegro%unit_forces) + allegro%unit_energy_val = 1.0_dp + allegro%unit_energy_val = cp_unit_to_cp2k(allegro%unit_energy_val, allegro%unit_energy) + allegro%unit_cell_val = 1.0_dp + allegro%unit_cell_val = cp_unit_to_cp2k(allegro%unit_cell_val, allegro%unit_cell) + + CALL timestop(handle) + END SUBROUTINE read_allegro_data + ! ************************************************************************************************** !> \brief reads TABPOT potential from file !> \param tab ... diff --git a/src/input_cp2k_mm.F b/src/input_cp2k_mm.F index 5f17304991..3a2fa068c6 100644 --- a/src/input_cp2k_mm.F +++ b/src/input_cp2k_mm.F @@ -16,7 +16,7 @@ MODULE input_cp2k_mm USE bibliography, ONLY: & Batzner2022, Clabaut2020, Clabaut2021, Devynck2012, Dick1958, Foiles1986, Mitchell1993, & - QUIP_ref, Siepmann1995, Tersoff1988, Tosi1964a, Tosi1964b, Yamada2000 + Musaelian2023, QUIP_ref, Siepmann1995, Tersoff1988, Tosi1964a, Tosi1964b, Yamada2000 USE cp_output_handling, ONLY: cp_print_key_section_create,& debug_print_level,& high_print_level,& @@ -1174,6 +1174,10 @@ CONTAINS CALL section_add_subsection(section, subsection) CALL section_release(subsection) + CALL create_ALLEGRO_section(subsection) + CALL section_add_subsection(section, subsection) + CALL section_release(subsection) + CALL create_Goodwin_section(subsection) CALL section_add_subsection(section, subsection) CALL section_release(subsection) @@ -1467,9 +1471,8 @@ CONTAINS CPASSERT(.NOT. ASSOCIATED(section)) CALL section_create(section, __LOCATION__, name="NEQUIP", & - description="This section specifies the input parameters for NEQUIP potential type. "// & - "neural network potentials "// & - "to achieve correlated-wavefunction-like accuracy. "// & + description="This section specifies the input parameters for NEQUIP potential type "// & + "based on equivariant neural networks with message passing. "// & "Requires linking with libtorch library from https://pytorch.org/cppdocs/installing.html .", & citations=(/Batzner2022/), n_keywords=1, n_subsections=0, repeats=.FALSE.) @@ -1517,6 +1520,67 @@ CONTAINS END SUBROUTINE create_NEQUIP_section +! ************************************************************************************************** +!> \brief This section specifies the input parameters for ALLEGRO potential type +!> \param section the section to create +!> \author teo +! ************************************************************************************************** + SUBROUTINE create_ALLEGRO_section(section) + TYPE(section_type), POINTER :: section + + TYPE(keyword_type), POINTER :: keyword + + CPASSERT(.NOT. ASSOCIATED(section)) + CALL section_create(section, __LOCATION__, name="ALLEGRO", & + description="This section specifies the input parameters for ALLEGRO potential type "// & + "based on equivariant neural network potentials. "// & + "Requires linking with libtorch library from https://pytorch.org/cppdocs/installing.html .", & + citations=(/Musaelian2023/), n_keywords=1, n_subsections=0, repeats=.FALSE.) + + NULLIFY (keyword) + + CALL keyword_create(keyword, __LOCATION__, name="ATOMS", & + description="Defines the atomic kinds involved in the ALLEGRO potential. "// & + "Provide a list of each element.", & + usage="ATOMS {KIND 1} {KIND 2} .. {KIND N}", type_of_var=char_t, & + n_var=-1) + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + + CALL keyword_create(keyword, __LOCATION__, name="PARM_FILE_NAME", & + variants=(/"PARMFILE"/), & + description="Specifies the filename that contains the ALLEGRO model.", & + usage="PARM_FILE_NAME {FILENAME}", default_lc_val="model.pth") + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + + CALL keyword_create(keyword, __LOCATION__, name="UNIT_COORDS", & + description="Units of coordinates in the ALLEGRO model.pth file.", & + usage="UNIT 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 ALLEGRO model.pth file.", & + usage="UNIT hartree", default_c_val="hartree") + 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 ALLEGRO model.pth file.", & + usage="UNIT hartree/bohr", default_c_val="hartree/bohr") + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + + CALL keyword_create(keyword, __LOCATION__, name="UNIT_CELL", & + description="Units of the cell vectors in the ALLEGRO model.pth file.", & + usage="UNIT angstrom", default_c_val="angstrom") + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + + END SUBROUTINE create_ALLEGRO_section + ! ************************************************************************************************** !> \brief This section specifies the input parameters for Lennard-Jones potential type !> \param section the section to create diff --git a/src/manybody_allegro.F b/src/manybody_allegro.F new file mode 100644 index 0000000000..131624e910 --- /dev/null +++ b/src/manybody_allegro.F @@ -0,0 +1,469 @@ +!--------------------------------------------------------------------------------------------------! +! CP2K: A general program to perform molecular dynamics simulations ! +! Copyright 2000-2023 CP2K developers group ! +! ! +! SPDX-License-Identifier: GPL-2.0-or-later ! +!--------------------------------------------------------------------------------------------------! + +! ************************************************************************************************** +!> \par History +!> allegro implementation +!> \author Gabriele Tocci +! ************************************************************************************************** +MODULE manybody_allegro + + USE atomic_kind_types, ONLY: atomic_kind_type + USE cell_types, ONLY: cell_type + USE fist_neighbor_list_types, ONLY: fist_neighbor_type,& + neighbor_kind_pairs_type + USE fist_nonbond_env_types, ONLY: allegro_data_type,& + fist_nonbond_env_get,& + fist_nonbond_env_set,& + fist_nonbond_env_type,& + pos_type + USE kinds, ONLY: dp,& + int_8,& + sp + USE pair_potential_types, ONLY: allegro_pot_type,& + allegro_type,& + pair_potential_pp_type,& + pair_potential_single_type + USE particle_types, ONLY: particle_type + USE torch_api, ONLY: torch_dict_create,& + torch_dict_get,& + torch_dict_insert,& + torch_dict_release,& + torch_dict_type,& + torch_model_eval,& + torch_model_load + USE util, ONLY: sort +#include "./base/base_uses.f90" + + IMPLICIT NONE + + PRIVATE + PUBLIC :: setup_allegro_arrays, destroy_allegro_arrays, & + allegro_energy_store_force_virial, allegro_add_force_virial + CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_allegro' + +CONTAINS + +! ************************************************************************************************** +!> \brief ... +!> \param nonbonded ... +!> \param potparm ... +!> \param glob_loc_list ... +!> \param glob_cell_v ... +!> \param glob_loc_list_a ... +!> \param unique_list_a ... +!> \param cell ... +!> \par History +!> Implementation of the allegro potential - [gtocci] 2023 +!> \author Gabriele Tocci - University of Zurich +! ************************************************************************************************** + SUBROUTINE setup_allegro_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, & + unique_list_a, cell) + TYPE(fist_neighbor_type), POINTER :: nonbonded + TYPE(pair_potential_pp_type), POINTER :: potparm + INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list + REAL(KIND=dp), DIMENSION(:, :), POINTER :: glob_cell_v + INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, unique_list_a + TYPE(cell_type), POINTER :: cell + + CHARACTER(LEN=*), PARAMETER :: routineN = 'setup_allegro_arrays' + + INTEGER :: handle, i, iend, igrp, ikind, ilist, & + ipair, istart, jkind, nkinds, nlocal, & + npairs, npairs_tot + INTEGER, ALLOCATABLE, DIMENSION(:) :: temp_unique_list_a, work_list, work_list2 + INTEGER, DIMENSION(:, :), POINTER :: list + REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: rwork_list + REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi + TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair + TYPE(pair_potential_single_type), POINTER :: pot + + CPASSERT(.NOT. ASSOCIATED(glob_loc_list)) + CPASSERT(.NOT. ASSOCIATED(glob_loc_list_a)) + CPASSERT(.NOT. ASSOCIATED(unique_list_a)) + CPASSERT(.NOT. ASSOCIATED(glob_cell_v)) + CALL timeset(routineN, handle) + npairs_tot = 0 + nkinds = SIZE(potparm%pot, 1) + DO ilist = 1, nonbonded%nlists + neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist) + npairs = neighbor_kind_pair%npairs + IF (npairs == 0) CYCLE + Kind_Group_Loop1: DO igrp = 1, neighbor_kind_pair%ngrp_kind + istart = neighbor_kind_pair%grp_kind_start(igrp) + iend = neighbor_kind_pair%grp_kind_end(igrp) + ikind = neighbor_kind_pair%ij_kind(1, igrp) + jkind = neighbor_kind_pair%ij_kind(2, igrp) + pot => potparm%pot(ikind, jkind)%pot + npairs = iend - istart + 1 + IF (pot%no_mb) CYCLE + DO i = 1, SIZE(pot%type) + IF (pot%type(i) == allegro_type) npairs_tot = npairs_tot + npairs + END DO + END DO Kind_Group_Loop1 + END DO + ALLOCATE (work_list(npairs_tot)) + ALLOCATE (work_list2(npairs_tot)) + ALLOCATE (glob_loc_list(2, npairs_tot)) + ALLOCATE (glob_cell_v(3, npairs_tot)) + ! Fill arrays with data + npairs_tot = 0 + DO ilist = 1, nonbonded%nlists + neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist) + npairs = neighbor_kind_pair%npairs + IF (npairs == 0) CYCLE + Kind_Group_Loop2: DO igrp = 1, neighbor_kind_pair%ngrp_kind + istart = neighbor_kind_pair%grp_kind_start(igrp) + iend = neighbor_kind_pair%grp_kind_end(igrp) + ikind = neighbor_kind_pair%ij_kind(1, igrp) + jkind = neighbor_kind_pair%ij_kind(2, igrp) + list => neighbor_kind_pair%list + cvi = neighbor_kind_pair%cell_vector + pot => potparm%pot(ikind, jkind)%pot + npairs = iend - istart + 1 + IF (pot%no_mb) CYCLE + cell_v = MATMUL(cell%hmat, cvi) + DO i = 1, SIZE(pot%type) + ! ALLEGRO + IF (pot%type(i) == allegro_type) THEN + DO ipair = 1, npairs + glob_loc_list(:, npairs_tot + ipair) = list(:, istart - 1 + ipair) + glob_cell_v(1:3, npairs_tot + ipair) = cell_v(1:3) + END DO + npairs_tot = npairs_tot + npairs + END IF + END DO + END DO Kind_Group_Loop2 + END DO + ! Order the arrays w.r.t. the first index of glob_loc_list + CALL sort(glob_loc_list(1, :), npairs_tot, work_list) + DO ipair = 1, npairs_tot + work_list2(ipair) = glob_loc_list(2, work_list(ipair)) + END DO + glob_loc_list(2, :) = work_list2 + DEALLOCATE (work_list2) + ALLOCATE (rwork_list(3, npairs_tot)) + DO ipair = 1, npairs_tot + rwork_list(:, ipair) = glob_cell_v(:, work_list(ipair)) + END DO + glob_cell_v = rwork_list + DEALLOCATE (rwork_list) + DEALLOCATE (work_list) + ALLOCATE (glob_loc_list_a(npairs_tot)) + glob_loc_list_a = glob_loc_list(1, :) + ALLOCATE (temp_unique_list_a(npairs_tot)) + nlocal = 1 + temp_unique_list_a(1) = glob_loc_list_a(1) + DO ipair = 2, npairs_tot + IF (glob_loc_list_a(ipair - 1) /= glob_loc_list_a(ipair)) THEN + nlocal = nlocal + 1 + temp_unique_list_a(nlocal) = glob_loc_list_a(ipair) + END IF + END DO + ALLOCATE (unique_list_a(nlocal)) + unique_list_a(:) = temp_unique_list_a(:nlocal) + DEALLOCATE (temp_unique_list_a) + CALL timestop(handle) + END SUBROUTINE setup_allegro_arrays + +! ************************************************************************************************** +!> \brief ... +!> \param glob_loc_list ... +!> \param glob_cell_v ... +!> \param glob_loc_list_a ... +!> \param unique_list_a ... +!> \par History +!> Implementation of the allegro potential - [gtocci] 2023 +!> \author Gabriele Tocci - University of Zurich +! ************************************************************************************************** + SUBROUTINE destroy_allegro_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a) + INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list + REAL(KIND=dp), DIMENSION(:, :), POINTER :: glob_cell_v + INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, unique_list_a + + IF (ASSOCIATED(glob_loc_list)) THEN + DEALLOCATE (glob_loc_list) + END IF + IF (ASSOCIATED(glob_loc_list_a)) THEN + DEALLOCATE (glob_loc_list_a) + END IF + IF (ASSOCIATED(glob_cell_v)) THEN + DEALLOCATE (glob_cell_v) + END IF + IF (ASSOCIATED(unique_list_a)) THEN + DEALLOCATE (unique_list_a) + END IF + + END SUBROUTINE destroy_allegro_arrays + +! ************************************************************************************************** +!> \brief ... +!> \param nonbonded ... +!> \param particle_set ... +!> \param cell ... +!> \param atomic_kind_set ... +!> \param potparm ... +!> \param allegro ... +!> \param glob_loc_list_a ... +!> \param r_last_update_pbc ... +!> \param pot_allegro ... +!> \param fist_nonbond_env ... +!> \param unique_list_a ... +!> \par History +!> Implementation of the allegro potential - [gtocci] 2023 +!> \author Gabriele Tocci - University of Zurich +! ************************************************************************************************** + SUBROUTINE allegro_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, & + potparm, allegro, glob_loc_list_a, r_last_update_pbc, & + pot_allegro, fist_nonbond_env, unique_list_a) + + TYPE(fist_neighbor_type), POINTER :: nonbonded + TYPE(particle_type), POINTER :: particle_set(:) + TYPE(cell_type), POINTER :: cell + TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:) + TYPE(pair_potential_pp_type), POINTER :: potparm + TYPE(allegro_pot_type), POINTER :: allegro + INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a + TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc + REAL(kind=dp) :: pot_allegro + TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env + INTEGER, DIMENSION(:), POINTER :: unique_list_a + + CHARACTER(LEN=*), PARAMETER :: routineN = 'allegro_energy_store_force_virial' + + INTEGER :: atom_a, atom_b, handle, i, iat, iat_use, iend, ifirst, igrp, ikind, ilast, ilist, & + ipair, istart, iunique, jkind, junique, mpair, n_atoms, n_atoms_use, nedges, nloc_size, & + npairs, nunique + INTEGER(kind=int_8), ALLOCATABLE :: atom_types(:), temp_atom_types(:) + INTEGER(kind=int_8), ALLOCATABLE, DIMENSION(:, :) :: edge_index, t_edge_index, temp_edge_index + INTEGER, ALLOCATABLE, DIMENSION(:) :: work_list + INTEGER, DIMENSION(:, :), POINTER :: list, sort_list + LOGICAL, ALLOCATABLE :: use_atom(:) + REAL(kind=dp) :: drij, lattice(3, 3), rab2_max, rij(3) + REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi + REAL(kind=sp), ALLOCATABLE :: pos(:, :) + REAL(kind=sp), ALLOCATABLE, DIMENSION(:, :) :: edge_cell_shifts, new_edge_cell_shifts + REAL(sp), DIMENSION(:, :), POINTER :: atomic_energy, forces + TYPE(allegro_data_type), POINTER :: allegro_data + TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair + TYPE(pair_potential_single_type), POINTER :: pot + TYPE(torch_dict_type) :: inputs, outputs + + CALL timeset(routineN, handle) + + NULLIFY (atomic_energy, forces) + n_atoms = SIZE(particle_set) + ALLOCATE (use_atom(n_atoms)) + use_atom = .FALSE. + + DO ikind = 1, SIZE(atomic_kind_set) + DO jkind = 1, SIZE(atomic_kind_set) + pot => potparm%pot(ikind, jkind)%pot + DO i = 1, SIZE(pot%type) + IF (pot%type(i) /= allegro_type) CYCLE + IF (.NOT. ASSOCIATED(allegro)) allegro => pot%set(i)%allegro + DO iat = 1, n_atoms + IF (particle_set(iat)%atomic_kind%kind_number == ikind .OR. & + particle_set(iat)%atomic_kind%kind_number == jkind) use_atom(iat) = .TRUE. + END DO ! iat + END DO ! i + END DO ! jkind + END DO ! ikind + n_atoms_use = COUNT(use_atom) + + ! get allegro_data to save force, virial info and to load model + CALL fist_nonbond_env_get(fist_nonbond_env, allegro_data=allegro_data) + IF (.NOT. ASSOCIATED(allegro_data)) THEN + ALLOCATE (allegro_data) + CALL fist_nonbond_env_set(fist_nonbond_env, allegro_data=allegro_data) + NULLIFY (allegro_data%use_indices, allegro_data%force) + CALL torch_model_load(allegro_data%model, pot%set(1)%allegro%allegro_file_name) + END IF + IF (ASSOCIATED(allegro_data%force)) THEN + IF (SIZE(allegro_data%force, 2) /= n_atoms_use) THEN + DEALLOCATE (allegro_data%force, allegro_data%use_indices) + END IF + END IF + IF (.NOT. ASSOCIATED(allegro_data%force)) THEN + ALLOCATE (allegro_data%force(3, n_atoms_use)) + ALLOCATE (allegro_data%use_indices(n_atoms_use)) + END IF + + iat_use = 0 + DO iat = 1, n_atoms_use + IF (use_atom(iat)) THEN + iat_use = iat_use + 1 + allegro_data%use_indices(iat_use) = iat + END IF + END DO + + nedges = 0 + + ALLOCATE (edge_index(2, SIZE(glob_loc_list_a))) + ALLOCATE (edge_cell_shifts(3, SIZE(glob_loc_list_a))) + ALLOCATE (temp_atom_types(SIZE(glob_loc_list_a))) + + DO ilist = 1, nonbonded%nlists + neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist) + npairs = neighbor_kind_pair%npairs + IF (npairs == 0) CYCLE + Kind_Group_Loop_Allegro: DO igrp = 1, neighbor_kind_pair%ngrp_kind + istart = neighbor_kind_pair%grp_kind_start(igrp) + iend = neighbor_kind_pair%grp_kind_end(igrp) + ikind = neighbor_kind_pair%ij_kind(1, igrp) + jkind = neighbor_kind_pair%ij_kind(2, igrp) + list => neighbor_kind_pair%list + cvi = neighbor_kind_pair%cell_vector + pot => potparm%pot(ikind, jkind)%pot + DO i = 1, SIZE(pot%type) + IF (pot%type(i) /= allegro_type) CYCLE + rab2_max = pot%set(i)%allegro%rcutsq + cell_v = MATMUL(cell%hmat, cvi) + pot => potparm%pot(ikind, jkind)%pot + allegro => pot%set(i)%allegro + npairs = iend - istart + 1 + IF (npairs /= 0) THEN + ALLOCATE (sort_list(2, npairs), work_list(npairs)) + sort_list = list(:, istart:iend) + ! Sort the list of neighbors, this increases the efficiency for single + ! potential contributions + CALL sort(sort_list(1, :), npairs, work_list) + DO ipair = 1, npairs + work_list(ipair) = sort_list(2, work_list(ipair)) + END DO + sort_list(2, :) = work_list + ! find number of unique elements of array index 1 + nunique = 1 + DO ipair = 1, npairs - 1 + IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1 + END DO + ipair = 1 + junique = sort_list(1, ipair) + ifirst = 1 + DO iunique = 1, nunique + atom_a = junique + IF (glob_loc_list_a(ifirst) > atom_a) CYCLE + DO mpair = ifirst, SIZE(glob_loc_list_a) + IF (glob_loc_list_a(mpair) == atom_a) EXIT + END DO + ifirst = mpair + DO mpair = ifirst, SIZE(glob_loc_list_a) + IF (glob_loc_list_a(mpair) /= atom_a) EXIT + END DO + ilast = mpair - 1 + nloc_size = 0 + IF (ifirst /= 0) nloc_size = ilast - ifirst + 1 + DO WHILE (ipair <= npairs) + IF (sort_list(1, ipair) /= junique) EXIT + atom_b = sort_list(2, ipair) + rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v + drij = DOT_PRODUCT(rij, rij) + ipair = ipair + 1 + IF (drij <= rab2_max) THEN + nedges = nedges + 1 + edge_index(:, nedges) = [atom_a - 1, atom_b - 1] + edge_cell_shifts(:, nedges) = REAL(cvi, kind=sp) + END IF + END DO + ifirst = ilast + 1 + IF (ipair <= npairs) junique = sort_list(1, ipair) + END DO + DEALLOCATE (sort_list, work_list) + END IF + END DO + END DO Kind_Group_Loop_Allegro + END DO + + ALLOCATE (temp_edge_index(2, nedges)) + temp_edge_index(:, :) = edge_index(:, :nedges) + ALLOCATE (new_edge_cell_shifts(3, nedges)) + new_edge_cell_shifts(:, :) = edge_cell_shifts(:, :nedges) + + ALLOCATE (t_edge_index(nedges, 2)) + + t_edge_index(:, :) = TRANSPOSE(temp_edge_index) + DEALLOCATE (temp_edge_index, edge_index) + + lattice = cell%hmat/pot%set(1)%allegro%unit_cell_val + + iat_use = 0 + ALLOCATE (pos(3, n_atoms_use), atom_types(n_atoms_use)) + + DO iat = 1, n_atoms_use + IF (.NOT. use_atom(iat)) CYCLE + iat_use = iat_use + 1 + atom_types(iat_use) = particle_set(iat)%atomic_kind%kind_number - 1 + pos(:, iat) = REAL(r_last_update_pbc(iat)%r(:)/pot%set(1)%allegro%unit_coords_val, kind=sp) + END DO + + CALL torch_dict_create(inputs) + CALL torch_dict_insert(inputs, "pos", pos) + CALL torch_dict_insert(inputs, "edge_index", t_edge_index) + CALL torch_dict_insert(inputs, "edge_cell_shift", new_edge_cell_shifts) + CALL torch_dict_insert(inputs, "cell", REAL(lattice, kind=sp)) + CALL torch_dict_insert(inputs, "atom_types", atom_types) + + CALL torch_dict_create(outputs) + + CALL torch_model_eval(allegro_data%model, inputs, outputs) + + CALL torch_dict_get(outputs, "atomic_energy", atomic_energy) + CALL torch_dict_get(outputs, "forces", forces) + + allegro_data%force(:, :) = REAL(forces(:, :), kind=dp)*allegro%unit_forces_val + + pot_allegro = 0.0_dp + + DO iat_use = 1, SIZE(unique_list_a) + i = unique_list_a(iat_use) + pot_allegro = pot_allegro + REAL(atomic_energy(1, i), kind=dp)*allegro%unit_energy_val + END DO + + CALL torch_dict_release(inputs) + CALL torch_dict_release(outputs) + + DEALLOCATE (pos, t_edge_index, edge_cell_shifts, atom_types, atomic_energy) + DEALLOCATE (new_edge_cell_shifts) + DEALLOCATE (forces) + + CALL timestop(handle) + END SUBROUTINE allegro_energy_store_force_virial + +! ************************************************************************************************** +!> \brief ... +!> \param fist_nonbond_env ... +!> \param f_nonbond ... +!> \param pv_nonbond ... +!> \param use_virial ... +! ************************************************************************************************** + SUBROUTINE allegro_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial) + + TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env + REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: f_nonbond, pv_nonbond + LOGICAL, INTENT(IN) :: use_virial + + INTEGER :: iat, iat_use + REAL(KIND=dp), DIMENSION(3, 3) :: virial + TYPE(allegro_data_type), POINTER :: allegro_data + + CALL fist_nonbond_env_get(fist_nonbond_env, allegro_data=allegro_data) + + IF (use_virial) THEN + virial = 0.0_dp + pv_nonbond = pv_nonbond + virial + CPABORT("Stress tensor for Allegro not yet implemented") + END IF + + DO iat_use = 1, SIZE(allegro_data%use_indices) + iat = allegro_data%use_indices(iat_use) + CPASSERT(iat >= 1 .AND. iat <= SIZE(f_nonbond, 2)) + f_nonbond(1:3, iat) = f_nonbond(1:3, iat) + allegro_data%force(1:3, iat_use) + END DO + + END SUBROUTINE allegro_add_force_virial +END MODULE manybody_allegro + diff --git a/src/manybody_nequip.F b/src/manybody_nequip.F index 05bb827681..975e341c55 100644 --- a/src/manybody_nequip.F +++ b/src/manybody_nequip.F @@ -74,10 +74,10 @@ CONTAINS INTEGER :: handle, i, iend, igrp, ikind, ilist, & ipair, istart, jkind, nkinds, npairs, & npairs_tot - INTEGER, DIMENSION(:), POINTER :: work_list, work_list2 + INTEGER, ALLOCATABLE, DIMENSION(:) :: work_list, work_list2 INTEGER, DIMENSION(:, :), POINTER :: list + REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: rwork_list REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi - REAL(KIND=dp), DIMENSION(:, :), POINTER :: rwork_list TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair TYPE(pair_potential_single_type), POINTER :: pot @@ -223,8 +223,7 @@ CONTAINS INTEGER(kind=int_8), ALLOCATABLE :: atom_types(:) INTEGER(kind=int_8), ALLOCATABLE, DIMENSION(:, :) :: edge_index, t_edge_index, temp_edge_index INTEGER, ALLOCATABLE, DIMENSION(:) :: displ, displ_cell, edge_count, & - edge_count_cell - INTEGER, DIMENSION(:), POINTER :: work_list + edge_count_cell, work_list INTEGER, DIMENSION(:, :), POINTER :: list, sort_list LOGICAL, ALLOCATABLE :: use_atom(:) REAL(kind=dp) :: drij, lattice(3, 3), rab2_max, rij(3) @@ -462,19 +461,8 @@ CONTAINS CALL fist_nonbond_env_get(fist_nonbond_env, nequip_data=nequip_data) IF (use_virial) THEN - virial(1, 1) = 0.0_dp; virial(1, 2) = 0.0_dp; virial(1, 3) = 0.0_dp - virial(2, 1) = 0.0_dp; virial(2, 2) = 0.0_dp; virial(2, 3) = 0.0_dp - virial(3, 1) = 0.0_dp; virial(3, 2) = 0.0_dp; virial(3, 3) = 0.0_dp - - pv_nonbond(1, 1) = pv_nonbond(1, 1) + virial(1, 1) - pv_nonbond(1, 2) = pv_nonbond(1, 2) + virial(1, 2) - pv_nonbond(1, 3) = pv_nonbond(1, 3) + virial(1, 3) - pv_nonbond(2, 1) = pv_nonbond(2, 1) + virial(2, 1) - pv_nonbond(2, 2) = pv_nonbond(2, 2) + virial(2, 2) - pv_nonbond(3, 1) = pv_nonbond(3, 1) + virial(3, 1) - pv_nonbond(3, 2) = pv_nonbond(3, 2) + virial(3, 2) - pv_nonbond(3, 3) = pv_nonbond(3, 3) + virial(3, 3) - + virial = 0.0_dp + pv_nonbond = pv_nonbond + virial CPABORT("Stress tensor for NequIP not yet implemented") END IF diff --git a/src/manybody_potential.F b/src/manybody_potential.F index 151a6da157..56a8cebbef 100644 --- a/src/manybody_potential.F +++ b/src/manybody_potential.F @@ -26,6 +26,10 @@ MODULE manybody_potential pos_type USE input_section_types, ONLY: section_vals_type USE kinds, ONLY: dp + USE manybody_allegro, ONLY: allegro_add_force_virial,& + allegro_energy_store_force_virial,& + destroy_allegro_arrays,& + setup_allegro_arrays USE manybody_eam, ONLY: get_force_eam USE manybody_gal, ONLY: destroy_gal_arrays,& gal_energy,& @@ -53,9 +57,10 @@ MODULE manybody_potential tersoff_forces USE message_passing, ONLY: mp_para_env_type USE pair_potential_types, ONLY: & - ea_type, eam_pot_type, gal21_pot_type, gal21_type, gal_pot_type, gal_type, & - nequip_pot_type, nequip_type, pair_potential_pp_type, pair_potential_single_type, & - quip_type, siepmann_pot_type, siepmann_type, tersoff_pot_type, tersoff_type + allegro_pot_type, allegro_type, ea_type, eam_pot_type, gal21_pot_type, gal21_type, & + gal_pot_type, gal_type, nequip_pot_type, nequip_type, pair_potential_pp_type, & + pair_potential_single_type, quip_type, siepmann_pot_type, siepmann_type, tersoff_pot_type, & + tersoff_type USE particle_types, ONLY: particle_type USE util, ONLY: sort #include "./base/base_uses.f90" @@ -100,15 +105,18 @@ CONTAINS INTEGER :: atom_a, atom_b, handle, i, iend, ifirst, igrp, ikind, ilast, ilist, indexa, & ipair, iparticle, iparticle_local, istart, iunique, jkind, junique, mpair, nkinds, & nloc_size, npairs, nparticle, nparticle_local, nr_h3O, nr_o, nr_oh, nunique - INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, work_list + INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, unique_list_a, work_list INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list - LOGICAL :: any_gal, any_gal21, any_nequip, & - any_quip, any_siepmann, any_tersoff - REAL(KIND=dp) :: drij, embed, pot_loc, pot_nequip, & - pot_quip, qr, rab2_max, rij(3) + LOGICAL :: any_allegro, any_gal, any_gal21, & + any_nequip, any_quip, any_siepmann, & + any_tersoff + REAL(KIND=dp) :: drij, embed, pot_allegro, pot_loc, & + pot_nequip, pot_quip, qr, rab2_max, & + rij(3) REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi REAL(KIND=dp), DIMENSION(:, :), POINTER :: glob_cell_v REAL(KIND=dp), POINTER :: fembed(:) + TYPE(allegro_pot_type), POINTER :: allegro TYPE(eam_pot_type), POINTER :: eam TYPE(eam_type), DIMENSION(:), POINTER :: eam_data TYPE(fist_neighbor_type), POINTER :: nonbonded @@ -129,6 +137,7 @@ CONTAINS any_gal21 = .FALSE. any_quip = .FALSE. any_nequip = .FALSE. + any_allegro = .FALSE. CALL timeset(routineN, handle) CALL fist_nonbond_env_get(fist_nonbond_env, r_last_update_pbc=r_last_update_pbc, & potparm=potparm, eam_data=eam_data) @@ -173,6 +182,7 @@ CONTAINS any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type) any_quip = any_quip .OR. ANY(pot%type == quip_type) any_nequip = any_nequip .OR. ANY(pot%type == nequip_type) + any_allegro = any_allegro .OR. ANY(pot%type == allegro_type) any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type) any_gal = any_gal .OR. ANY(pot%type == gal_type) any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type) @@ -195,6 +205,17 @@ CONTAINS pot_manybody = pot_manybody + pot_nequip CALL destroy_nequip_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a) END IF + ! ALLEGRO + IF (any_allegro) THEN + NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a) + CALL setup_allegro_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, & + unique_list_a, cell) + CALL allegro_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, potparm, & + allegro, glob_loc_list_a, r_last_update_pbc, pot_allegro, & + fist_nonbond_env, unique_list_a) + pot_manybody = pot_manybody + pot_allegro + CALL destroy_allegro_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a) + END IF ! TERSOFF IF (any_tersoff) THEN NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a) @@ -555,8 +576,9 @@ CONTAINS INTEGER, ALLOCATABLE, DIMENSION(:, :) :: eam_kinds_index INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, work_list INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list - LOGICAL :: any_gal, any_gal21, any_nequip, & - any_quip, any_siepmann, any_tersoff + LOGICAL :: any_allegro, any_gal, any_gal21, & + any_nequip, any_quip, any_siepmann, & + any_tersoff REAL(KIND=dp) :: f_eam, fac, fr(3), ptens11, ptens12, ptens13, ptens21, ptens22, ptens23, & ptens31, ptens32, ptens33, rab(3), rab2, rab2_max, rtmp(3) REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi @@ -576,6 +598,7 @@ CONTAINS any_tersoff = .FALSE. any_quip = .FALSE. any_nequip = .FALSE. + any_allegro = .FALSE. any_siepmann = .FALSE. any_gal = .FALSE. any_gal21 = .FALSE. @@ -634,6 +657,7 @@ CONTAINS any_gal = any_gal .OR. ANY(pot%type == gal_type) any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type) any_nequip = any_nequip .OR. ANY(pot%type == nequip_type) + any_allegro = any_allegro .OR. ANY(pot%type == allegro_type) i = eam_kinds_index(ikind, jkind) IF (i == -1) CYCLE ! EAM @@ -1006,6 +1030,11 @@ CONTAINS CALL nequip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial) END IF + ! ALLEGRO + IF (any_allegro) THEN + CALL allegro_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial) + END IF + IF (use_virial) THEN pv_nonbond(1, 1) = pv_nonbond(1, 1) + ptens11 pv_nonbond(1, 2) = pv_nonbond(1, 2) + ptens12 diff --git a/src/pair_potential.F b/src/pair_potential.F index ca0f6e8215..9f107a8fa9 100644 --- a/src/pair_potential.F +++ b/src/pair_potential.F @@ -29,10 +29,10 @@ MODULE pair_potential default_string_length,& dp USE pair_potential_types, ONLY: & - b4_type, bm_type, compare_pot, ea_type, ft_type, ftd_type, gal21_type, gal_type, gp_type, & - gw_type, ip_type, list_pot, lj_charmm_type, lj_type, multi_type, nequip_type, nn_type, & - pair_potential_pp_type, pair_potential_single_type, potential_single_allocation, & - quip_type, siepmann_type, tab_type, tersoff_type, wl_type + allegro_type, b4_type, bm_type, compare_pot, ea_type, ft_type, ftd_type, gal21_type, & + gal_type, gp_type, gw_type, ip_type, list_pot, lj_charmm_type, lj_type, multi_type, & + nequip_type, nn_type, pair_potential_pp_type, pair_potential_single_type, & + potential_single_allocation, quip_type, siepmann_type, tab_type, tersoff_type, wl_type USE pair_potential_util, ONLY: ener_pot,& ener_zbl,& zbl_matching_polinomial @@ -186,7 +186,7 @@ CONTAINS DO k = 1, SIZE(pot%type) SELECT CASE (pot%type(k)) CASE (lj_type, lj_charmm_type, wl_type, gw_type, ft_type, ftd_type, ip_type, & - b4_type, bm_type, gp_type, ea_type, quip_type, nequip_type, tab_type) + b4_type, bm_type, gp_type, ea_type, quip_type, nequip_type, allegro_type, tab_type) pot%no_pp = .FALSE. CASE (tersoff_type) pot%no_mb = .FALSE. @@ -204,7 +204,7 @@ CONTAINS END SELECT ! Special case for EAM SELECT CASE (pot%type(k)) - CASE (ea_type, quip_type, nequip_type) + CASE (ea_type, quip_type, nequip_type, allegro_type) pot%no_mb = .FALSE. END SELECT END DO @@ -608,6 +608,8 @@ CONTAINS nvar = 1 + nvar CASE (nequip_type) nvar = 1 + nvar + CASE (allegro_type) + nvar = 1 + nvar CASE (ft_type) nvar = 4 + nvar CASE (ftd_type) @@ -691,6 +693,9 @@ CONTAINS CASE (nequip_type) pot_par(nk, 1) = str2id( & TRIM(potparm%pot(i, j)%pot%set(1)%nequip%nequip_file_name)) + CASE (allegro_type) + pot_par(nk, 1) = str2id( & + TRIM(potparm%pot(i, j)%pot%set(1)%allegro%allegro_file_name)) CASE (ft_type) pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%ft%A pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%ft%B diff --git a/src/pair_potential_types.F b/src/pair_potential_types.F index 99ff9ab1a0..8f6667f9b5 100644 --- a/src/pair_potential_types.F +++ b/src/pair_potential_types.F @@ -50,10 +50,11 @@ MODULE pair_potential_types gal_type = 14, & quip_type = 15, & nequip_type = 16, & - gal21_type = 17, & - tab_type = 18 + allegro_type = 17, & + gal21_type = 18, & + tab_type = 19 - INTEGER, PUBLIC, PARAMETER, DIMENSION(19) :: list_pot = (/nn_type, & + INTEGER, PUBLIC, PARAMETER, DIMENSION(20) :: list_pot = (/nn_type, & lj_type, & lj_charmm_type, & ft_type, & @@ -70,6 +71,7 @@ MODULE pair_potential_types gal_type, & quip_type, & nequip_type, & + allegro_type, & gal21_type, & tab_type/) @@ -105,6 +107,7 @@ MODULE pair_potential_types eam_pot_type, & quip_pot_type, & nequip_pot_type, & + allegro_pot_type, & tersoff_pot_type, & siepmann_pot_type, & gal_pot_type, & @@ -178,12 +181,24 @@ MODULE pair_potential_types ! ************************************************************************************************** TYPE nequip_pot_type - CHARACTER(LEN=default_path_length) :: nequip_file_name, nequip_version, unit_coords, & - unit_forces, unit_energy, unit_cell - REAL(KIND=dp) :: rcutsq, unit_coords_val, unit_forces_val, & - unit_energy_val, unit_cell_val + CHARACTER(LEN=default_path_length) :: nequip_file_name = 'NULL', nequip_version = 'NULL', & + unit_coords = 'NULL', unit_forces = 'NULL', & + unit_energy = 'NULL', unit_cell = 'NULL' + REAL(KIND=dp) :: rcutsq = 0.0_dp, unit_coords_val = 0.0_dp, & + unit_forces_val = 0.0_dp, unit_energy_val = 0.0_dp, & + unit_cell_val = 0.0_dp END TYPE nequip_pot_type +! ************************************************************************************************** + TYPE allegro_pot_type + CHARACTER(LEN=default_path_length) :: allegro_file_name = 'NULL', unit_cell = 'NULL', & + allegro_version = 'NULL', unit_coords = 'NULL', & + unit_forces = 'NULL', unit_energy = 'NULL' + REAL(KIND=dp) :: rcutsq = 0.0_dp, unit_coords_val = 0.0_dp, & + unit_forces_val = 0.0_dp, unit_cell_val = 0.0_dp, & + unit_energy_val = 0.0_dp + END TYPE allegro_pot_type + ! ************************************************************************************************** TYPE buck4ran_pot_type REAL(KIND=dp) :: a @@ -337,6 +352,7 @@ MODULE pair_potential_types TYPE(eam_pot_type), POINTER :: eam TYPE(quip_pot_type), POINTER :: quip TYPE(nequip_pot_type), POINTER :: nequip + TYPE(allegro_pot_type), POINTER :: allegro TYPE(buck4ran_pot_type), POINTER :: buck4r TYPE(buckmorse_pot_type), POINTER :: buckmo TYPE(tersoff_pot_type), POINTER :: tersoff @@ -454,6 +470,12 @@ CONTAINS (pot1%set(i)%nequip%unit_forces == pot2%set(i)%nequip%unit_forces) .AND. & (pot1%set(i)%nequip%unit_energy == pot2%set(i)%nequip%unit_energy) .AND. & (pot1%set(i)%nequip%unit_cell == pot2%set(i)%nequip%unit_cell)) mycompare = .TRUE. + CASE (allegro_type) + IF ((pot1%set(i)%allegro%allegro_file_name == pot2%set(i)%allegro%allegro_file_name) .AND. & + (pot1%set(i)%allegro%unit_coords == pot2%set(i)%allegro%unit_coords) .AND. & + (pot1%set(i)%allegro%unit_forces == pot2%set(i)%allegro%unit_forces) .AND. & + (pot1%set(i)%allegro%unit_energy == pot2%set(i)%allegro%unit_energy) .AND. & + (pot1%set(i)%allegro%unit_cell == pot2%set(i)%allegro%unit_cell)) mycompare = .TRUE. CASE (ft_type) IF ((pot1%set(i)%ft%A == pot2%set(i)%ft%A) .AND. & (pot1%set(i)%ft%B == pot2%set(i)%ft%B) .AND. & @@ -591,6 +613,7 @@ CONTAINS potparm%set(i)%eam, & potparm%set(i)%quip, & potparm%set(i)%nequip, & + potparm%set(i)%allegro, & potparm%set(i)%buck4r, & potparm%set(i)%buckmo, & potparm%set(i)%tersoff, & @@ -635,6 +658,7 @@ CONTAINS CALL pair_potential_eam_clean(potparm%set(i)%eam) CALL pair_potential_quip_clean(potparm%set(i)%quip) CALL pair_potential_nequip_clean(potparm%set(i)%nequip) + CALL pair_potential_allegro_clean(potparm%set(i)%allegro) CALL pair_potential_buck4r_clean(potparm%set(i)%buck4r) CALL pair_potential_buckmo_clean(potparm%set(i)%buckmo) CALL pair_potential_bmhft_clean(potparm%set(i)%ft) @@ -691,6 +715,7 @@ CONTAINS CALL pair_potential_eam_copy(potparm_source%set(i)%eam, potparm_dest%set(i)%eam) CALL pair_potential_quip_copy(potparm_source%set(i)%quip, potparm_dest%set(i)%quip) CALL pair_potential_nequip_copy(potparm_source%set(i)%nequip, potparm_dest%set(i)%nequip) + CALL pair_potential_allegro_copy(potparm_source%set(i)%allegro, potparm_dest%set(i)%allegro) CALL pair_potential_bmhft_copy(potparm_source%set(i)%ft, potparm_dest%set(i)%ft) CALL pair_potential_bmhftd_copy(potparm_source%set(i)%ftd, potparm_dest%set(i)%ftd) CALL pair_potential_ipbv_copy(potparm_source%set(i)%ipbv, potparm_dest%set(i)%ipbv) @@ -740,6 +765,7 @@ CONTAINS (ASSOCIATED(potparm_dest%set(1)%eam)) .OR. & (ASSOCIATED(potparm_dest%set(1)%quip)) .OR. & (ASSOCIATED(potparm_dest%set(1)%nequip)) .OR. & + (ASSOCIATED(potparm_dest%set(1)%allegro)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ft)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ftd)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ipbv)) .OR. & @@ -791,6 +817,7 @@ CONTAINS CALL pair_potential_eam_copy(potparm_tmp%set(i)%eam, potparm_dest%set(i)%eam) CALL pair_potential_quip_copy(potparm_tmp%set(i)%quip, potparm_dest%set(i)%quip) CALL pair_potential_nequip_copy(potparm_tmp%set(i)%nequip, potparm_dest%set(i)%nequip) + CALL pair_potential_allegro_copy(potparm_tmp%set(i)%allegro, potparm_dest%set(i)%allegro) CALL pair_potential_bmhft_copy(potparm_tmp%set(i)%ft, potparm_dest%set(i)%ft) CALL pair_potential_bmhftd_copy(potparm_tmp%set(i)%ftd, potparm_dest%set(i)%ftd) CALL pair_potential_ipbv_copy(potparm_tmp%set(i)%ipbv, potparm_dest%set(i)%ipbv) @@ -826,6 +853,7 @@ CONTAINS CALL pair_potential_eam_copy(potparm_source%set(j)%eam, potparm_dest%set(i)%eam) CALL pair_potential_quip_copy(potparm_source%set(j)%quip, potparm_dest%set(i)%quip) CALL pair_potential_nequip_copy(potparm_source%set(j)%nequip, potparm_dest%set(i)%nequip) + CALL pair_potential_allegro_copy(potparm_source%set(j)%allegro, potparm_dest%set(i)%allegro) CALL pair_potential_bmhft_copy(potparm_source%set(j)%ft, potparm_dest%set(i)%ft) CALL pair_potential_bmhftd_copy(potparm_source%set(j)%ftd, potparm_dest%set(i)%ftd) CALL pair_potential_ipbv_copy(potparm_source%set(j)%ipbv, potparm_dest%set(i)%ipbv) @@ -863,6 +891,7 @@ CONTAINS CALL pair_potential_eam_release(potparm%set(i)%eam) CALL pair_potential_quip_release(potparm%set(i)%quip) CALL pair_potential_nequip_release(potparm%set(i)%nequip) + CALL pair_potential_allegro_release(potparm%set(i)%allegro) CALL pair_potential_buck4r_release(potparm%set(i)%buck4r) CALL pair_potential_buckmo_release(potparm%set(i)%buckmo) CALL pair_potential_gp_release(potparm%set(i)%gp) @@ -1037,6 +1066,7 @@ CONTAINS !> \param eam ... !> \param quip ... !> \param nequip ... +!> \param allegro ... !> \param bmhft ... !> \param bmhftd ... !> \param ipbv ... @@ -1050,19 +1080,17 @@ CONTAINS !> \param tab ... !> \author Teodoro Laino [Teo] 11.2005 ! ************************************************************************************************** - SUBROUTINE pair_potential_reallocate(p, lb1_new, ub1_new, lj, lj_charmm, williams, & - goodwin, eam, quip, nequip, bmhft, bmhftd, ipbv, buck4r, buckmo, gp, tersoff, & - siepmann, gal, gal21, tab) + SUBROUTINE pair_potential_reallocate(p, lb1_new, ub1_new, lj, lj_charmm, williams, goodwin, eam, & + quip, nequip, allegro, bmhft, bmhftd, ipbv, buck4r, buckmo, & + gp, tersoff, siepmann, gal, gal21, tab) TYPE(pair_potential_p_type), POINTER :: p INTEGER, INTENT(IN) :: lb1_new, ub1_new - LOGICAL, INTENT(IN), OPTIONAL :: lj, lj_charmm, williams, goodwin, eam, & - quip, nequip, bmhft, bmhftd, ipbv, & - buck4r, buckmo, gp, tersoff, siepmann, & - gal, gal21, tab + LOGICAL, INTENT(IN), OPTIONAL :: lj, lj_charmm, williams, goodwin, eam, quip, nequip, & + allegro, bmhft, bmhftd, ipbv, buck4r, buckmo, gp, tersoff, siepmann, gal, gal21, tab INTEGER :: i, ipot, lb1_old, std_dim, ub1_old - LOGICAL :: check, lbmhft, lbmhftd, lbuck4r, lbuckmo, leam, lgal, lgal21, lgoodwin, lgp, & - lipbv, llj, llj_charmm, lnequip, lquip, lsiepmann, ltab, ltersoff, lwilliams + LOGICAL :: check, lallegro, lbmhft, lbmhftd, lbuck4r, lbuckmo, leam, lgal, lgal21, lgoodwin, & + lgp, lipbv, llj, llj_charmm, lnequip, lquip, lsiepmann, ltab, ltersoff, lwilliams TYPE(pair_potential_p_type), POINTER :: work NULLIFY (work) @@ -1074,6 +1102,7 @@ CONTAINS leam = .FALSE.; IF (PRESENT(eam)) leam = eam lquip = .FALSE.; IF (PRESENT(quip)) lquip = quip lnequip = .FALSE.; IF (PRESENT(nequip)) lnequip = nequip + lallegro = .FALSE.; IF (PRESENT(allegro)) lallegro = allegro lbmhft = .FALSE.; IF (PRESENT(bmhft)) lbmhft = bmhft lbmhftd = .FALSE.; IF (PRESENT(bmhftd)) lbmhftd = bmhftd lipbv = .FALSE.; IF (PRESENT(ipbv)) lipbv = ipbv @@ -1088,78 +1117,85 @@ CONTAINS IF (llj) THEN ipot = lj_type - check = .NOT. (llj_charmm .OR. lwilliams .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj_charmm .OR. lwilliams .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (llj_charmm) THEN ipot = lj_charmm_type - check = .NOT. (llj .OR. lwilliams .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. lwilliams .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lwilliams) THEN ipot = wl_type - check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. leam .OR. lquip .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lgoodwin) THEN ipot = gw_type - check = .NOT. (llj .OR. llj_charmm .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. llj_charmm .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (leam) THEN ipot = ea_type - check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. lquip .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. lquip .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lquip) THEN ipot = quip_type - check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lnequip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lnequip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lnequip) THEN ipot = nequip_type - check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lbmhft & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lallegro & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + CPASSERT(check) + END IF + IF (lallegro) THEN + ipot = allegro_type + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & + .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lbmhft) THEN ipot = ft_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + .OR. lallegro .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lbmhftd) THEN ipot = ftd_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + .OR. lallegro .OR. lbmhft .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lipbv) THEN ipot = ip_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lbuck4r) THEN ipot = b4_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuckmo .OR. lgp .OR. ltersoff & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuckmo .OR. lgp .OR. ltersoff & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF @@ -1173,43 +1209,43 @@ CONTAINS IF (ltersoff) THEN ipot = tersoff_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lsiepmann) THEN ipot = siepmann_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & .OR. ltersoff .OR. lgal .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lgal) THEN ipot = gal_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & .OR. ltersoff .OR. lsiepmann .OR. lgal21 .OR. ltab) CPASSERT(check) END IF IF (lgal21) THEN ipot = gal21_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab) CPASSERT(check) END IF IF (lgp) THEN ipot = gp_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgal21 .OR. lbuckmo & + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgal21 .OR. lbuckmo & .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab) CPASSERT(check) END IF IF (ltab) THEN ipot = tab_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & - .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lgal21 .OR. lbuckmo & - .OR. ltersoff .OR. lsiepmann .OR. lgal) + .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lgal21 & + .OR. lbuckmo .OR. ltersoff .OR. lsiepmann .OR. lgal) CPASSERT(check) END IF @@ -1253,6 +1289,8 @@ CONTAINS CALL pair_potential_quip_create(p%pot(i)%pot%set(std_dim)%quip) CASE (nequip_type) CALL pair_potential_nequip_create(p%pot(i)%pot%set(std_dim)%nequip) + CASE (allegro_type) + CALL pair_potential_allegro_create(p%pot(i)%pot%set(std_dim)%allegro) CASE (ft_type) CALL pair_potential_bmhft_create(p%pot(i)%pot%set(std_dim)%ft) CASE (ftd_type) @@ -1716,28 +1754,24 @@ CONTAINS DEALLOCATE (quip) END IF END SUBROUTINE pair_potential_quip_release + ! ************************************************************************************************** !> \brief Creates the NEQUIP potential type !> \param nequip ... -!> \author Teodoro Laino [teo] 11.2005 +!> \author Gabriele Tocci 2023 ! ************************************************************************************************** SUBROUTINE pair_potential_nequip_create(nequip) TYPE(nequip_pot_type), POINTER :: nequip CPASSERT(.NOT. ASSOCIATED(nequip)) ALLOCATE (nequip) - nequip%nequip_file_name = "" - nequip%unit_coords = "" - nequip%unit_forces = "" - nequip%unit_energy = "" - nequip%unit_cell = "" END SUBROUTINE pair_potential_nequip_create ! ************************************************************************************************** !> \brief Copy two NEQUIP potential type !> \param nequip_source ... !> \param nequip_dest ... -!> \author Teodoro Laino [teo] 11.2005 +!> \author Gabriele Tocci 2023 ! ************************************************************************************************** SUBROUTINE pair_potential_nequip_copy(nequip_source, nequip_dest) TYPE(nequip_pot_type), POINTER :: nequip_source, nequip_dest @@ -1745,47 +1779,27 @@ CONTAINS IF (.NOT. ASSOCIATED(nequip_source)) RETURN IF (ASSOCIATED(nequip_dest)) CALL pair_potential_nequip_release(nequip_dest) CALL pair_potential_nequip_create(nequip_dest) - nequip_dest%nequip_file_name = nequip_source%nequip_file_name - nequip_dest%nequip_version = nequip_source%nequip_version - nequip_dest%rcutsq = nequip_source%rcutsq - nequip_dest%unit_coords = nequip_source%unit_coords - nequip_dest%unit_coords_val = nequip_source%unit_coords_val - nequip_dest%unit_forces = nequip_source%unit_forces - nequip_dest%unit_forces_val = nequip_source%unit_forces_val - nequip_dest%unit_energy = nequip_source%unit_energy - nequip_dest%unit_energy_val = nequip_source%unit_energy_val - nequip_dest%unit_cell = nequip_source%unit_cell - nequip_dest%unit_cell_val = nequip_source%unit_cell_val + nequip_dest = nequip_source END SUBROUTINE pair_potential_nequip_copy ! ************************************************************************************************** !> \brief Creates the NEQUIP potential type !> \param nequip ... -!> \author Teodoro Laino [teo] 11.2005 +!> \author Gabriele Tocci 2023 ! ************************************************************************************************** SUBROUTINE pair_potential_nequip_clean(nequip) TYPE(nequip_pot_type), POINTER :: nequip IF (.NOT. ASSOCIATED(nequip)) RETURN - nequip%nequip_file_name = 'NULL' - nequip%nequip_version = 'NULL' - nequip%rcutsq = 0.0_dp - nequip%unit_energy_val = 0.0_dp - nequip%unit_coords_val = 0.0_dp - nequip%unit_forces_val = 0.0_dp - nequip%unit_cell_val = 0.0_dp - nequip%unit_coords = 'NULL' - nequip%unit_forces = 'NULL' - nequip%unit_energy = 'NULL' - nequip%unit_cell = 'NULL' + nequip = nequip_pot_type() END SUBROUTINE pair_potential_nequip_clean ! ************************************************************************************************** !> \brief Destroys the NEQUIP potential type !> \param nequip ... -!> \author Teodoro Laino [teo] 11.2005 +!> \author Gabriele Tocci 2023 ! ************************************************************************************************** SUBROUTINE pair_potential_nequip_release(nequip) TYPE(nequip_pot_type), POINTER :: nequip @@ -1795,6 +1809,59 @@ CONTAINS END IF END SUBROUTINE pair_potential_nequip_release +! ************************************************************************************************** +!> \brief Creates the ALLEGRO potential type +!> \param allegro ... +!> \author Gabriele Tocci 2023 +! ************************************************************************************************** + SUBROUTINE pair_potential_allegro_create(allegro) + TYPE(allegro_pot_type), POINTER :: allegro + + CPASSERT(.NOT. ASSOCIATED(allegro)) + ALLOCATE (allegro) + END SUBROUTINE pair_potential_allegro_create + +! ************************************************************************************************** +!> \brief Copy two ALLEGRO potential type +!> \param allegro_source ... +!> \param allegro_dest ... +!> \author Gabriele Tocci 2023 +! ************************************************************************************************** + SUBROUTINE pair_potential_allegro_copy(allegro_source, allegro_dest) + TYPE(allegro_pot_type), POINTER :: allegro_source, allegro_dest + + IF (.NOT. ASSOCIATED(allegro_source)) RETURN + IF (ASSOCIATED(allegro_dest)) CALL pair_potential_allegro_release(allegro_dest) + CALL pair_potential_allegro_create(allegro_dest) + allegro_dest = allegro_source + END SUBROUTINE pair_potential_allegro_copy + +! ************************************************************************************************** +!> \brief Creates the ALLEGRO potential type +!> \param allegro ... +!> \author Gabriele Tocci 2023 +! ************************************************************************************************** + SUBROUTINE pair_potential_allegro_clean(allegro) + TYPE(allegro_pot_type), POINTER :: allegro + + IF (.NOT. ASSOCIATED(allegro)) RETURN + allegro = allegro_pot_type() + + END SUBROUTINE pair_potential_allegro_clean + +! ************************************************************************************************** +!> \brief Destroys the ALLEGRO potential type +!> \param allegro ... +!> \author Gabriele Tocci 2023 +! ************************************************************************************************** + SUBROUTINE pair_potential_allegro_release(allegro) + TYPE(allegro_pot_type), POINTER :: allegro + + IF (ASSOCIATED(allegro)) THEN + DEALLOCATE (allegro) + END IF + END SUBROUTINE pair_potential_allegro_release + ! ************************************************************************************************** !> \brief Creates the BMHFT (TOSI-FUMI) potential type !> \param ft ... diff --git a/tests/Fist/regtest-allegro/Allegro_si_MD.inp b/tests/Fist/regtest-allegro/Allegro_si_MD.inp new file mode 100644 index 0000000000..08c76a5f1a --- /dev/null +++ b/tests/Fist/regtest-allegro/Allegro_si_MD.inp @@ -0,0 +1,64 @@ +&GLOBAL + PROJECT Si + RUN_TYPE MD +&END GLOBAL +&FORCE_EVAL + &PRINT + &FORCES + &END + &END + METHOD FIST + &MM + &FORCEFIELD + &NONBONDED + &ALLEGRO + ATOMS Si + PARM_FILE_NAME Allegro/si-deployed.pth + UNIT_COORDS angstrom + UNIT_ENERGY eV + UNIT_FORCES eV*angstrom^-1 + &END ALLEGRO + &END NONBONDED + &END FORCEFIELD + &POISSON + &EWALD + EWALD_TYPE none + &END EWALD + &END POISSON + &END MM + &SUBSYS + &CELL + ABC 10.861999859992501 10.861999859992501 10.861999859992501 +# MULTIPLE_UNIT_CELL 4 4 4 + &END CELL + &TOPOLOGY + COORD_FILE_FORMAT XYZ + COORD_FILE_NAME si_input.xyz +# MULTIPLE_UNIT_CELL 4 4 4 + &END + &END SUBSYS +&END FORCE_EVAL + +&MOTION + &MD + ENSEMBLE NVT + STEPS 0 + TIMESTEP 1 + TEMPERATURE 300.0 + &THERMOSTAT + REGION GLOBAL + TYPE CSVR + &CSVR + TIMECON 100. + &END + &END + &END MD + &PRINT + &FORCES + &EACH + MD 1 + &END + UNIT eV*angstrom^-1 + &END + &END +&END MOTION diff --git a/tests/Fist/regtest-allegro/TEST_FILES b/tests/Fist/regtest-allegro/TEST_FILES new file mode 100644 index 0000000000..976b4818c7 --- /dev/null +++ b/tests/Fist/regtest-allegro/TEST_FILES @@ -0,0 +1,3 @@ +# Test of Allegro using libtorch https://pytorch.org/cppdocs/installing.html +Allegro_si_MD.inp 11 1.0E-14 -305.899211744308900 +#EOF diff --git a/tests/Fist/regtest-allegro/si_input.xyz b/tests/Fist/regtest-allegro/si_input.xyz new file mode 100644 index 0000000000..0913097829 --- /dev/null +++ b/tests/Fist/regtest-allegro/si_input.xyz @@ -0,0 +1,66 @@ +64 + +Si 0.10000000 0.00000000 0.00000000 +Si 0.10000000 2.71549996 2.71549996 +Si 2.71549996 2.71549996 0.00000000 +Si 2.71549996 0.00000000 2.71549996 +Si 4.07324995 1.35774998 4.07324995 +Si 1.35774998 1.35774998 1.35774998 +Si 1.35774998 4.07324995 4.07324995 +Si 4.07324995 4.07324995 1.35774998 +Si 0.00000000 0.00000000 5.43099993 +Si 0.00000000 2.71549996 8.14649989 +Si 2.71549996 2.71549996 5.43099993 +Si 2.71549996 0.00000000 8.14649989 +Si 4.07324995 1.35774998 9.50424988 +Si 1.35774998 1.35774998 6.78874991 +Si 1.35774998 4.07324995 9.50424988 +Si 4.07324995 4.07324995 6.78874991 +Si 0.00000000 5.43099993 0.00000000 +Si 0.00000000 8.14649989 2.71549996 +Si 2.71549996 8.14649989 0.00000000 +Si 2.71549996 5.43099993 2.71549996 +Si 4.07324995 6.78874991 4.07324995 +Si 1.35774998 6.78874991 1.35774998 +Si 1.35774998 9.50424988 4.07324995 +Si 4.07324995 9.50424988 1.35774998 +Si 0.00000000 5.43099993 5.43099993 +Si 0.00000000 8.14649989 8.14649989 +Si 2.71549996 8.14649989 5.43099993 +Si 2.71549996 5.43099993 8.14649989 +Si 4.07324995 6.78874991 9.50424988 +Si 1.35774998 6.78874991 6.78874991 +Si 1.35774998 9.50424988 9.50424988 +Si 4.07324995 9.50424988 6.78874991 +Si 5.43099993 0.00000000 0.00000000 +Si 5.43099993 2.71549996 2.71549996 +Si 8.14649989 2.71549996 0.00000000 +Si 8.14649989 0.00000000 2.71549996 +Si 9.50424988 1.35774998 4.07324995 +Si 6.78874991 1.35774998 1.35774998 +Si 6.78874991 4.07324995 4.07324995 +Si 9.50424988 4.07324995 1.35774998 +Si 5.43099993 0.00000000 5.43099993 +Si 5.43099993 2.71549996 8.14649989 +Si 8.14649989 2.71549996 5.43099993 +Si 8.14649989 0.00000000 8.14649989 +Si 9.50424988 1.35774998 9.50424988 +Si 6.78874991 1.35774998 6.78874991 +Si 6.78874991 4.07324995 9.50424988 +Si 9.50424988 4.07324995 6.78874991 +Si 5.43099993 5.43099993 0.00000000 +Si 5.43099993 8.14649989 2.71549996 +Si 8.14649989 8.14649989 0.00000000 +Si 8.14649989 5.43099993 2.71549996 +Si 9.50424988 6.78874991 4.07324995 +Si 6.78874991 6.78874991 1.35774998 +Si 6.78874991 9.50424988 4.07324995 +Si 9.50424988 9.50424988 1.35774998 +Si 5.43099993 5.43099993 5.43099993 +Si 5.43099993 8.14649989 8.14649989 +Si 8.14649989 8.14649989 5.43099993 +Si 8.14649989 5.43099993 8.14649989 +Si 9.50424988 6.78874991 9.50424988 +Si 6.78874991 6.78874991 6.78874991 +Si 6.78874991 9.50424988 9.50424988 +Si 9.60424988 9.50424988 6.78874991 diff --git a/tests/TEST_DIRS b/tests/TEST_DIRS index 3d1d3b941f..ad34d63c0b 100644 --- a/tests/TEST_DIRS +++ b/tests/TEST_DIRS @@ -338,6 +338,7 @@ Fist/regtest-spgr spglib Fist/regtest-plumed2 plumed2 Fist/regtest-quip quip Fist/regtest-nequip libtorch +Fist/regtest-allegro libtorch Fist/regtest-16 DFTB/regtest-vdw QS/regtest-tddfpt-force-gapw diff --git a/tools/toolchain/install_cp2k_toolchain.sh b/tools/toolchain/install_cp2k_toolchain.sh index 829f97228c..218ab6d837 100755 --- a/tools/toolchain/install_cp2k_toolchain.sh +++ b/tools/toolchain/install_cp2k_toolchain.sh @@ -220,7 +220,7 @@ The --with-PKG options follow the rules: Default = install --with-libvori Enable libvori for the Voronoi integration (and the BQB compressed trajectory format) Default = install - --with-libtorch Enable libtorch the machine learning framework needed for NequIP. + --with-libtorch Enable libtorch the machine learning framework needed for NequIP and Allegro Default = no FURTHER INSTRUCTIONS @@ -305,7 +305,7 @@ with_spfft="__DONTUSE__" with_spla="__DONTUSE__" with_cosma="__INSTALL__" with_libvori="__INSTALL__" -with_libtorch="__DONTUSE__" +with_libtorch="__INSTALL__" # for MPI, we try to detect system MPI variant if (command -v mpiexec > /dev/null 2>&1); then # check if we are dealing with openmpi, mpich or intelmpi