diff --git a/INSTALL.md b/INSTALL.md index b19689447a..9dd61187bf 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -456,6 +456,15 @@ Calls to `offload_dgemm` also accept pointers on GPU or a combination of them. - See for more information. --> +### 2y. DeePMD-kit (optional, wider range of interaction potentials) + +DeePMD-kit - Deep Potential Molecular Dyanmics. Support for DeePMD-kit can be enabled via the flag +`-D__DEEPMD`. + +- DeePMD-kit C interface can be downloaded from + +- For more information see . + ## 3. Compile ### 3a. ARCH files diff --git a/data/DeePMD/W.pb b/data/DeePMD/W.pb new file mode 100644 index 0000000000..5ed22eb83e Binary files /dev/null and b/data/DeePMD/W.pb differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 56cf808770..b47efb3efc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,7 @@ list( ct_methods.F ct_types.F debug_os_integrals.F + deepmd_wrapper.F dft_plus_u.F dgemm_counter_types.F distribution_2d_types.F @@ -310,6 +311,7 @@ list( lri_optimize_ri_basis_types.F ls_matrix_exp.F manybody_eam.F + manybody_deepmd.F manybody_gal21.F manybody_gal.F manybody_allegro.F diff --git a/src/common/bibliography.F b/src/common/bibliography.F index a2495aa49c..87b5b16342 100644 --- a/src/common/bibliography.F +++ b/src/common/bibliography.F @@ -90,7 +90,7 @@ MODULE bibliography cp2kqs2020, Behler2007, Behler2011, Schran2020a, Schran2020b, & Rycroft2009, Thomas2015, Brehm2018, Brehm2020, Shigeta2001, Heinecke2016, & Brehm2021, Bussy2021a, Bussy2021b, Ditler2021, Ditler2022, Mattiat2019, Mattiat2022, & - Belleflamme2023, Knizia2013, Musaelian2023, Eriksen2020, Graml2023, Bussy2023 + Belleflamme2023, Knizia2013, Musaelian2023, Eriksen2020, Graml2023, Bussy2023, Wang2018, Zeng2023 CONTAINS @@ -4904,6 +4904,86 @@ SUBROUTINE add_all_references() "ER"), & DOI="10.48550/arXiv.2306.16066") + CALL add_reference(key=Wang2018, ISI_record=s2a( & + "TY JOUR", & + "PT J", & + "AU Wang, Han", & + " Zhang, Linfeng", & + " Han, Jiequn", & + " E, Weinan", & + "TI DeePMD-kit: A Deep Learning Package for Many-body", & + " Potential Energy Representation and Molecular Dynamics", & + "SO Computer Physics Communications", & + "JF Computer Physics Communications", & + "JO Computer Physics Communications", & + "SN 178-184", & + "IS 7", & + "PY 2018", & + "VL 228", & + "DI 10.1016/j.cpc.2018.03.016", & + "ER"), & + DOI="10.1016/j.cpc.2018.03.016") + + CALL add_reference(key=Zeng2023, ISI_record=s2a( & + "TY JOUR", & + "PT J", & + "AU Zeng, Jinzhe", & + " Zhang, Duo", & + " Lu, Denghui", & + " Mo, Pinghui", & + " Li, Zeyu", & + " Chen, Yixiao", & + " Rynik, Marián", & + " Huang, Li'ang", & + " Li, Ziyao", & + " Shi, Shaochen", & + " Wang, Yingze", & + " Ye, Haotian", & + " Tuo, Ping", & + " Yang, Jiabin", & + " Ding, Ye", & + " Li, Yifan", & + " Tisi, Davide", & + " Zeng, Qiyu", & + " Bao, Han", & + " Xia, Yu", & + " Huang, Jiameng", & + " Muraoka, Koki", & + " Wang, Yibo", & + " Chang, Junhan", & + " Yuan, Fengbo", & + " Bore, Sigbjørn Løland", & + " Cai, Chun", & + " Lin, Yinnian", & + " Wang, Bo", & + " Xu, Jiayan", & + " Zhu, Jia-Xin", & + " Luo, Chenxing", & + " Zhang, Yuzhi", & + " Goodall, Rhys E. A.", & + " Liang, Wenshuo", & + " Singh, Anurag Kumar", & + " Yao, Sikai", & + " Zhang, Jingchao", & + " Wentzcovitch, Renata", & + " Han, Jiequn", & + " Liu, Jie", & + " Jia, Weile", & + " York, Darrin M.", & + " E, Weinan", & + " Car, Roberto", & + " Zhang, Linfeng", & + " Wang, Han", & + "TI DeePMD-kit v2: A software package for deep potential models", & + "SO The Journal of Chemical Physics", & + "JF The Journal of Chemical Physics", & + "JO The Journal of Chemical Physics", & + "PY 2023", & + "VL 159", & + "DI 10.1063/5.0155600", & + "ER"), & + DOI="10.1063/5.0155600") + END SUBROUTINE add_all_references END MODULE bibliography diff --git a/src/cp2k_info.F b/src/cp2k_info.F index 1b02e8b0b1..0430649307 100644 --- a/src/cp2k_info.F +++ b/src/cp2k_info.F @@ -137,9 +137,14 @@ FUNCTION cp2k_flags() RESULT(flags) flags = TRIM(flags)//" patched_cufft_70" #endif +#if defined(__DEEPMD) + flags = TRIM(flags)//" deepmd" +#endif + #if defined(__PW_FPGA) flags = TRIM(flags)//" pw_fpga" #endif + #if defined(__PW_FPGA_SP) flags = TRIM(flags)//" pw_fpga_sp" #endif diff --git a/src/deepmd_wrapper.F b/src/deepmd_wrapper.F new file mode 100644 index 0000000000..e8964a2753 --- /dev/null +++ b/src/deepmd_wrapper.F @@ -0,0 +1,144 @@ +!--------------------------------------------------------------------------------------------------! +! CP2K: A general program to perform molecular dynamics simulations ! +! Copyright 2000-2024 CP2K developers group ! +! ! +! SPDX-License-Identifier: GPL-2.0-or-later ! +!--------------------------------------------------------------------------------------------------! + +! ************************************************************************************************** +!> \brief Interface to the DeePMD-kit or a c++ wrapper. +!> \par History +!> 07.2019 created [Yongbin Zhuang] +!> 06.2021 refactored [Yunpei Liu] +!> 10.2023 adapt to DeePMD-kit C Interface [Yunpei Liu] +!> \author Yongbin Zhuang +! ************************************************************************************************** + +MODULE deepmd_wrapper + + USE ISO_C_BINDING, ONLY: C_CHAR,& + C_DOUBLE,& + C_INT,& + C_LOC,& + C_NULL_CHAR,& + C_NULL_PTR,& + C_PTR +#include "./base/base_uses.f90" + + IMPLICIT NONE + PRIVATE + PUBLIC :: dp_deep_pot, dp_deep_pot_compute, deepmd_model_release + +#if(__DEEPMD) + INTERFACE + FUNCTION dp_deep_pot_c(c_model) BIND(C, name="DP_NewDeepPot") + USE ISO_C_BINDING, ONLY: C_PTR, & + C_CHAR, & + C_DOUBLE, & + C_INT, & + C_NULL_CHAR, & + C_LOC + CHARACTER(LEN=1, KIND=C_CHAR) :: c_model(*) + TYPE(C_PTR) :: dp_deep_pot_c + + END FUNCTION + + SUBROUTINE dp_deep_pot_compute_c(dp, natom, & + coord, atype, cell, & + energy, force, virial, & + atomic_energy, atomic_virial) BIND(C, name="DP_DeepPotCompute") + USE ISO_C_BINDING, ONLY: C_PTR, & + C_INT, & + C_CHAR, & + C_DOUBLE + TYPE(C_PTR), VALUE :: dp + INTEGER(C_INT), VALUE :: natom + REAL(C_DOUBLE), DIMENSION(natom, 3), INTENT(IN) :: coord + INTEGER(C_INT), DIMENSION(natom), INTENT(IN) :: atype + REAL(C_DOUBLE), DIMENSION(9), INTENT(IN) :: cell + REAL(C_DOUBLE), INTENT(OUT) :: energy + REAL(C_DOUBLE), DIMENSION(natom, 3), INTENT(OUT) :: force + REAL(C_DOUBLE), DIMENSION(9), INTENT(OUT) :: virial + REAL(C_DOUBLE), DIMENSION(natom), INTENT(OUT) :: atomic_energy + REAL(C_DOUBLE), DIMENSION(natom, 9), INTENT(OUT) :: atomic_virial + + END SUBROUTINE + END INTERFACE +#endif + +CONTAINS + +! ************************************************************************************************** +!> \brief Load DP from a model file. +!> \param model Path to the model file. +!> \return Pointer to the DP model. +! ************************************************************************************************** + + FUNCTION dp_deep_pot(model) RESULT(pot) + CHARACTER(len=*), INTENT(INOUT) :: model + TYPE(C_PTR) :: pot + +#if(__DEEPMD) + pot = dp_deep_pot_c(c_model=TRIM(model)//C_NULL_CHAR) +#else + pot = C_NULL_PTR +#endif + END FUNCTION dp_deep_pot + +! ************************************************************************************************** +!> \brief Compute energy, force and virial from DP. +!> \param dp Pointer to the DP model. +!> \param natom Number of atoms. +!> \param coord Coordinates of the atoms. +!> \param atype Atom types. +!> \param cell Cell vectors. +!> \param energy Potential energy. +!> \param force Forces. +!> \param virial Virial tensor. +!> \param atomic_energy Atomic energies. +!> \param atomic_virial Atomic virial tensors. +! ************************************************************************************************** + + SUBROUTINE dp_deep_pot_compute(dp, natom, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial) + USE, INTRINSIC :: ISO_C_BINDING + TYPE(C_PTR), VALUE :: dp + INTEGER(C_INT), VALUE :: natom + REAL(C_DOUBLE), DIMENSION(natom, 3), INTENT(IN) :: coord + INTEGER(C_INT), DIMENSION(natom), INTENT(IN) :: atype + REAL(C_DOUBLE), DIMENSION(9), INTENT(IN), OPTIONAL :: cell + REAL(C_DOUBLE), INTENT(OUT), OPTIONAL :: energy + REAL(C_DOUBLE), DIMENSION(natom, 3), INTENT(OUT), OPTIONAL :: force + REAL(C_DOUBLE), DIMENSION(9), INTENT(OUT), OPTIONAL :: virial + REAL(C_DOUBLE), DIMENSION(natom), INTENT(OUT), OPTIONAL :: atomic_energy + REAL(C_DOUBLE), DIMENSION(natom, 9), INTENT(OUT), OPTIONAL :: atomic_virial + +#if(__DEEPMD) + CALL dp_deep_pot_compute_c(dp, natom, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial) +#else + CPABORT("CP2K was compiled without libdeepmd_c library.") + MARK_USED(dp) + MARK_USED(natom) + MARK_USED(coord) + MARK_USED(atype) + MARK_USED(cell) + MARK_USED(energy) + MARK_USED(force) + MARK_USED(virial) + MARK_USED(atomic_energy) + MARK_USED(atomic_virial) +#endif + END SUBROUTINE + +! ************************************************************************************************** +!> \brief Releases a deepmd model and all its ressources. +!> \param model Pointer to the DP model. +! ************************************************************************************************** + SUBROUTINE deepmd_model_release(model) + USE ISO_C_BINDING, ONLY: C_PTR, & + C_NULL_PTR + TYPE(C_PTR), INTENT(INOUT) :: model + + model = C_NULL_PTR + END SUBROUTINE deepmd_model_release + +END MODULE deepmd_wrapper diff --git a/src/fist_nonbond_env_types.F b/src/fist_nonbond_env_types.F index 429145bb67..a187bec62e 100644 --- a/src/fist_nonbond_env_types.F +++ b/src/fist_nonbond_env_types.F @@ -11,9 +11,11 @@ !> \author HAF ! ************************************************************************************************** MODULE fist_nonbond_env_types + USE ISO_C_BINDING, ONLY: C_PTR USE atomic_kind_types, ONLY: atomic_kind_type USE cell_types, ONLY: cell_release,& cell_type + USE deepmd_wrapper, ONLY: deepmd_model_release USE fist_neighbor_list_types, ONLY: fist_neighbor_deallocate,& fist_neighbor_type USE kinds, ONLY: default_string_length,& @@ -36,7 +38,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, allegro_data_type + quip_data_type, nequip_data_type, allegro_data_type, deepmd_data_type ! ************************************************************************************************** TYPE pos_type @@ -68,6 +70,13 @@ MODULE fist_nonbond_env_types TYPE(torch_model_type) :: model END TYPE + TYPE deepmd_data_type + INTEGER, POINTER :: use_indices(:) => NULL() + REAL(KIND=dp), POINTER :: force(:, :) => NULL() + REAL(KIND=dp) :: virial(3, 3) = 0.0_dp + TYPE(C_PTR) :: model + END TYPE + ! ************************************************************************************************** TYPE fist_nonbond_env_type INTEGER :: natom_types = -1 @@ -97,6 +106,7 @@ MODULE fist_nonbond_env_types TYPE(pos_type), DIMENSION(:), POINTER :: rcore_last_update_pbc => NULL() TYPE(eam_type), DIMENSION(:), POINTER :: eam_data => NULL() TYPE(quip_data_type), POINTER :: quip_data => NULL() + TYPE(deepmd_data_type), POINTER :: deepmd_data => NULL() TYPE(nequip_data_type), POINTER :: nequip_data => NULL() TYPE(allegro_data_type), POINTER :: allegro_data => NULL() END TYPE fist_nonbond_env_type @@ -132,6 +142,7 @@ MODULE fist_nonbond_env_types !> \param quip_data ... !> \param nequip_data ... !> \param allegro_data ... +!> \param deepmd_data ... !> \param charges ... !> \par History !> 12.2002 created [fawzi] @@ -142,7 +153,7 @@ SUBROUTINE fist_nonbond_env_get(fist_nonbond_env, potparm14, potparm, & shift_cutoff, do_electrostatics, 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, allegro_data, charges) + quip_data, nequip_data, allegro_data, deepmd_data, charges) TYPE(fist_nonbond_env_type), INTENT(IN) :: fist_nonbond_env TYPE(pair_potential_pp_type), OPTIONAL, POINTER :: potparm14, potparm @@ -162,6 +173,7 @@ SUBROUTINE fist_nonbond_env_get(fist_nonbond_env, potparm14, potparm, & TYPE(quip_data_type), OPTIONAL, POINTER :: quip_data TYPE(nequip_data_type), OPTIONAL, POINTER :: nequip_data TYPE(allegro_data_type), OPTIONAL, POINTER :: allegro_data + TYPE(deepmd_data_type), OPTIONAL, POINTER :: deepmd_data REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: charges IF (PRESENT(charges)) charges => fist_nonbond_env%charges @@ -170,6 +182,7 @@ SUBROUTINE fist_nonbond_env_get(fist_nonbond_env, potparm14, potparm, & 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(deepmd_data)) deepmd_data => fist_nonbond_env%deepmd_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 @@ -228,6 +241,7 @@ END SUBROUTINE fist_nonbond_env_get !> \param quip_data ... !> \param nequip_data ... !> \param allegro_data ... +!> \param deepmd_data ... !> \param charges ... !> \par History !> 12.2002 created [fawzi] @@ -238,7 +252,7 @@ SUBROUTINE fist_nonbond_env_set(fist_nonbond_env, potparm14, potparm, & shift_cutoff, do_electrostatics, 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, allegro_data, charges) + nequip_data, allegro_data, deepmd_data, charges) TYPE(fist_nonbond_env_type), INTENT(INOUT) :: fist_nonbond_env TYPE(pair_potential_pp_type), OPTIONAL, POINTER :: potparm14, potparm @@ -257,6 +271,7 @@ SUBROUTINE fist_nonbond_env_set(fist_nonbond_env, potparm14, potparm, & TYPE(quip_data_type), OPTIONAL, POINTER :: quip_data TYPE(nequip_data_type), OPTIONAL, POINTER :: nequip_data TYPE(allegro_data_type), OPTIONAL, POINTER :: allegro_data + TYPE(deepmd_data_type), OPTIONAL, POINTER :: deepmd_data REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: charges IF (PRESENT(potparm14)) fist_nonbond_env%potparm14 => potparm14 @@ -264,6 +279,7 @@ SUBROUTINE fist_nonbond_env_set(fist_nonbond_env, potparm14, potparm, & 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(deepmd_data)) fist_nonbond_env%deepmd_data => deepmd_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 @@ -337,6 +353,7 @@ SUBROUTINE fist_nonbond_env_create(fist_nonbond_env, atomic_kind_set, & NULLIFY (fist_nonbond_env%quip_data) NULLIFY (fist_nonbond_env%nequip_data) NULLIFY (fist_nonbond_env%allegro_data) + NULLIFY (fist_nonbond_env%deepmd_data) NULLIFY (fist_nonbond_env%charges) CALL init_fist_nonbond_env(fist_nonbond_env, atomic_kind_set, potparm14, & potparm, do_nonbonded, do_electrostatics, verlet_skin, ewald_rcut, ei_scale14, & @@ -542,6 +559,16 @@ SUBROUTINE fist_nonbond_env_release(fist_nonbond_env) CALL torch_model_release(fist_nonbond_env%allegro_data%model) DEALLOCATE (fist_nonbond_env%allegro_data) END IF + IF (ASSOCIATED(fist_nonbond_env%deepmd_data)) THEN + IF (ASSOCIATED(fist_nonbond_env%deepmd_data%force)) THEN + DEALLOCATE (fist_nonbond_env%deepmd_data%force) + END IF + IF (ASSOCIATED(fist_nonbond_env%deepmd_data%use_indices)) THEN + DEALLOCATE (fist_nonbond_env%deepmd_data%use_indices) + END IF + CALL deepmd_model_release(fist_nonbond_env%deepmd_data%model) + DEALLOCATE (fist_nonbond_env%deepmd_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 ac3f89a00a..3e5f2da0fa 100644 --- a/src/fist_nonbond_force.F +++ b/src/fist_nonbond_force.F @@ -38,7 +38,7 @@ MODULE fist_nonbond_force USE message_passing, ONLY: mp_comm_type USE pair_potential_coulomb, ONLY: potential_coulomb USE pair_potential_types, ONLY: & - allegro_type, gal21_type, gal_type, nequip_type, nosh_nosh, nosh_sh, & + allegro_type, deepmd_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,& @@ -229,7 +229,8 @@ SUBROUTINE force_nonbond(fist_nonbond_env, ewald_env, particle_set, cell, & 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 == allegro_type) + .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) & + .OR. ANY(pot%type == deepmd_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 +729,8 @@ SUBROUTINE bonded_correct_gaussian(fist_nonbond_env, atomic_kind_set, & 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 == allegro_type) + .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) & + .OR. ANY(pot%type == deepmd_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 13cb63a48f..d5e941d44d 100644 --- a/src/force_fields_all.F +++ b/src/force_fields_all.F @@ -64,10 +64,11 @@ MODULE force_fields_all spline_nonbond_control USE pair_potential_coulomb, ONLY: potential_coulomb USE pair_potential_types, ONLY: & - 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 + allegro_type, deepmd_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 USE particle_types, ONLY: allocate_particle_set,& particle_type USE physcon, ONLY: bohr @@ -2041,7 +2042,7 @@ SUBROUTINE force_field_pack_charge(atomic_kind_set, qmmm_env, fatal, iw, iw4, & 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, & - allegro_type) + allegro_type, deepmd_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 3f2034ee44..acb6366e5f 100644 --- a/src/force_fields_input.F +++ b/src/force_fields_input.F @@ -65,12 +65,12 @@ MODULE force_fields_input USE memory_utilities, ONLY: reallocate USE message_passing, ONLY: mp_para_env_type USE pair_potential_types, ONLY: & - 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 + allegro_pot_type, allegro_type, b4_type, bm_type, deepmd_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 @@ -107,9 +107,9 @@ SUBROUTINE read_force_field_section1(ff_section, mm_section, ff_type, para_env) CHARACTER(LEN=default_string_length), & DIMENSION(:), POINTER :: atm_names - 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 + INTEGER :: nallegro, nb4, nbends, nbm, nbmhft, nbmhftd, nbonds, nchg, ndeepmd, 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 @@ -319,6 +319,19 @@ SUBROUTINE read_force_field_section1(ff_section, mm_section, ff_type, para_env) 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) END IF + + tmp_section2 => section_vals_get_subs_vals(tmp_section, "DEEPMD") + CALL section_vals_get(tmp_section2, explicit=explicit, n_repetition=ndeepmd) + ntot = nlj + nwl + neam + ngd + nipbv + nbmhft + nbmhftd + nb4 + nbm + ngp + ntersoff + ngal + ngal21 + nsiepmann + & + nquip + nnequip + nallegro + ntab + IF (explicit) THEN + ! avoid repeating the deepmd section for each pair + CALL section_vals_val_get(tmp_section2, "ATOMS", c_vals=atm_names) + ndeepmd = ndeepmd - 1 + SIZE(atm_names) + (SIZE(atm_names)*SIZE(atm_names) - SIZE(atm_names))/2 + CALL pair_potential_reallocate(inp_info%nonbonded, 1, ntot + ndeepmd, deepmd=.TRUE.) + CALL read_deepmd_section(inp_info%nonbonded, tmp_section2, ntot) + END IF + END IF tmp_section => section_vals_get_subs_vals(ff_section, "NONBONDED14") @@ -654,6 +667,47 @@ SUBROUTINE read_eam_section(nonbonded, section, start, para_env, mm_section) END DO END SUBROUTINE read_eam_section +! ************************************************************************************************** +!> \brief Reads the DEEPMD section +!> \param nonbonded ... +!> \param section ... +!> \param start ... +!> \author teo +! ************************************************************************************************** + SUBROUTINE read_deepmd_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) :: deepmd_file_name + CHARACTER(LEN=default_string_length), & + DIMENSION(:), POINTER :: atm_names + INTEGER :: isec, jsec, n_items + INTEGER, DIMENSION(:), POINTER :: atm_deepmd_types + + 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, "ATOMS_DEEPMD_TYPE", i_vals=atm_deepmd_types) + CALL section_vals_val_get(section, "POT_FILE_NAME", c_val=deepmd_file_name) + + DO isec = 1, SIZE(atm_names) + DO jsec = isec, SIZE(atm_names) + nonbonded%pot(start + n_items)%pot%type = deepmd_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)%deepmd%deepmd_file_name = discover_file(deepmd_file_name) + nonbonded%pot(start + n_items)%pot%set(1)%deepmd%atom_deepmd_type = atm_deepmd_types(isec) + nonbonded%pot(start + n_items)%pot%rcutsq = 0.0_dp + n_items = n_items + 1 + END DO + END DO + END SUBROUTINE read_deepmd_section + ! ************************************************************************************************** !> \brief Reads the QUIP section !> \param nonbonded ... diff --git a/src/input_cp2k_mm.F b/src/input_cp2k_mm.F index 14143f8582..6b1c2a7f6f 100644 --- a/src/input_cp2k_mm.F +++ b/src/input_cp2k_mm.F @@ -16,7 +16,8 @@ MODULE input_cp2k_mm USE bibliography, ONLY: & Batzner2022, Clabaut2020, Clabaut2021, Devynck2012, Dick1958, Foiles1986, Mitchell1993, & - Musaelian2023, QUIP_ref, Siepmann1995, Tersoff1988, Tosi1964a, Tosi1964b, Yamada2000 + Musaelian2023, QUIP_ref, Siepmann1995, Tersoff1988, Tosi1964a, Tosi1964b, Wang2018, & + Yamada2000, Zeng2023 USE cp_output_handling, ONLY: cp_print_key_section_create,& debug_print_level,& high_print_level,& @@ -1187,6 +1188,10 @@ SUBROUTINE create_NONBONDED_section(section) CALL section_add_subsection(section, subsection) CALL section_release(subsection) + CALL create_DEEPMD_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) @@ -1591,6 +1596,50 @@ SUBROUTINE create_ALLEGRO_section(section) END SUBROUTINE create_ALLEGRO_section +! ************************************************************************************************** +!> \brief This section specifies the input parameters for DEEPMD potential type +!> \param section the section to create +!> \author ybzhuang +! ************************************************************************************************** + SUBROUTINE create_DEEPMD_section(section) + TYPE(section_type), POINTER :: section + + TYPE(keyword_type), POINTER :: keyword + + CALL section_create(section, __LOCATION__, name="DEEPMD", & + description="This section specifies the input parameters for Deep Potential type. "// & + "Mainly intended for things like neural network to DFT "// & + "to achieve correlated-wavefunction-like accuracy. "// & + "Requires linking with DeePMD-kit library from "// & + "https://docs.deepmodeling.com/projects/deepmd/en/master .", & + citations=(/Wang2018, Zeng2023/), 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 Deep Potential. "// & + "Provide a list of each element, "// & + "making sure that the mapping from the ATOMS list to DeePMD atom types is correct.", & + 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="POT_FILE_NAME", & + variants=(/"PARMFILE"/), & + description="Specifies the filename that contains the DeePMD-kit potential.", & + usage="POT_FILE_NAME {FILENAME}", default_lc_val="graph.pb") + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + CALL keyword_create(keyword, __LOCATION__, name="ATOMS_DEEPMD_TYPE", & + description="Specifies the atomic TYPE for the DeePMD-kit potential. "// & + "Provide a list of index, making sure that the mapping "// & + "from the ATOMS list to DeePMD atom types is correct. ", & + usage="ATOMS_DEEPMD_TYPE {TYPE INTEGER 1} {TYPE INTEGER 2} .. "// & + "{TYPE INTEGER N}", type_of_var=integer_t, & + n_var=-1) + CALL section_add_keyword(section, keyword) + CALL keyword_release(keyword) + END SUBROUTINE create_DEEPMD_section + ! ************************************************************************************************** !> \brief This section specifies the input parameters for Lennard-Jones potential type !> \param section the section to create diff --git a/src/manybody_deepmd.F b/src/manybody_deepmd.F new file mode 100644 index 0000000000..7e417536d0 --- /dev/null +++ b/src/manybody_deepmd.F @@ -0,0 +1,255 @@ +!--------------------------------------------------------------------------------------------------! +! CP2K: A general program to perform molecular dynamics simulations ! +! Copyright 2000-2024 CP2K developers group ! +! ! +! SPDX-License-Identifier: GPL-2.0-or-later ! +!--------------------------------------------------------------------------------------------------! + +MODULE manybody_deepmd + + USE cp_log_handling, ONLY: cp_logger_get_default_io_unit + USE atomic_kind_types, ONLY: atomic_kind_type + USE bibliography, ONLY: Wang2018, & + Zeng2023, & + cite_reference + USE cell_types, ONLY: cell_type + USE fist_nonbond_env_types, ONLY: fist_nonbond_env_get, & + fist_nonbond_env_set, & + fist_nonbond_env_type, & + deepmd_data_type + USE kinds, ONLY: dp + USE message_passing, ONLY: mp_para_env_type + USE pair_potential_types, ONLY: pair_potential_pp_type, & + pair_potential_single_type, & + deepmd_pot_type, & + deepmd_type + USE particle_types, ONLY: particle_type + USE physcon, ONLY: angstrom, & + evolt +#ifdef __DEEPMD + USE ISO_C_BINDING, ONLY: C_PTR, C_LOC + USE deepmd_wrapper, ONLY: dp_deep_pot, & + dp_deep_pot_compute +#endif + +#include "./base/base_uses.f90" + + IMPLICIT NONE + + PRIVATE + PUBLIC deepmd_energy_store_force_virial, deepmd_add_force_virial + + CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_deepmd' + +CONTAINS + +! ************************************************************************************************** +!> \brief ... +!> \param particle_set ... +!> \param cell ... +!> \param atomic_kind_set ... +!> \param potparm ... +!> \param fist_nonbond_env ... +!> \param pot_deepmd ... +!> \param para_env ... +! ************************************************************************************************** + SUBROUTINE deepmd_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, fist_nonbond_env, & + pot_deepmd, para_env) + 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(fist_nonbond_env_type), POINTER :: fist_nonbond_env + REAL(kind=dp) :: pot_deepmd + TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env + + CHARACTER(LEN=*), PARAMETER :: routineN = 'deepmd_energy_store_force_virial' + +#ifdef __DEEPMD + INTEGER :: i, iat, iat_use, ikind, & + jkind, n_atoms, n_atoms_use, & + output_unit + LOGICAL, ALLOCATABLE :: use_atom(:) + REAL(kind=dp) :: lattice(3, 3) + TYPE(pair_potential_single_type), & + POINTER :: pot + TYPE(deepmd_data_type), POINTER :: deepmd_data + TYPE(deepmd_pot_type), POINTER :: deepmd + REAL(kind=dp), ALLOCATABLE :: dpmd_force(:), dpmd_virial(:), & + dpmd_atomic_energy(:), dpmd_atomic_virial(:), & + dpmd_cell(:), dpmd_coord(:) + INTEGER, ALLOCATABLE :: dpmd_atype(:), use_atom_type(:) + INTEGER :: dpmd_natoms + +#endif + INTEGER :: handle + + CALL timeset(routineN, handle) +#ifndef __DEEPMD + CPABORT("In order to use DeePMD-kit you need to download and install libdeepmd_c") + MARK_USED(particle_set) + MARK_USED(cell) + MARK_USED(atomic_kind_set) + MARK_USED(potparm) + MARK_USED(fist_nonbond_env) + MARK_USED(pot_deepmd) + MARK_USED(para_env) +#else + n_atoms = SIZE(particle_set) + ALLOCATE (use_atom(n_atoms)) + ALLOCATE (use_atom_type(n_atoms)) + use_atom = .FALSE. + use_atom_type = 0 + + NULLIFY (deepmd) + + DO ikind = 1, SIZE(atomic_kind_set) + DO jkind = 1, SIZE(atomic_kind_set) + pot => potparm%pot(ikind, jkind)%pot + ! ensure that each atom is only used once + IF (ikind /= jkind) CYCLE + DO i = 1, SIZE(pot%type) + IF (pot%type(i) /= deepmd_type) CYCLE + DO iat = 1, n_atoms + IF (particle_set(iat)%atomic_kind%kind_number == ikind .OR. & + particle_set(iat)%atomic_kind%kind_number == jkind) THEN + use_atom(iat) = .TRUE. + use_atom_type(iat) = pot%set(i)%deepmd%atom_deepmd_type + END IF + END DO ! iat + END DO ! i + END DO ! jkind + END DO ! ikind + + n_atoms_use = COUNT(use_atom) + dpmd_natoms = n_atoms_use + ALLOCATE (dpmd_cell(9), dpmd_atype(dpmd_natoms), dpmd_coord(dpmd_natoms*3), & + dpmd_force(dpmd_natoms*3), dpmd_virial(9), & + dpmd_atomic_energy(dpmd_natoms), dpmd_atomic_virial(dpmd_natoms*9)) + + iat_use = 0 + DO iat = 1, n_atoms + IF (.NOT. use_atom(iat)) CYCLE + iat_use = iat_use + 1 + dpmd_coord((iat_use - 1)*3 + 1:(iat_use - 1)*3 + 3) = particle_set(iat)%r*angstrom + dpmd_atype(iat_use) = use_atom_type(iat) + END DO + IF (iat_use > 0) THEN + CALL cite_reference(Wang2018) + CALL cite_reference(Zeng2023) + END IF + output_unit = cp_logger_get_default_io_unit() + lattice = cell%hmat*angstrom + + ! change matrix to one d array + DO i = 1, 3 + dpmd_cell((i - 1)*3 + 1:(i - 1)*3 + 3) = lattice(:, i) + END DO + + ! get deepmd_data to save force, virial info + CALL fist_nonbond_env_get(fist_nonbond_env, deepmd_data=deepmd_data) + IF (.NOT. ASSOCIATED(deepmd_data)) THEN + ALLOCATE (deepmd_data) + CALL fist_nonbond_env_set(fist_nonbond_env, deepmd_data=deepmd_data) + NULLIFY (deepmd_data%use_indices, deepmd_data%force) + deepmd_data%model = dp_deep_pot(pot%set(1)%deepmd%deepmd_file_name) + END IF + IF (ASSOCIATED(deepmd_data%force)) THEN + IF (SIZE(deepmd_data%force, 2) /= n_atoms_use) THEN + DEALLOCATE (deepmd_data%force, deepmd_data%use_indices) + END IF + END IF + IF (.NOT. ASSOCIATED(deepmd_data%force)) THEN + ALLOCATE (deepmd_data%force(3, n_atoms_use)) + ALLOCATE (deepmd_data%use_indices(n_atoms_use)) + END IF + + CALL dp_deep_pot_compute(dp=deepmd_data%model, & + natom=dpmd_natoms, & + coord=dpmd_coord, & + atype=dpmd_atype, & + cell=dpmd_cell, & + energy=pot_deepmd, & + force=dpmd_force, & + virial=dpmd_virial, & + atomic_energy=dpmd_atomic_energy, & + atomic_virial=dpmd_atomic_virial) + + ! convert units + pot_deepmd = pot_deepmd/evolt + dpmd_force = dpmd_force/(evolt/angstrom) + dpmd_virial = dpmd_virial/evolt + + ! account for double counting from multiple MPI processes + IF (PRESENT(para_env)) THEN + pot_deepmd = pot_deepmd/REAL(para_env%num_pe, dp) + dpmd_force = dpmd_force/REAL(para_env%num_pe, dp) + dpmd_virial = dpmd_virial/REAL(para_env%num_pe, dp) + END IF + + ! save force, virial info + iat_use = 0 + DO iat = 1, n_atoms + IF (use_atom(iat)) THEN + iat_use = iat_use + 1 + deepmd_data%use_indices(iat_use) = iat + deepmd_data%force(1:3, iat_use) = dpmd_force((iat_use - 1)*3 + 1:(iat_use - 1)*3 + 3) + END IF + END DO + DO i = 1, 3 + deepmd_data%virial(1:3, i) = dpmd_virial((i - 1)*3 + 1:(i - 1)*3 + 3) + END DO + DEALLOCATE (use_atom, use_atom_type, dpmd_coord, dpmd_force, & + dpmd_virial, dpmd_atomic_energy, dpmd_atomic_virial, & + dpmd_cell, dpmd_atype) +#endif + CALL timestop(handle) + END SUBROUTINE deepmd_energy_store_force_virial + +! ************************************************************************************************** +!> \brief ... +!> \param fist_nonbond_env ... +!> \param force ... +!> \param pv_nonbond ... +!> \param use_virial ... +! ************************************************************************************************** + SUBROUTINE deepmd_add_force_virial(fist_nonbond_env, force, pv_nonbond, use_virial) + TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env + REAL(KIND=dp) :: force(:, :), pv_nonbond(3, 3) + LOGICAL, OPTIONAL :: use_virial + + CHARACTER(LEN=*), PARAMETER :: routineN = 'deepmd_add_force_virial' + INTEGER :: handle + +#ifdef __DEEPMD + INTEGER :: iat, iat_use + TYPE(deepmd_data_type), POINTER :: deepmd_data +#endif + + CALL timeset(routineN, handle) + +#ifndef __DEEPMD + CPABORT("In order to use DeePMD-kit you need to download and install libdeepmd_c") + MARK_USED(fist_nonbond_env) + MARK_USED(force) + MARK_USED(pv_nonbond) +#else + CALL fist_nonbond_env_get(fist_nonbond_env, deepmd_data=deepmd_data) + + IF (.NOT. ASSOCIATED(deepmd_data)) RETURN + + DO iat_use = 1, SIZE(deepmd_data%use_indices) + iat = deepmd_data%use_indices(iat_use) + CPASSERT(iat >= 1 .AND. iat <= SIZE(force, 2)) + force(1:3, iat) = force(1:3, iat) + deepmd_data%force(1:3, iat_use) + END DO + + IF (use_virial) THEN + pv_nonbond = pv_nonbond + deepmd_data%virial + END IF + +#endif + CALL timestop(handle) + END SUBROUTINE deepmd_add_force_virial + +END MODULE manybody_deepmd diff --git a/src/manybody_potential.F b/src/manybody_potential.F index 6dfb5fea2d..42f516b3bc 100644 --- a/src/manybody_potential.F +++ b/src/manybody_potential.F @@ -30,6 +30,8 @@ MODULE manybody_potential allegro_energy_store_force_virial,& destroy_allegro_arrays,& setup_allegro_arrays + USE manybody_deepmd, ONLY: deepmd_add_force_virial,& + deepmd_energy_store_force_virial USE manybody_eam, ONLY: get_force_eam USE manybody_gal, ONLY: destroy_gal_arrays,& gal_energy,& @@ -57,8 +59,8 @@ MODULE manybody_potential tersoff_forces USE message_passing, ONLY: mp_para_env_type USE pair_potential_types, ONLY: & - 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, & + allegro_pot_type, allegro_type, deepmd_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 @@ -107,12 +109,12 @@ SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, & nloc_size, npairs, nparticle, nparticle_local, nr_h3O, nr_o, nr_oh, nunique INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, unique_list_a, work_list INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list - 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) + LOGICAL :: any_allegro, any_deepmd, any_gal, & + any_gal21, any_nequip, any_quip, & + any_siepmann, any_tersoff + REAL(KIND=dp) :: drij, embed, pot_allegro, pot_deepmd, & + 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(:) @@ -138,6 +140,7 @@ SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, & any_quip = .FALSE. any_nequip = .FALSE. any_allegro = .FALSE. + any_deepmd = .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) @@ -183,6 +186,7 @@ SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, & 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_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_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) @@ -216,6 +220,13 @@ SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, & 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 + ! DEEPMD + IF (any_deepmd) THEN + CALL deepmd_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, & + fist_nonbond_env, pot_deepmd, para_env) + pot_manybody = pot_manybody + pot_deepmd + END IF + ! TERSOFF IF (any_tersoff) THEN NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a) @@ -576,9 +587,9 @@ SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, & 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_allegro, any_gal, any_gal21, & - any_nequip, any_quip, any_siepmann, & - any_tersoff + LOGICAL :: any_allegro, any_deepmd, 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 @@ -600,6 +611,7 @@ SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, & any_nequip = .FALSE. any_allegro = .FALSE. any_siepmann = .FALSE. + any_deepmd = .FALSE. any_gal = .FALSE. any_gal21 = .FALSE. CALL timeset(routineN, handle) @@ -631,6 +643,14 @@ SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, & END DO END DO END DO + DO ikind = 1, nkinds + DO jkind = ikind, nkinds + any_deepmd = any_deepmd .OR. ANY(potparm%pot(ikind, jkind)%pot%type == deepmd_type) + END DO + END DO + ! DEEPMD + IF (any_deepmd) & + CALL deepmd_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial) ! QUIP IF (use_virial) & @@ -654,6 +674,7 @@ SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, & cell_v = MATMUL(cell%hmat, cvi) any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type) any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type) + any_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_type) 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) diff --git a/src/pair_potential.F b/src/pair_potential.F index ea21f8dce5..f9fe3e8021 100644 --- a/src/pair_potential.F +++ b/src/pair_potential.F @@ -29,9 +29,9 @@ MODULE pair_potential default_string_length,& dp USE pair_potential_types, ONLY: & - 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, & + allegro_type, b4_type, bm_type, compare_pot, deepmd_type, 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,& @@ -186,7 +186,7 @@ SUBROUTINE spline_nonbond_control(spline_env, potparm, atomic_kind_set, & 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, allegro_type, tab_type) + b4_type, bm_type, gp_type, ea_type, quip_type, nequip_type, allegro_type, tab_type, deepmd_type) pot%no_pp = .FALSE. CASE (tersoff_type) pot%no_mb = .FALSE. @@ -204,7 +204,7 @@ SUBROUTINE spline_nonbond_control(spline_env, potparm, atomic_kind_set, & END SELECT ! Special case for EAM SELECT CASE (pot%type(k)) - CASE (ea_type, quip_type, nequip_type, allegro_type) + CASE (ea_type, quip_type, nequip_type, allegro_type, deepmd_type) pot%no_mb = .FALSE. END SELECT END DO @@ -610,6 +610,8 @@ SUBROUTINE get_nonbond_storage(spline_env, potparm, atomic_kind_set, do_zbl, & nvar = 1 + nvar CASE (allegro_type) nvar = 1 + nvar + CASE (deepmd_type) + nvar = 2 + nvar CASE (ft_type) nvar = 4 + nvar CASE (ftd_type) @@ -696,6 +698,10 @@ SUBROUTINE get_nonbond_storage(spline_env, potparm, atomic_kind_set, do_zbl, & CASE (allegro_type) pot_par(nk, 1) = str2id( & TRIM(potparm%pot(i, j)%pot%set(1)%allegro%allegro_file_name)) + CASE (deepmd_type) + pot_par(nk, 1) = str2id( & + TRIM(potparm%pot(i, j)%pot%set(1)%deepmd%deepmd_file_name)) + pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%deepmd%atom_deepmd_type 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 79ab8d7356..0f1212ecc5 100644 --- a/src/pair_potential_types.F +++ b/src/pair_potential_types.F @@ -52,9 +52,10 @@ MODULE pair_potential_types nequip_type = 16, & allegro_type = 17, & gal21_type = 18, & - tab_type = 19 + tab_type = 19, & + deepmd_type = 20 - INTEGER, PUBLIC, PARAMETER, DIMENSION(20) :: list_pot = (/nn_type, & + INTEGER, PUBLIC, PARAMETER, DIMENSION(21) :: list_pot = (/nn_type, & lj_type, & lj_charmm_type, & ft_type, & @@ -73,7 +74,8 @@ MODULE pair_potential_types nequip_type, & allegro_type, & gal21_type, & - tab_type/) + tab_type, & + deepmd_type/) ! Shell model INTEGER, PUBLIC, PARAMETER :: nosh_nosh = 0, & @@ -108,6 +110,7 @@ MODULE pair_potential_types quip_pot_type, & nequip_pot_type, & allegro_pot_type, & + deepmd_pot_type, & tersoff_pot_type, & siepmann_pot_type, & gal_pot_type, & @@ -172,6 +175,12 @@ MODULE pair_potential_types REAL(KIND=dp), POINTER, DIMENSION(:) :: rhop => NULL(), phip => NULL(), frhop => NULL() END TYPE eam_pot_type +! ************************************************************************************************** + TYPE deepmd_pot_type + CHARACTER(LEN=default_path_length) :: deepmd_file_name = 'NULL' + INTEGER :: atom_deepmd_type = 0 + END TYPE deepmd_pot_type + ! ************************************************************************************************** TYPE quip_pot_type CHARACTER(LEN=default_path_length) :: quip_file_name = "" @@ -355,6 +364,7 @@ MODULE pair_potential_types TYPE(quip_pot_type), POINTER :: quip => NULL() TYPE(nequip_pot_type), POINTER :: nequip => NULL() TYPE(allegro_pot_type), POINTER :: allegro => NULL() + TYPE(deepmd_pot_type), POINTER :: deepmd => NULL() TYPE(buck4ran_pot_type), POINTER :: buck4r => NULL() TYPE(buckmorse_pot_type), POINTER :: buckmo => NULL() TYPE(tersoff_pot_type), POINTER :: tersoff => NULL() @@ -462,6 +472,9 @@ SUBROUTINE compare_pot(pot1, pot2, compare) (SUM(ABS(pot1%set(i)%eam%phip - pot2%set(i)%eam%phip)) == 0.0_dp) .AND. & (SUM(ABS(pot1%set(i)%eam%frhop - pot2%set(i)%eam%frhop)) == 0.0_dp)) mycompare = .TRUE. END IF + CASE (deepmd_type) + IF ((pot1%set(i)%deepmd%deepmd_file_name == pot2%set(i)%deepmd%deepmd_file_name) .AND. & + (pot1%set(i)%deepmd%atom_deepmd_type == pot2%set(i)%deepmd%atom_deepmd_type)) mycompare = .TRUE. CASE (quip_type) IF ((pot1%set(i)%quip%quip_file_name == pot2%set(i)%quip%quip_file_name) .AND. & (pot1%set(i)%quip%init_args == pot2%set(i)%quip%init_args) .AND. & @@ -616,6 +629,7 @@ SUBROUTINE pair_potential_single_create(potparm, nset) potparm%set(i)%quip, & potparm%set(i)%nequip, & potparm%set(i)%allegro, & + potparm%set(i)%deepmd, & potparm%set(i)%buck4r, & potparm%set(i)%buckmo, & potparm%set(i)%tersoff, & @@ -661,6 +675,7 @@ SUBROUTINE pair_potential_single_clean(potparm) 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_deepmd_clean(potparm%set(i)%deepmd) 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) @@ -718,6 +733,7 @@ SUBROUTINE pair_potential_single_copy(potparm_source, potparm_dest) 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_deepmd_copy(potparm_source%set(i)%deepmd, potparm_dest%set(i)%deepmd) 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) @@ -768,6 +784,7 @@ SUBROUTINE pair_potential_single_add(potparm_source, potparm_dest) (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)%deepmd)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ft)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ftd)) .OR. & (ASSOCIATED(potparm_dest%set(1)%ipbv)) .OR. & @@ -820,6 +837,7 @@ SUBROUTINE pair_potential_single_add(potparm_source, potparm_dest) 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_deepmd_copy(potparm_tmp%set(i)%deepmd, potparm_dest%set(i)%deepmd) 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) @@ -856,6 +874,7 @@ SUBROUTINE pair_potential_single_add(potparm_source, potparm_dest) 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_deepmd_copy(potparm_source%set(j)%deepmd, potparm_dest%set(i)%deepmd) 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) @@ -894,6 +913,7 @@ SUBROUTINE pair_potential_single_release(potparm) 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_deepmd_release(potparm%set(i)%deepmd) 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) @@ -1080,19 +1100,22 @@ END SUBROUTINE pair_potential_p_copy !> \param gal ... !> \param gal21 ... !> \param tab ... +!> \param deepmd ... !> \author Teodoro Laino [Teo] 11.2005 ! ************************************************************************************************** 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) + gp, tersoff, siepmann, gal, gal21, tab, deepmd) 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, & - allegro, bmhft, bmhftd, ipbv, buck4r, buckmo, gp, tersoff, siepmann, gal, gal21, tab + allegro, bmhft, bmhftd, ipbv, buck4r, buckmo, gp, tersoff, siepmann, gal, gal21, tab, & + deepmd INTEGER :: i, ipot, lb1_old, std_dim, ub1_old - LOGICAL :: check, lallegro, 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, ldeepmd, leam, lgal, lgal21, & + lgoodwin, lgp, lipbv, llj, llj_charmm, lnequip, lquip, lsiepmann, ltab, ltersoff, & + lwilliams TYPE(pair_potential_p_type), POINTER :: work NULLIFY (work) @@ -1105,6 +1128,7 @@ SUBROUTINE pair_potential_reallocate(p, lb1_new, ub1_new, lj, lj_charmm, william lquip = .FALSE.; IF (PRESENT(quip)) lquip = quip lnequip = .FALSE.; IF (PRESENT(nequip)) lnequip = nequip lallegro = .FALSE.; IF (PRESENT(allegro)) lallegro = allegro + ldeepmd = .FALSE.; IF (PRESENT(deepmd)) ldeepmd = deepmd lbmhft = .FALSE.; IF (PRESENT(bmhft)) lbmhft = bmhft lbmhftd = .FALSE.; IF (PRESENT(bmhftd)) lbmhftd = bmhftd lipbv = .FALSE.; IF (PRESENT(ipbv)) lipbv = ipbv @@ -1121,126 +1145,133 @@ SUBROUTINE pair_potential_reallocate(p, lb1_new, ub1_new, lj, lj_charmm, william ipot = lj_type 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) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro & .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) + CPASSERT(check) + END IF + IF (ldeepmd) THEN + ipot = deepmd_type + check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .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 (lbmhft) THEN ipot = ft_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & .OR. lallegro .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lipbv .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lbuck4r .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuckmo .OR. lgp .OR. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) CPASSERT(check) END IF IF (lbuckmo) THEN ipot = bm_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. ltersoff & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) CPASSERT(check) END IF IF (ltersoff) THEN ipot = tersoff_type check = .NOT. (llj .OR. llj_charmm .OR. lgoodwin .OR. lwilliams .OR. leam .OR. lquip .OR. lnequip & .OR. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & - .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab) + .OR. lsiepmann .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & - .OR. ltersoff .OR. lgal .OR. lgal21 .OR. ltab) + .OR. ltersoff .OR. lgal .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & - .OR. ltersoff .OR. lsiepmann .OR. lgal21 .OR. ltab) + .OR. ltersoff .OR. lsiepmann .OR. lgal21 .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgp .OR. lbuckmo & - .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab) + .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab .OR. ldeepmd) 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. lallegro .OR. lbmhft .OR. lbmhftd .OR. lipbv .OR. lbuck4r .OR. lgal21 .OR. lbuckmo & - .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab) + .OR. ltersoff .OR. lsiepmann .OR. lgal .OR. ltab .OR. ldeepmd) CPASSERT(check) END IF IF (ltab) THEN @@ -1293,6 +1324,8 @@ SUBROUTINE pair_potential_reallocate(p, lb1_new, ub1_new, lj, lj_charmm, william 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 (deepmd_type) + CALL pair_potential_deepmd_create(p%pot(i)%pot%set(std_dim)%deepmd) CASE (ft_type) CALL pair_potential_bmhft_create(p%pot(i)%pot%set(std_dim)%ft) CASE (ftd_type) @@ -1697,6 +1730,59 @@ SUBROUTINE pair_potential_eam_release(eam) END IF END SUBROUTINE pair_potential_eam_release +! ************************************************************************************************** +!> \brief Creates the DEEPMD potential type +!> \param deepmd ... +!> \author Yongbin Zhuang 07.2019 +! ************************************************************************************************** + SUBROUTINE pair_potential_deepmd_create(deepmd) + TYPE(deepmd_pot_type), POINTER :: deepmd + + CPASSERT(.NOT. ASSOCIATED(deepmd)) + ALLOCATE (deepmd) + END SUBROUTINE pair_potential_deepmd_create + +! ************************************************************************************************** +!> \brief Copy two DEEPMD potential type +!> \param deepmd_source ... +!> \param deepmd_dest ... +!> \author Yongbin Zhuang 07.2019 +! ************************************************************************************************** + SUBROUTINE pair_potential_deepmd_copy(deepmd_source, deepmd_dest) + TYPE(deepmd_pot_type), POINTER :: deepmd_source, deepmd_dest + + IF (.NOT. ASSOCIATED(deepmd_source)) RETURN + NULLIFY (deepmd_dest) + IF (ASSOCIATED(deepmd_dest)) CALL pair_potential_deepmd_release(deepmd_dest) + CALL pair_potential_deepmd_create(deepmd_dest) + deepmd_dest = deepmd_source + END SUBROUTINE pair_potential_deepmd_copy + +! ************************************************************************************************** +!> \brief CLEAN the DEEPMD potential type +!> \param deepmd ... +!> \author Yongbin Zhuang 07.2019 +! ************************************************************************************************** + SUBROUTINE pair_potential_deepmd_clean(deepmd) + TYPE(deepmd_pot_type), POINTER :: deepmd + + IF (.NOT. ASSOCIATED(deepmd)) RETURN + deepmd = deepmd_pot_type() + END SUBROUTINE pair_potential_deepmd_clean + +! ************************************************************************************************** +!> \brief Destroys the DEEPMD potential type +!> \param deepmd ... +!> \author Yongbin Zhuang 07.2019 +! ************************************************************************************************** + SUBROUTINE pair_potential_deepmd_release(deepmd) + TYPE(deepmd_pot_type), POINTER :: deepmd + + IF (ASSOCIATED(deepmd)) THEN + DEALLOCATE (deepmd) + END IF + END SUBROUTINE pair_potential_deepmd_release + ! ************************************************************************************************** !> \brief Creates the QUIP potential type !> \param quip ... diff --git a/tests/Fist/regtest-deepmd/DeePMD_W.inp b/tests/Fist/regtest-deepmd/DeePMD_W.inp new file mode 100644 index 0000000000..dd68f03263 --- /dev/null +++ b/tests/Fist/regtest-deepmd/DeePMD_W.inp @@ -0,0 +1,47 @@ +&GLOBAL + PROJECT W + RUN_TYPE ENERGY_FORCE + &PRINT DEBUG + &END PRINT +&END GLOBAL + +&FORCE_EVAL + METHOD FIST + &MM + &FORCEFIELD + &NONBONDED + &DEEPMD + ATOMS W + ATOMS_DEEPMD_TYPE 0 + POT_FILE_NAME DeePMD/W.pb + &END DEEPMD + &END NONBONDED + &END FORCEFIELD + &POISSON + &EWALD + EWALD_TYPE none + &END EWALD + &END POISSON + &END MM + &PRINT + &FORCES + &END FORCES + &END PRINT + &SUBSYS + &CELL + ABC 5.06227038 5.06227038 5.06227038 + &END CELL + &COORD + W 1.2656 0.0000 2.5311 + W 3.7967 0.0000 2.5311 + W 0.0000 2.5311 1.2656 + W 0.0000 2.5311 3.7967 + W 2.5311 3.7967 0.0000 + W 2.5311 1.2656 0.0000 + W 0.0000 0.0000 0.0000 + W 2.5311 2.5311 2.5311 + &END COORD + &TOPOLOGY + &END TOPOLOGY + &END SUBSYS +&END FORCE_EVAL diff --git a/tests/Fist/regtest-deepmd/TEST_FILES b/tests/Fist/regtest-deepmd/TEST_FILES new file mode 100644 index 0000000000..1ac6e62d1e --- /dev/null +++ b/tests/Fist/regtest-deepmd/TEST_FILES @@ -0,0 +1,2 @@ +# Test of DeePMD using libdeepmd_c https://docs.deepmodeling.com/projects/deepmd/en/master/install/install-from-c-library.html +DeePMD_W.inp 11 1.0E-6 -3.760691212989066 diff --git a/tests/TEST_DIRS b/tests/TEST_DIRS index 68ea88e612..58305d816f 100644 --- a/tests/TEST_DIRS +++ b/tests/TEST_DIRS @@ -356,5 +356,6 @@ Fist/regtest-plumed2 plumed2 Fist/regtest-quip quip Fist/regtest-nequip libtorch Fist/regtest-allegro libtorch +Fist/regtest-deepmd deepmd Fist/regtest-16 DFTB/regtest-vdw diff --git a/tools/toolchain/README.md b/tools/toolchain/README.md index 1e13564bec..876b9454ae 100644 --- a/tools/toolchain/README.md +++ b/tools/toolchain/README.md @@ -98,6 +98,7 @@ proprietary software packages, like e.g. MKL, these have to be installed separat | --------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | cmake | [BSD 3-Clause](https://gitlab.kitware.com/cmake/cmake/raw/master/Copyright.txt) | Yes | | cosma | [BSD 3-Clause](https://github.com/eth-cscs/COSMA/blob/master/LICENCE) | Yes | +| deepmd | [LGPL](https://github.com/deepmodeling/deepmd-kit/blob/master/LICENSE) | Yes | | elpa | [LGPL](https://gitlab.mpcdf.mpg.de/elpa/elpa/blob/master/LICENSE) | Yes | | fftw | [GPL](http://www.fftw.org/doc/License-and-Copyright.html) | Yes | | gcc | [GPL](https://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=COPYING;hb=HEAD) | Yes | diff --git a/tools/toolchain/install_cp2k_toolchain.sh b/tools/toolchain/install_cp2k_toolchain.sh index 957fe85c0c..dc2955eb5c 100755 --- a/tools/toolchain/install_cp2k_toolchain.sh +++ b/tools/toolchain/install_cp2k_toolchain.sh @@ -203,6 +203,8 @@ The --with-PKG options follow the rules: Default = no --with-quip Enable interface to QUIP library Default = no + --with-deepmd Enable interface to DeePMD-kit library. + Default = no --with-plumed Enable interface to the PLUMED library. Default = no --with-sirius Enable interface to the plane wave SIRIUS library. @@ -264,7 +266,7 @@ mpi_list="mpich openmpi intelmpi" math_list="mkl acml openblas" lib_list="fftw libint libxc libgrpp libxsmm cosma scalapack elpa cusolvermp plumed \ spfft spla ptscotch superlu pexsi quip gsl spglib hdf5 libvdwxc sirius - libvori libtorch" + libvori libtorch deepmd" package_list="${tool_list} ${mpi_list} ${math_list} ${lib_list}" # ------------------------------------------------------------------------ @@ -612,6 +614,9 @@ while [ $# -ge 1 ]; do --with-quip*) with_quip=$(read_with "${1}") ;; + --with-deepmd*) + with_deepmd=$(read_with $1) + ;; --with-plumed*) with_plumed=$(read_with "${1}") ;; diff --git a/tools/toolchain/scripts/arch_base.tmpl b/tools/toolchain/scripts/arch_base.tmpl index 804b6b0178..ddca384c15 100644 --- a/tools/toolchain/scripts/arch_base.tmpl +++ b/tools/toolchain/scripts/arch_base.tmpl @@ -10,6 +10,7 @@ WFLAGS = ${WFLAGS} # FCDEBFLAGS = ${FCDEBFLAGS} CFLAGS = ${CFLAGS} +CXXFLAGS = ${CXXFLAGS} FCFLAGS = ${FCFLAGS} CXXFLAGS = ${CXXFLAGS} # diff --git a/tools/toolchain/scripts/stage6/install_deepmd.sh b/tools/toolchain/scripts/stage6/install_deepmd.sh new file mode 100755 index 0000000000..406617c415 --- /dev/null +++ b/tools/toolchain/scripts/stage6/install_deepmd.sh @@ -0,0 +1,105 @@ +#!/bin/bash -e + +# TODO: Review and if possible fix shellcheck errors. +# shellcheck disable=all + +[ "${BASH_SOURCE[0]}" ] && SCRIPT_NAME="${BASH_SOURCE[0]}" || SCRIPT_NAME=$0 +SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_NAME")/.." && pwd -P)" + +deepmd_ver="2.2.7" +deepmd_sha256="605bbb0c3bcc847ecbfe7326bac9ff4cac5690accc8083122e3735290bb923ae" + +# shellcheck source=/dev/null +source "${SCRIPT_DIR}"/common_vars.sh +source "${SCRIPT_DIR}"/tool_kit.sh +source "${SCRIPT_DIR}"/signal_trap.sh +source "${INSTALLDIR}"/toolchain.conf +source "${INSTALLDIR}"/toolchain.env + +[ -f "${BUILDDIR}/setup_deepmd" ] && rm "${BUILDDIR}/setup_deepmd" + +DEEPMD_LDFLAGS='' +DEEPMD_LIBS='' + +! [ -d "${BUILDDIR}" ] && mkdir -p "${BUILDDIR}" +cd "${BUILDDIR}" + +case "$with_deepmd" in + __INSTALL__) + echo "==================== Installing DeePMD ====================" + pkg_install_dir="${INSTALLDIR}/libdeepmd_c-${deepmd_ver}" + install_lock_file="${pkg_install_dir}/install_successful" + deepmd_root="${pkg_install_dir}" + if verify_checksums "${install_lock_file}"; then + echo "libdeepmd_c-${deepmd_ver} is already installed, skipping it." + else + if [ -f libdeepmd_c-${deepmd_ver}.tar.gz ]; then + echo "libdeepmd_c-${deepmd_ver}.tar.gz is found" + else + #download_pkg ${DOWNLOADER_FLAGS} -o libdeepmd_c-${deepmd_ver}.tar.gz ${deepmd_sha256} \ + #https://github.com/deepmodeling/deepmd-kit/releases/download/v${deepmd_ver}/libdeepmd_c.tar.gz + wget ${DOWNLOADER_FLAGS} --quiet \ + https://github.com/deepmodeling/deepmd-kit/releases/download/v${deepmd_ver}/libdeepmd_c.tar.gz + mv libdeepmd_c.tar.gz libdeepmd_c-${deepmd_ver}.tar.gz + fi + [ -d libdeepmd_c ] && rm -rf libdeepmd_c + echo "Installing from scratch into ${pkg_install_dir}" + tar -xzf libdeepmd_c-${deepmd_ver}.tar.gz + mv libdeepmd_c ${pkg_install_dir} + write_checksums "${install_lock_file}" "${SCRIPT_DIR}/stage6/$(basename ${SCRIPT_NAME})" + fi + DEEPMD_DFLAGS="-D__DEEPMD" + DEEPMD_CFLAGS="-I'${pkg_install_dir}/include'" + DEEPMD_LDFLAGS="-L'${pkg_install_dir}/lib' -Wl,--no-as-needed -ldeepmd_c -Wl,-rpath='${pkg_install_dir}/lib'" + ;; + __SYSTEM__) + echo "==================== Finding DeePMD from system paths ====================" + check_lib -ldeepmd "DEEPMD" + add_lib_from_paths DEEPMD_LDFLAGS "libdeepmd*" $LIB_PATHS + add_include_from_paths DEEPMD_CFLAGS "deepmd" $INCLUDE_PATHS + DEEPMD_DFLAGS="-D__DEEPMD" + ;; + __DONTUSE__) ;; + *) + echo "==================== Linking DEEPMD to user paths ====================" + pkg_install_dir="$with_deepmd" + check_dir "${pkg_install_dir}/include/deepmd" + check_dir "${pkg_install_dir}/lib" + DEEPMD_DFLAGS="-D__DEEPMD" + DEEPMD_CFLAGS="-I'${pkg_install_dir}/include'" + DEEPMD_LDFLAGS="-L'${pkg_install_dir}/lib' -Wl,--no-as-needed -ldeepmd_c -Wl,-rpath='${pkg_install_dir}/lib'" + ;; +esac + +if [ "$with_deepmd" != "__DONTUSE__" ]; then + DEEPMD_LIBS='-ldeepmd_c -lstdc++' + if [ "$with_deepmd" != "__SYSTEM__" ]; then + cat << EOF > "${BUILDDIR}/setup_deepmd" +prepend_path LD_LIBRARY_PATH "$pkg_install_dir/lib" +prepend_path LD_RUN_PATH "$pkg_install_dir/lib" +prepend_path LIBRARY_PATH "$pkg_install_dir/lib" +EOF + cat "${BUILDDIR}/setup_deepmd" >> $SETUPFILE + fi + + cat << EOF >> "${BUILDDIR}/setup_deepmd" +export DEEPMD_DFLAGS="${DEEPMD_DFLAGS}" +export DEEPMD_CFLAGS="${DEEPMD_CFLAGS}" +export DEEPMD_LDFLAGS="${DEEPMD_LDFLAGS}" +export DEEPMD_LIBS="${DEEPMD_LIBS}" +export CP_DFLAGS="\${CP_DFLAGS} ${DEEPMD_DFLAGS}" +export CP_CFLAGS="\${CP_CFLAGS} ${DEEPMD_CFLAGS}" +export CP_LDFLAGS="\${CP_LDFLAGS} ${DEEPMD_LDFLAGS}" +export CP_LIBS="\${CP_LIBS} ${DEEPMD_LIBS}" +EOF + cat << EOF >> "${INSTALLDIR}/lsan.supp" +# leaks related to DeePMD-kit and TensorFlow +leak:DP_NewDeepPot +EOF +fi + +load "${BUILDDIR}/setup_deepmd" +write_toolchain_env "${INSTALLDIR}" + +cd "${ROOTDIR}" +report_timing "deepmd" diff --git a/tools/toolchain/scripts/stage6/install_stage6.sh b/tools/toolchain/scripts/stage6/install_stage6.sh index 5fcc6124e4..cfce269145 100755 --- a/tools/toolchain/scripts/stage6/install_stage6.sh +++ b/tools/toolchain/scripts/stage6/install_stage6.sh @@ -6,5 +6,6 @@ ./scripts/stage6/install_quip.sh ./scripts/stage6/install_gsl.sh ./scripts/stage6/install_plumed.sh +./scripts/stage6/install_deepmd.sh #EOF