LCOV - code coverage report
Current view: top level - src - nnp_environment.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cb5d5fc) Lines: 87.6 % 402 352
Test Date: 2026-04-24 07:01:27 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief  Methods dealing with Neural Network potentials
      10              : !> \author Christoph Schran (christoph.schran@rub.de)
      11              : !> \date   2020-10-10
      12              : ! **************************************************************************************************
      13              : MODULE nnp_environment
      14              : 
      15              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      16              :    USE bibliography,                    ONLY: Behler2007,&
      17              :                                               Behler2011,&
      18              :                                               Schran2020a,&
      19              :                                               Schran2020b,&
      20              :                                               cite_reference
      21              :    USE cell_types,                      ONLY: cell_type
      22              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      23              :                                               cp_logger_get_default_unit_nr,&
      24              :                                               cp_logger_type
      25              :    USE cp_parser_methods,               ONLY: parser_read_line,&
      26              :                                               parser_search_string
      27              :    USE cp_parser_types,                 ONLY: cp_parser_type,&
      28              :                                               parser_create,&
      29              :                                               parser_release,&
      30              :                                               parser_reset
      31              :    USE cp_subsys_methods,               ONLY: cp_subsys_create
      32              :    USE cp_subsys_types,                 ONLY: cp_subsys_type
      33              :    USE distribution_1d_types,           ONLY: distribution_1d_release,&
      34              :                                               distribution_1d_type
      35              :    USE distribution_methods,            ONLY: distribute_molecules_1d
      36              :    USE input_section_types,             ONLY: section_vals_get,&
      37              :                                               section_vals_get_subs_vals,&
      38              :                                               section_vals_type,&
      39              :                                               section_vals_val_get
      40              :    USE kinds,                           ONLY: default_path_length,&
      41              :                                               dp
      42              :    USE message_passing,                 ONLY: mp_para_env_type
      43              :    USE molecule_kind_types,             ONLY: molecule_kind_type,&
      44              :                                               write_molecule_kind_set
      45              :    USE molecule_types,                  ONLY: molecule_type
      46              :    USE nnp_acsf,                        ONLY: nnp_init_acsf_groups,&
      47              :                                               nnp_sort_acsf,&
      48              :                                               nnp_sort_ele,&
      49              :                                               nnp_write_acsf
      50              :    USE nnp_environment_types,           ONLY: &
      51              :         nnp_actfnct_cos, nnp_actfnct_exp, nnp_actfnct_gaus, nnp_actfnct_invsig, nnp_actfnct_lin, &
      52              :         nnp_actfnct_quad, nnp_actfnct_sig, nnp_actfnct_softplus, nnp_actfnct_tanh, nnp_env_set, &
      53              :         nnp_type
      54              :    USE nnp_model,                       ONLY: nnp_write_arc
      55              :    USE particle_methods,                ONLY: write_fist_particle_coordinates,&
      56              :                                               write_particle_distances,&
      57              :                                               write_structure_data
      58              :    USE particle_types,                  ONLY: particle_type
      59              :    USE periodic_table,                  ONLY: get_ptable_info
      60              : #include "./base/base_uses.f90"
      61              : 
      62              :    IMPLICIT NONE
      63              : 
      64              :    PRIVATE
      65              : 
      66              :    LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .TRUE.
      67              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'nnp_environment'
      68              : 
      69              :    PUBLIC :: nnp_init
      70              :    PUBLIC :: nnp_init_model
      71              : 
      72              : CONTAINS
      73              : 
      74              : ! **************************************************************************************************
      75              : !> \brief Read and initialize all the information for neural network potentials
      76              : !> \param nnp_env ...
      77              : !> \param root_section ...
      78              : !> \param para_env ...
      79              : !> \param force_env_section ...
      80              : !> \param subsys_section ...
      81              : !> \param use_motion_section ...
      82              : !> \date   2020-10-10
      83              : !> \author Christoph Schran (christoph.schran@rub.de)
      84              : ! **************************************************************************************************
      85           28 :    SUBROUTINE nnp_init(nnp_env, root_section, para_env, force_env_section, subsys_section, &
      86              :                        use_motion_section)
      87              :       TYPE(nnp_type), INTENT(INOUT), POINTER             :: nnp_env
      88              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: root_section
      89              :       TYPE(mp_para_env_type), INTENT(IN), POINTER        :: para_env
      90              :       TYPE(section_vals_type), INTENT(INOUT), POINTER    :: force_env_section, subsys_section
      91              :       LOGICAL, INTENT(IN)                                :: use_motion_section
      92              : 
      93              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'nnp_init'
      94              : 
      95              :       INTEGER                                            :: handle
      96              :       LOGICAL                                            :: explicit
      97              :       TYPE(cp_subsys_type), POINTER                      :: subsys
      98              :       TYPE(section_vals_type), POINTER                   :: nnp_section
      99              : 
     100           14 :       CALL timeset(routineN, handle)
     101           14 :       CALL cite_reference(Behler2007)
     102           14 :       CALL cite_reference(Behler2011)
     103           14 :       CALL cite_reference(Schran2020a)
     104           14 :       CALL cite_reference(Schran2020b)
     105              : 
     106           14 :       CPASSERT(ASSOCIATED(nnp_env))
     107              : 
     108           14 :       NULLIFY (nnp_section, subsys)
     109              : 
     110           14 :       IF (.NOT. ASSOCIATED(subsys_section)) THEN
     111            0 :          subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
     112              :       END IF
     113           14 :       nnp_section => section_vals_get_subs_vals(force_env_section, "NNP")
     114           14 :       CALL section_vals_get(nnp_section, explicit=explicit)
     115           14 :       IF (.NOT. explicit) THEN
     116            0 :          CPWARN("NNP section not explicitly stated. Using default file names.")
     117              :       END IF
     118              : 
     119              :       CALL nnp_env_set(nnp_env=nnp_env, nnp_input=nnp_section, &
     120           14 :                        force_env_input=force_env_section)
     121              : 
     122              :       CALL cp_subsys_create(subsys, para_env, root_section, &
     123              :                             force_env_section=force_env_section, subsys_section=subsys_section, &
     124           14 :                             use_motion_section=use_motion_section)
     125              : 
     126              :       CALL nnp_init_subsys(nnp_env=nnp_env, subsys=subsys, &
     127           14 :                            subsys_section=subsys_section)
     128              : 
     129           14 :       CALL timestop(handle)
     130              : 
     131           14 :    END SUBROUTINE nnp_init
     132              : 
     133              : ! **************************************************************************************************
     134              : !> \brief Read and initialize all the information for neural network potentials
     135              : !> \param nnp_env ...
     136              : !> \param subsys ...
     137              : !> \param subsys_section ...
     138              : !> \date   2020-10-10
     139              : !> \author Christoph Schran (christoph.schran@rub.de)
     140              : ! **************************************************************************************************
     141           14 :    SUBROUTINE nnp_init_subsys(nnp_env, subsys, subsys_section)
     142              :       TYPE(nnp_type), INTENT(INOUT), POINTER             :: nnp_env
     143              :       TYPE(cp_subsys_type), INTENT(IN), POINTER          :: subsys
     144              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: subsys_section
     145              : 
     146              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'nnp_init_subsys'
     147              : 
     148              :       INTEGER                                            :: handle, natom
     149           14 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     150              :       TYPE(cell_type), POINTER                           :: my_cell, my_cell_ref
     151              :       TYPE(distribution_1d_type), POINTER                :: local_molecules, local_particles
     152           14 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     153           14 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     154           14 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     155              : 
     156           14 :       CALL timeset(routineN, handle)
     157              : 
     158              :       NULLIFY (atomic_kind_set, molecule_kind_set, my_cell, my_cell_ref, &
     159           14 :                particle_set, molecule_set, local_molecules, local_particles)
     160              : 
     161           14 :       particle_set => subsys%particles%els
     162           14 :       atomic_kind_set => subsys%atomic_kinds%els
     163           14 :       molecule_kind_set => subsys%molecule_kinds%els
     164           14 :       molecule_set => subsys%molecules%els
     165           14 :       my_cell => subsys%cell
     166           14 :       my_cell_ref => subsys%cell_ref
     167              : 
     168              :       !Print the molecule kind set
     169           14 :       CALL write_molecule_kind_set(molecule_kind_set, subsys_section)
     170              : 
     171              :       !Set up cell
     172              :       CALL nnp_env_set(nnp_env=nnp_env, subsys=subsys, &
     173              :                        cell=my_cell, cell_ref=my_cell_ref, &
     174           14 :                        use_ref_cell=subsys%use_ref_cell)
     175              : 
     176              :       !Print the atomic coordinates
     177           14 :       CALL write_fist_particle_coordinates(particle_set, subsys_section)
     178              :       CALL write_particle_distances(particle_set, cell=my_cell, &
     179           14 :                                     subsys_section=subsys_section)
     180              :       CALL write_structure_data(particle_set, cell=my_cell, &
     181           14 :                                 input_section=subsys_section)
     182              : 
     183              :       !Distribute molecules and atoms using the new data structures
     184              :       CALL distribute_molecules_1d(atomic_kind_set=atomic_kind_set, &
     185              :                                    particle_set=particle_set, &
     186              :                                    local_particles=local_particles, &
     187              :                                    molecule_kind_set=molecule_kind_set, &
     188              :                                    molecule_set=molecule_set, &
     189              :                                    local_molecules=local_molecules, &
     190           14 :                                    force_env_section=nnp_env%force_env_input)
     191              : 
     192           14 :       natom = SIZE(particle_set)
     193              : 
     194           42 :       ALLOCATE (nnp_env%nnp_forces(3, natom))
     195              : 
     196         9254 :       nnp_env%nnp_forces(:, :) = 0.0_dp
     197              : 
     198           14 :       nnp_env%nnp_potential_energy = 0.0_dp
     199              : 
     200              :       ! Set up arrays for calculation:
     201           14 :       nnp_env%num_atoms = natom
     202           42 :       ALLOCATE (nnp_env%ele_ind(natom))
     203           42 :       ALLOCATE (nnp_env%nuc_atoms(natom))
     204           42 :       ALLOCATE (nnp_env%coord(3, natom))
     205           42 :       ALLOCATE (nnp_env%atoms(natom))
     206           42 :       ALLOCATE (nnp_env%sort(natom))
     207           42 :       ALLOCATE (nnp_env%sort_inv(natom))
     208              : 
     209              :       CALL nnp_env_set(nnp_env=nnp_env, &
     210              :                        local_molecules=local_molecules, &
     211           14 :                        local_particles=local_particles)
     212              : 
     213           14 :       CALL distribution_1d_release(local_particles)
     214           14 :       CALL distribution_1d_release(local_molecules)
     215              : 
     216           14 :       CALL nnp_init_model(nnp_env=nnp_env, printtag="NNP")
     217              : 
     218           14 :       CALL timestop(handle)
     219              : 
     220           14 :    END SUBROUTINE nnp_init_subsys
     221              : 
     222              : ! **************************************************************************************************
     223              : !> \brief Initialize the Neural Network Potential
     224              : !> \param nnp_env ...
     225              : !> \param printtag ...
     226              : !> \date   2020-10-10
     227              : !> \author Christoph Schran (christoph.schran@rub.de)
     228              : ! **************************************************************************************************
     229           15 :    SUBROUTINE nnp_init_model(nnp_env, printtag)
     230              :       TYPE(nnp_type), INTENT(INOUT), POINTER             :: nnp_env
     231              :       CHARACTER(LEN=*), INTENT(IN)                       :: printtag
     232              : 
     233              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'nnp_init_model'
     234              :       INTEGER, PARAMETER                                 :: def_str_len = 256, &
     235              :                                                             default_path_length = 256
     236              : 
     237           15 :       CHARACTER(len=1), ALLOCATABLE, DIMENSION(:)        :: cactfnct
     238              :       CHARACTER(len=2)                                   :: ele
     239              :       CHARACTER(len=def_str_len)                         :: dummy, line
     240              :       CHARACTER(len=default_path_length)                 :: base_name, file_name
     241              :       INTEGER                                            :: handle, i, i_com, io, iweight, j, k, l, &
     242              :                                                             n_weight, nele, nuc_ele, symfnct_type, &
     243              :                                                             unit_nr
     244              :       LOGICAL                                            :: at_end, atom_e_found, explicit, first, &
     245              :                                                             found
     246              :       REAL(KIND=dp)                                      :: energy
     247           15 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: weights
     248              :       REAL(KIND=dp), DIMENSION(7)                        :: test_array
     249           15 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: work
     250              :       TYPE(cp_logger_type), POINTER                      :: logger
     251              :       TYPE(cp_parser_type)                               :: parser
     252              :       TYPE(section_vals_type), POINTER                   :: bias_section, model_section
     253              : 
     254           15 :       CALL timeset(routineN, handle)
     255              : 
     256           15 :       NULLIFY (logger)
     257              : 
     258           15 :       logger => cp_get_default_logger()
     259              : 
     260           15 :       IF (logger%para_env%is_source()) THEN
     261            8 :          unit_nr = cp_logger_get_default_unit_nr(logger)
     262            8 :          WRITE (unit_nr, *) ""
     263            8 :          WRITE (unit_nr, *) TRIM(printtag)//"| Neural Network Potential Force Environment"
     264              :       END IF
     265              : 
     266           15 :       model_section => section_vals_get_subs_vals(nnp_env%nnp_input, "MODEL")
     267           15 :       CALL section_vals_get(model_section, n_repetition=nnp_env%n_committee)
     268           60 :       ALLOCATE (nnp_env%atomic_energy(nnp_env%num_atoms, nnp_env%n_committee))
     269           45 :       ALLOCATE (nnp_env%committee_energy(nnp_env%n_committee))
     270           60 :       ALLOCATE (nnp_env%myforce(3, nnp_env%num_atoms, nnp_env%n_committee))
     271           60 :       ALLOCATE (nnp_env%committee_forces(3, nnp_env%num_atoms, nnp_env%n_committee))
     272           45 :       ALLOCATE (nnp_env%committee_stress(3, 3, nnp_env%n_committee))
     273              : 
     274           15 :       CALL section_vals_val_get(nnp_env%nnp_input, "NNP_INPUT_FILE_NAME", c_val=file_name)
     275           15 :       CALL parser_create(parser, file_name, para_env=logger%para_env)
     276              : 
     277              :       ! read number of elements and cut_type and check for scale and center
     278           15 :       nnp_env%scale_acsf = .FALSE.
     279           15 :       nnp_env%scale_sigma_acsf = .FALSE.
     280              :       ! Defaults for scale min and max:
     281           15 :       nnp_env%scmin = 0.0_dp
     282           15 :       nnp_env%scmax = 1.0_dp
     283           15 :       nnp_env%center_acsf = .FALSE.
     284           15 :       nnp_env%normnodes = .FALSE.
     285           15 :       nnp_env%n_hlayer = 0
     286              : 
     287           15 :       IF (logger%para_env%is_source()) THEN
     288            8 :          unit_nr = cp_logger_get_default_unit_nr(logger)
     289            8 :          WRITE (unit_nr, *) TRIM(printtag)//"| Reading NNP input from file: ", TRIM(file_name)
     290              :       END IF
     291              : 
     292              :       CALL parser_search_string(parser, "number_of_elements", .TRUE., found, line, &
     293           15 :                                 search_from_begin_of_file=.TRUE.)
     294           15 :       IF (found) THEN
     295           15 :          READ (line, *) dummy, nnp_env%n_ele
     296              :       ELSE
     297              :          CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     298            0 :                        "| number of elements missing in NNP_INPUT_FILE")
     299              :       END IF
     300              : 
     301              :       CALL parser_search_string(parser, "scale_symmetry_functions_sigma", .TRUE., found, &
     302           15 :                                 search_from_begin_of_file=.TRUE.)
     303           15 :       nnp_env%scale_sigma_acsf = found
     304              : 
     305              :       CALL parser_search_string(parser, "scale_symmetry_functions", .TRUE., found, &
     306           15 :                                 search_from_begin_of_file=.TRUE.)
     307           15 :       nnp_env%scale_acsf = found
     308              : 
     309              :       ! Test if there are two keywords of this:
     310           15 :       CALL parser_search_string(parser, "scale_symmetry_functions", .TRUE., found)
     311           15 :       IF (found .AND. nnp_env%scale_sigma_acsf) THEN
     312            0 :          CPWARN('Two scaling keywords in the input, we will ignore sigma scaling in this case')
     313            0 :          nnp_env%scale_sigma_acsf = .FALSE.
     314           15 :       ELSE IF (.NOT. found .AND. nnp_env%scale_sigma_acsf) THEN
     315            0 :          nnp_env%scale_acsf = .FALSE.
     316              :       END IF
     317              : 
     318              :       CALL parser_search_string(parser, "scale_min_short_atomic", .TRUE., found, line, &
     319           15 :                                 search_from_begin_of_file=.TRUE.)
     320           15 :       IF (found) READ (line, *) dummy, nnp_env%scmin
     321              : 
     322              :       CALL parser_search_string(parser, "scale_max_short_atomic", .TRUE., found, line, &
     323           15 :                                 search_from_begin_of_file=.TRUE.)
     324           15 :       IF (found) READ (line, *) dummy, nnp_env%scmax
     325              : 
     326              :       CALL parser_search_string(parser, "center_symmetry_functions", .TRUE., found, &
     327           15 :                                 search_from_begin_of_file=.TRUE.)
     328           15 :       nnp_env%center_acsf = found
     329              :       ! n2p2 overwrites sigma scaling, if centering is requested:
     330           15 :       IF (nnp_env%scale_sigma_acsf .AND. nnp_env%center_acsf) THEN
     331            0 :          nnp_env%scale_sigma_acsf = .FALSE.
     332              :       END IF
     333              :       ! Print warning if centering and scaling is requested:
     334           15 :       IF (nnp_env%center_acsf .AND. nnp_env%scale_acsf) THEN
     335           15 :          IF ((ABS(nnp_env%scmin) > EPSILON(0.0_dp)*1.0E+4_dp) .OR. (ABS(nnp_env%scmax - 1.0_dp) > EPSILON(0.0_dp)*1.0E+4_dp)) THEN
     336              :             CALL cp_warn(__LOCATION__, &
     337              :                          "Centering and scaling of symmetry functions requested while scale_min_short_atomic != 0 and/or "// &
     338              :                          "scale_max_short_atomic != 1. Make sure that scaling and centering of symmetry functions in CP2K "// &
     339              :                          "is consistent with your training code. "// &
     340            0 :                          "In CP2K: G* = (G - ave(G)) / (max(G) - min(G)) * (Smax - Smin) + Smin")
     341              :          END IF
     342              :       END IF
     343              : 
     344              :       CALL parser_search_string(parser, "normalize_nodes", .TRUE., found, &
     345           15 :                                 search_from_begin_of_file=.TRUE.)
     346           15 :       nnp_env%normnodes = found
     347              : 
     348              :       CALL parser_search_string(parser, "cutoff_type", .TRUE., found, line, &
     349           15 :                                 search_from_begin_of_file=.TRUE.)
     350           15 :       IF (found) THEN
     351           15 :          READ (line, *) dummy, nnp_env%cut_type
     352              :       ELSE
     353              :          CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     354            0 :                        "| no cutoff type specified in NNP_INPUT_FILE")
     355              :       END IF
     356              : 
     357              :       CALL parser_search_string(parser, "global_hidden_layers_short", .TRUE., found, line, &
     358           15 :                                 search_from_begin_of_file=.TRUE.)
     359           15 :       IF (found) THEN
     360           15 :          READ (line, *) dummy, nnp_env%n_hlayer
     361              :       ELSE
     362              :          CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     363            0 :                        "| number of hidden layers missing in NNP_INPUT_FILE")
     364              :       END IF
     365           15 :       nnp_env%n_layer = nnp_env%n_hlayer + 2
     366              : 
     367           15 :       nele = nnp_env%n_ele
     368           76 :       ALLOCATE (nnp_env%rad(nele))
     369           76 :       ALLOCATE (nnp_env%ang(nele))
     370           45 :       ALLOCATE (nnp_env%n_rad(nele))
     371           30 :       ALLOCATE (nnp_env%n_ang(nele))
     372           45 :       ALLOCATE (nnp_env%actfnct(nnp_env%n_hlayer + 1))
     373           45 :       ALLOCATE (cactfnct(nnp_env%n_hlayer + 1))
     374           30 :       ALLOCATE (nnp_env%ele(nele))
     375           30 :       ALLOCATE (nnp_env%nuc_ele(nele))
     376           76 :       ALLOCATE (nnp_env%arc(nele))
     377           46 :       DO i = 1, nele
     378          217 :          ALLOCATE (nnp_env%arc(i)%layer(nnp_env%n_layer))
     379          108 :          ALLOCATE (nnp_env%arc(i)%n_nodes(nnp_env%n_layer))
     380              :       END DO
     381           45 :       ALLOCATE (nnp_env%n_hnodes(nnp_env%n_hlayer))
     382           45 :       ALLOCATE (nnp_env%atom_energies(nele))
     383           46 :       nnp_env%atom_energies = 0.0_dp
     384              : 
     385              :       ! read elements, broadcast and sort
     386           15 :       CALL parser_reset(parser)
     387              :       DO
     388           30 :          CALL parser_search_string(parser, "elements", .TRUE., found, line)
     389           30 :          IF (found) THEN
     390           30 :             READ (line, *) dummy
     391           30 :             IF (TRIM(ADJUSTL(dummy)) == "elements") THEN
     392           15 :                READ (line, *) dummy, nnp_env%ele(:)
     393           15 :                CALL nnp_sort_ele(nnp_env%ele, nnp_env%nuc_ele)
     394           15 :                EXIT
     395              :             END IF
     396              :          ELSE
     397              :             CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     398            0 :                           "| elements not specified in NNP_INPUT_FILE")
     399              :          END IF
     400              :       END DO
     401              : 
     402              :       CALL parser_search_string(parser, "remove_atom_energies", .TRUE., atom_e_found, &
     403           15 :                                 search_from_begin_of_file=.TRUE.)
     404              : 
     405           15 :       IF (atom_e_found) THEN
     406            0 :          CALL parser_reset(parser)
     407            0 :          i = 0
     408              :          DO
     409            0 :             CALL parser_search_string(parser, "atom_energy", .TRUE., found, line)
     410            0 :             IF (found) THEN
     411            0 :                READ (line, *) dummy, ele, energy
     412            0 :                DO j = 1, nele
     413            0 :                   IF (nnp_env%ele(j) == TRIM(ele)) THEN
     414            0 :                      i = i + 1
     415            0 :                      nnp_env%atom_energies(j) = energy
     416              :                   END IF
     417              :                END DO
     418            0 :                IF (i == nele) EXIT
     419              :             ELSE
     420              :                CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     421            0 :                              "| atom energies are not specified")
     422              :             END IF
     423              :          END DO
     424              :       END IF
     425              : 
     426              :       CALL parser_search_string(parser, "global_nodes_short", .TRUE., found, line, &
     427           15 :                                 search_from_begin_of_file=.TRUE.)
     428           15 :       IF (found) THEN
     429           15 :          READ (line, *) dummy, nnp_env%n_hnodes(:)
     430              :       ELSE
     431              :          CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     432            0 :                        "NNP| global_nodes_short not specified in NNP_INPUT_FILE")
     433              :       END IF
     434              : 
     435              :       CALL parser_search_string(parser, "global_activation_short", .TRUE., found, line, &
     436           15 :                                 search_from_begin_of_file=.TRUE.)
     437           15 :       IF (found) THEN
     438           15 :          READ (line, *) dummy, cactfnct(:)
     439              :       ELSE
     440              :          CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     441            0 :                        "| global_activation_short not specified in NNP_INPUT_FILE")
     442              :       END IF
     443              : 
     444           60 :       DO i = 1, nnp_env%n_hlayer + 1
     445           15 :          SELECT CASE (cactfnct(i))
     446              :          CASE ("t")
     447           30 :             nnp_env%actfnct(i) = nnp_actfnct_tanh
     448              :          CASE ("g")
     449            0 :             nnp_env%actfnct(i) = nnp_actfnct_gaus
     450              :          CASE ("l")
     451           15 :             nnp_env%actfnct(i) = nnp_actfnct_lin
     452              :          CASE ("c")
     453            0 :             nnp_env%actfnct(i) = nnp_actfnct_cos
     454              :          CASE ("s")
     455            0 :             nnp_env%actfnct(i) = nnp_actfnct_sig
     456              :          CASE ("S")
     457            0 :             nnp_env%actfnct(i) = nnp_actfnct_invsig
     458              :          CASE ("e")
     459            0 :             nnp_env%actfnct(i) = nnp_actfnct_exp
     460              :          CASE ("p")
     461            0 :             nnp_env%actfnct(i) = nnp_actfnct_softplus
     462              :          CASE ("h")
     463            0 :             nnp_env%actfnct(i) = nnp_actfnct_quad
     464              :          CASE DEFAULT
     465              :             CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     466           45 :                           "| Activation function unkown")
     467              :          END SELECT
     468              :       END DO
     469              : 
     470              :       ! determine n_rad and n_ang
     471           46 :       DO i = 1, nele
     472           31 :          nnp_env%n_rad(i) = 0
     473           46 :          nnp_env%n_ang(i) = 0
     474              :       END DO
     475              : 
     476              :       ! count symfunctions
     477           15 :       CALL parser_reset(parser)
     478           15 :       first = .TRUE.
     479              :       DO
     480          871 :          CALL parser_search_string(parser, "symfunction_short", .TRUE., found, line)
     481          871 :          IF (found) THEN
     482          856 :             READ (line, *) dummy, ele, symfnct_type
     483         2626 :             DO i = 1, nele
     484         2626 :                IF (TRIM(ele) == nnp_env%ele(i)) THEN
     485          856 :                   IF (symfnct_type == 2) THEN
     486          486 :                      nnp_env%n_rad(i) = nnp_env%n_rad(i) + 1
     487          370 :                   ELSE IF (symfnct_type == 3) THEN
     488          370 :                      nnp_env%n_ang(i) = nnp_env%n_ang(i) + 1
     489              :                   ELSE
     490              :                      CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     491            0 :                                    "| Symmetry function type not supported")
     492              :                   END IF
     493              :                END IF
     494              :             END DO
     495              :             first = .FALSE.
     496              :          ELSE
     497           15 :             IF (first) CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     498            0 :                                      "| no symfunction_short specified in NNP_INPUT_FILE")
     499              :             ! no additional symfnct found
     500              :             EXIT
     501              :          END IF
     502              :       END DO
     503              : 
     504           46 :       DO i = 1, nele
     505           93 :          ALLOCATE (nnp_env%rad(i)%y(nnp_env%n_rad(i)))
     506           93 :          ALLOCATE (nnp_env%rad(i)%funccut(nnp_env%n_rad(i)))
     507           93 :          ALLOCATE (nnp_env%rad(i)%eta(nnp_env%n_rad(i)))
     508           93 :          ALLOCATE (nnp_env%rad(i)%rs(nnp_env%n_rad(i)))
     509           93 :          ALLOCATE (nnp_env%rad(i)%loc_min(nnp_env%n_rad(i)))
     510           93 :          ALLOCATE (nnp_env%rad(i)%loc_max(nnp_env%n_rad(i)))
     511           93 :          ALLOCATE (nnp_env%rad(i)%loc_av(nnp_env%n_rad(i)))
     512           93 :          ALLOCATE (nnp_env%rad(i)%sigma(nnp_env%n_rad(i)))
     513           62 :          ALLOCATE (nnp_env%rad(i)%ele(nnp_env%n_rad(i)))
     514           93 :          ALLOCATE (nnp_env%rad(i)%nuc_ele(nnp_env%n_rad(i)))
     515          517 :          nnp_env%rad(i)%funccut = 0.0_dp
     516          517 :          nnp_env%rad(i)%eta = 0.0_dp
     517          517 :          nnp_env%rad(i)%rs = 0.0_dp
     518          517 :          nnp_env%rad(i)%ele = 'X'
     519          517 :          nnp_env%rad(i)%nuc_ele = 0
     520              : 
     521           93 :          ALLOCATE (nnp_env%ang(i)%y(nnp_env%n_ang(i)))
     522           93 :          ALLOCATE (nnp_env%ang(i)%funccut(nnp_env%n_ang(i)))
     523           93 :          ALLOCATE (nnp_env%ang(i)%eta(nnp_env%n_ang(i)))
     524           93 :          ALLOCATE (nnp_env%ang(i)%zeta(nnp_env%n_ang(i)))
     525           93 :          ALLOCATE (nnp_env%ang(i)%prefzeta(nnp_env%n_ang(i)))
     526           93 :          ALLOCATE (nnp_env%ang(i)%lam(nnp_env%n_ang(i)))
     527           93 :          ALLOCATE (nnp_env%ang(i)%loc_min(nnp_env%n_ang(i)))
     528           93 :          ALLOCATE (nnp_env%ang(i)%loc_max(nnp_env%n_ang(i)))
     529           93 :          ALLOCATE (nnp_env%ang(i)%loc_av(nnp_env%n_ang(i)))
     530           93 :          ALLOCATE (nnp_env%ang(i)%sigma(nnp_env%n_ang(i)))
     531           62 :          ALLOCATE (nnp_env%ang(i)%ele1(nnp_env%n_ang(i)))
     532           62 :          ALLOCATE (nnp_env%ang(i)%ele2(nnp_env%n_ang(i)))
     533           93 :          ALLOCATE (nnp_env%ang(i)%nuc_ele1(nnp_env%n_ang(i)))
     534           93 :          ALLOCATE (nnp_env%ang(i)%nuc_ele2(nnp_env%n_ang(i)))
     535          401 :          nnp_env%ang(i)%funccut = 0.0_dp
     536          401 :          nnp_env%ang(i)%eta = 0.0_dp
     537          401 :          nnp_env%ang(i)%zeta = 0.0_dp
     538          401 :          nnp_env%ang(i)%prefzeta = 1.0_dp
     539          401 :          nnp_env%ang(i)%lam = 0.0_dp
     540          401 :          nnp_env%ang(i)%ele1 = 'X'
     541          401 :          nnp_env%ang(i)%ele2 = 'X'
     542          401 :          nnp_env%ang(i)%nuc_ele1 = 0
     543          401 :          nnp_env%ang(i)%nuc_ele2 = 0
     544              : 
     545              :          ! set number of nodes
     546           31 :          nnp_env%arc(i)%n_nodes(1) = nnp_env%n_rad(i) + nnp_env%n_ang(i)
     547           93 :          nnp_env%arc(i)%n_nodes(2:nnp_env%n_layer - 1) = nnp_env%n_hnodes
     548           31 :          nnp_env%arc(i)%n_nodes(nnp_env%n_layer) = 1
     549          170 :          DO j = 1, nnp_env%n_layer
     550          372 :             ALLOCATE (nnp_env%arc(i)%layer(j)%node(nnp_env%arc(i)%n_nodes(j)))
     551          372 :             ALLOCATE (nnp_env%arc(i)%layer(j)%node_grad(nnp_env%arc(i)%n_nodes(j)))
     552          527 :             ALLOCATE (nnp_env%arc(i)%layer(j)%tmp_der(nnp_env%arc(i)%n_nodes(1), nnp_env%arc(i)%n_nodes(j)))
     553              :          END DO
     554              :       END DO
     555              : 
     556              :       ! read, bcast and sort symfnct parameters
     557           46 :       DO i = 1, nele
     558           31 :          nnp_env%n_rad(i) = 0
     559           46 :          nnp_env%n_ang(i) = 0
     560              :       END DO
     561           15 :       CALL parser_reset(parser)
     562           15 :       first = .TRUE.
     563           15 :       nnp_env%max_cut = 0.0_dp
     564              :       DO
     565          871 :          CALL parser_search_string(parser, "symfunction_short", .TRUE., found, line)
     566          871 :          IF (found) THEN
     567          856 :             READ (line, *) dummy, ele, symfnct_type
     568         2626 :             DO i = 1, nele
     569         2626 :                IF (TRIM(ele) == nnp_env%ele(i)) THEN
     570          856 :                   IF (symfnct_type == 2) THEN
     571          486 :                      nnp_env%n_rad(i) = nnp_env%n_rad(i) + 1
     572          486 :                      READ (line, *) dummy, ele, symfnct_type, &
     573          486 :                         nnp_env%rad(i)%ele(nnp_env%n_rad(i)), &
     574          486 :                         nnp_env%rad(i)%eta(nnp_env%n_rad(i)), &
     575          486 :                         nnp_env%rad(i)%rs(nnp_env%n_rad(i)), &
     576          972 :                         nnp_env%rad(i)%funccut(nnp_env%n_rad(i))
     577          486 :                      IF (nnp_env%max_cut < nnp_env%rad(i)%funccut(nnp_env%n_rad(i))) THEN
     578           16 :                         nnp_env%max_cut = nnp_env%rad(i)%funccut(nnp_env%n_rad(i))
     579              :                      END IF
     580          370 :                   ELSE IF (symfnct_type == 3) THEN
     581          370 :                      nnp_env%n_ang(i) = nnp_env%n_ang(i) + 1
     582          370 :                      READ (line, *) dummy, ele, symfnct_type, &
     583          370 :                         nnp_env%ang(i)%ele1(nnp_env%n_ang(i)), &
     584          370 :                         nnp_env%ang(i)%ele2(nnp_env%n_ang(i)), &
     585          370 :                         nnp_env%ang(i)%eta(nnp_env%n_ang(i)), &
     586          370 :                         nnp_env%ang(i)%lam(nnp_env%n_ang(i)), &
     587          370 :                         nnp_env%ang(i)%zeta(nnp_env%n_ang(i)), &
     588          740 :                         nnp_env%ang(i)%funccut(nnp_env%n_ang(i))
     589              :                      nnp_env%ang(i)%prefzeta(nnp_env%n_ang(i)) = &
     590          370 :                         2.0_dp**(1.0_dp - nnp_env%ang(i)%zeta(nnp_env%n_ang(i)))
     591          370 :                      IF (nnp_env%max_cut < nnp_env%ang(i)%funccut(nnp_env%n_ang(i))) THEN
     592            0 :                         nnp_env%max_cut = nnp_env%ang(i)%funccut(nnp_env%n_ang(i))
     593              :                      END IF
     594              :                   ELSE
     595              :                      CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     596            0 :                                    "| Symmetry function type not supported")
     597              :                   END IF
     598              :                END IF
     599              :             END DO
     600              :             first = .FALSE.
     601              :          ELSE
     602           15 :             IF (first) CALL cp_abort(__LOCATION__, TRIM(printtag)// &
     603            0 :                                      "| no symfunction_short specified in NNP_INPUT_FILE")
     604              :             ! no additional symfnct found
     605              :             EXIT
     606              :          END IF
     607              :       END DO
     608              : 
     609           46 :       DO i = 1, nele
     610          517 :          DO j = 1, nnp_env%n_rad(i)
     611          517 :             CALL get_ptable_info(nnp_env%rad(i)%ele(j), number=nnp_env%rad(i)%nuc_ele(j))
     612              :          END DO
     613          416 :          DO j = 1, nnp_env%n_ang(i)
     614          370 :             CALL get_ptable_info(nnp_env%ang(i)%ele1(j), number=nnp_env%ang(i)%nuc_ele1(j))
     615          370 :             CALL get_ptable_info(nnp_env%ang(i)%ele2(j), number=nnp_env%ang(i)%nuc_ele2(j))
     616              :             ! sort ele1 and ele2
     617          401 :             IF (nnp_env%ang(i)%nuc_ele1(j) > nnp_env%ang(i)%nuc_ele2(j)) THEN
     618          164 :                ele = nnp_env%ang(i)%ele1(j)
     619          164 :                nnp_env%ang(i)%ele1(j) = nnp_env%ang(i)%ele2(j)
     620          164 :                nnp_env%ang(i)%ele2(j) = ele
     621          164 :                nuc_ele = nnp_env%ang(i)%nuc_ele1(j)
     622          164 :                nnp_env%ang(i)%nuc_ele1(j) = nnp_env%ang(i)%nuc_ele2(j)
     623          164 :                nnp_env%ang(i)%nuc_ele2(j) = nuc_ele
     624              :             END IF
     625              :          END DO
     626              :       END DO
     627              :       ! Done with input.nn file
     628           15 :       CALL parser_release(parser)
     629              : 
     630              :       ! sort symmetry functions and output information
     631           15 :       CALL nnp_sort_acsf(nnp_env)
     632           15 :       CALL nnp_write_acsf(nnp_env, logger%para_env, printtag)
     633           15 :       CALL nnp_write_arc(nnp_env, logger%para_env, printtag)
     634              : 
     635              :       ! read scaling information from file
     636           15 :       IF (nnp_env%scale_acsf .OR. nnp_env%center_acsf .OR. nnp_env%scale_sigma_acsf) THEN
     637           15 :          IF (logger%para_env%is_source()) THEN
     638            8 :             WRITE (unit_nr, *) TRIM(printtag)//"| Reading scaling information from file: ", TRIM(file_name)
     639              :          END IF
     640              :          CALL section_vals_val_get(nnp_env%nnp_input, "SCALE_FILE_NAME", &
     641           15 :                                    c_val=file_name)
     642           15 :          CALL parser_create(parser, file_name, para_env=logger%para_env)
     643              : 
     644              :          ! Get number of elements in scaling file
     645           15 :          CALL parser_read_line(parser, 1)
     646           15 :          k = 0
     647          119 :          DO WHILE (k < 7)
     648          105 :             READ (parser%input_line, *, IOSTAT=io) test_array(1:k)
     649          105 :             IF (io == -1) EXIT
     650          105 :             k = k + 1
     651              :          END DO
     652           15 :          k = k - 1
     653              : 
     654           15 :          IF (k == 5 .AND. nnp_env%scale_sigma_acsf) THEN
     655            0 :             CPABORT("Sigma scaling requested, but scaling.data does not contain sigma.")
     656              :          END IF
     657              : 
     658           15 :          CALL parser_reset(parser)
     659           46 :          DO i = 1, nnp_env%n_ele
     660          517 :             DO j = 1, nnp_env%n_rad(i)
     661          486 :                CALL parser_read_line(parser, 1)
     662          517 :                IF (nnp_env%scale_sigma_acsf) THEN
     663            0 :                   READ (parser%input_line, *) dummy, dummy, &
     664            0 :                      nnp_env%rad(i)%loc_min(j), &
     665            0 :                      nnp_env%rad(i)%loc_max(j), &
     666            0 :                      nnp_env%rad(i)%loc_av(j), &
     667            0 :                      nnp_env%rad(i)%sigma(j)
     668              :                ELSE
     669          486 :                   READ (parser%input_line, *) dummy, dummy, &
     670          486 :                      nnp_env%rad(i)%loc_min(j), &
     671          486 :                      nnp_env%rad(i)%loc_max(j), &
     672          972 :                      nnp_env%rad(i)%loc_av(j)
     673              :                END IF
     674              :             END DO
     675          416 :             DO j = 1, nnp_env%n_ang(i)
     676          370 :                CALL parser_read_line(parser, 1)
     677          401 :                IF (nnp_env%scale_sigma_acsf) THEN
     678            0 :                   READ (parser%input_line, *) dummy, dummy, &
     679            0 :                      nnp_env%ang(i)%loc_min(j), &
     680            0 :                      nnp_env%ang(i)%loc_max(j), &
     681            0 :                      nnp_env%ang(i)%loc_av(j), &
     682            0 :                      nnp_env%ang(i)%sigma(j)
     683              :                ELSE
     684          370 :                   READ (parser%input_line, *) dummy, dummy, &
     685          370 :                      nnp_env%ang(i)%loc_min(j), &
     686          370 :                      nnp_env%ang(i)%loc_max(j), &
     687          740 :                      nnp_env%ang(i)%loc_av(j)
     688              :                END IF
     689              :             END DO
     690              :          END DO
     691           15 :          CALL parser_release(parser)
     692              :       END IF
     693              : 
     694           15 :       CALL nnp_init_acsf_groups(nnp_env)
     695              : 
     696              :       ! read weights from file
     697           46 :       DO i = 1, nnp_env%n_ele
     698          139 :          DO j = 2, nnp_env%n_layer
     699            0 :             ALLOCATE (nnp_env%arc(i)%layer(j)%weights(nnp_env%arc(i)%n_nodes(j - 1), &
     700          465 :                                                       nnp_env%arc(i)%n_nodes(j), nnp_env%n_committee))
     701          403 :             ALLOCATE (nnp_env%arc(i)%layer(j)%bweights(nnp_env%arc(i)%n_nodes(j), nnp_env%n_committee))
     702              :          END DO
     703              :       END DO
     704          114 :       DO i_com = 1, nnp_env%n_committee
     705           99 :          CALL section_vals_val_get(model_section, "WEIGHTS", c_val=base_name, i_rep_section=i_com)
     706           99 :          IF (logger%para_env%is_source()) THEN
     707           50 :             WRITE (unit_nr, *) TRIM(printtag)//"| Initializing weights for model: ", i_com
     708              :          END IF
     709          313 :          DO i = 1, nnp_env%n_ele
     710          199 :             WRITE (file_name, '(A,I0.3,A)') TRIM(base_name)//".", nnp_env%nuc_ele(i), ".data"
     711          199 :             IF (logger%para_env%is_source()) THEN
     712          101 :                WRITE (unit_nr, *) TRIM(printtag)//"| Reading weights from file: ", TRIM(file_name)
     713              :             END IF
     714          199 :             CALL parser_create(parser, file_name, para_env=logger%para_env)
     715          199 :             n_weight = 0
     716       205629 :             DO WHILE (.TRUE.)
     717       205828 :                CALL parser_read_line(parser, 1, at_end)
     718       205828 :                IF (at_end) EXIT
     719       205629 :                n_weight = n_weight + 1
     720              :             END DO
     721              : 
     722          597 :             ALLOCATE (weights(n_weight))
     723              : 
     724          199 :             CALL parser_reset(parser)
     725       205828 :             DO j = 1, n_weight
     726       205629 :                CALL parser_read_line(parser, 1)
     727       205828 :                READ (parser%input_line, *) weights(j)
     728              :             END DO
     729          199 :             CALL parser_release(parser)
     730              : 
     731              :             ! sort weights into corresponding arrays
     732          199 :             iweight = 0
     733          796 :             DO j = 2, nnp_env%n_layer
     734        14231 :                DO k = 1, nnp_env%arc(i)%n_nodes(j - 1)
     735       211671 :                   DO l = 1, nnp_env%arc(i)%n_nodes(j)
     736       197440 :                      iweight = iweight + 1
     737       211074 :                      nnp_env%arc(i)%layer(j)%weights(k, l, i_com) = weights(iweight)
     738              :                   END DO
     739              :                END DO
     740              : 
     741         8985 :                DO k = 1, nnp_env%arc(i)%n_nodes(j)
     742         8189 :                   iweight = iweight + 1
     743         8786 :                   nnp_env%arc(i)%layer(j)%bweights(k, i_com) = weights(iweight)
     744              :                END DO
     745              :             END DO
     746              : 
     747          497 :             DEALLOCATE (weights)
     748              :          END DO
     749              :       END DO
     750              : 
     751              :       !Initialize extrapolation counter
     752           15 :       nnp_env%expol = 0
     753              : 
     754              :       ! Bias the standard deviation of committee disagreement
     755           15 :       NULLIFY (bias_section)
     756           15 :       explicit = .FALSE.
     757              :       !HELIUM NNP does atm not allow for bias (not even defined)
     758           15 :       bias_section => section_vals_get_subs_vals(nnp_env%nnp_input, "BIAS", can_return_null=.TRUE.)
     759           15 :       IF (ASSOCIATED(bias_section)) CALL section_vals_get(bias_section, explicit=explicit)
     760           15 :       nnp_env%bias = .FALSE.
     761           15 :       IF (explicit) THEN
     762            4 :          IF (nnp_env%n_committee > 1) THEN
     763            4 :             IF (logger%para_env%is_source()) THEN
     764            2 :                WRITE (unit_nr, *) "NNP| Biasing of committee disagreement enabled"
     765              :             END IF
     766            4 :             nnp_env%bias = .TRUE.
     767           12 :             ALLOCATE (nnp_env%bias_forces(3, nnp_env%num_atoms))
     768           12 :             ALLOCATE (nnp_env%bias_e_avrg(nnp_env%n_committee))
     769            4 :             CALL section_vals_val_get(bias_section, "SIGMA_0", r_val=nnp_env%bias_sigma0)
     770            4 :             CALL section_vals_val_get(bias_section, "K_B", r_val=nnp_env%bias_kb)
     771           36 :             nnp_env%bias_e_avrg(:) = 0.0_dp
     772            4 :             CALL section_vals_val_get(bias_section, "ALIGN_NNP_ENERGIES", explicit=explicit)
     773            4 :             nnp_env%bias_align = explicit
     774            4 :             IF (explicit) THEN
     775            4 :                NULLIFY (work)
     776            4 :                CALL section_vals_val_get(bias_section, "ALIGN_NNP_ENERGIES", r_vals=work)
     777            4 :                IF (SIZE(work) /= nnp_env%n_committee) THEN
     778            0 :                   CPABORT("ALIGN_NNP_ENERGIES size mismatch wrt committee size.")
     779              :                END IF
     780           68 :                nnp_env%bias_e_avrg(:) = work
     781            4 :                IF (logger%para_env%is_source()) THEN
     782            2 :                   WRITE (unit_nr, *) TRIM(printtag)//"| Biasing is aligned by shifting the energy prediction of the C-NNP members"
     783              :                END IF
     784              :             END IF
     785              :          ELSE
     786            0 :             CPWARN("NNP committee size is 1, BIAS section is ignored.")
     787              :          END IF
     788              :       END IF
     789              : 
     790           15 :       IF (logger%para_env%is_source()) THEN
     791            8 :          WRITE (unit_nr, *) TRIM(printtag)//"| NNP force environment initialized"
     792              :       END IF
     793              : 
     794           15 :       CALL timestop(handle)
     795              : 
     796           75 :    END SUBROUTINE nnp_init_model
     797              : 
     798              : END MODULE nnp_environment
        

Generated by: LCOV version 2.0-1