LCOV - code coverage report
Current view: top level - src - stm_images.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 144 149 96.6 %
Date: 2024-12-21 06:28:57 Functions: 2 2 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Calculation of STM image as post processing of an electronic
      10             : !>     structure calculation,
      11             : !> \par History
      12             : !>      Started as a copy from the code in qs_scf_post
      13             : !> \author Joost VandeVondele 7.2008, MI 02.2009
      14             : ! **************************************************************************************************
      15             : MODULE stm_images
      16             :    USE cp_array_utils,                  ONLY: cp_1d_r_p_type
      17             :    USE cp_dbcsr_api,                    ONLY: dbcsr_copy,&
      18             :                                               dbcsr_deallocate_matrix,&
      19             :                                               dbcsr_p_type,&
      20             :                                               dbcsr_set,&
      21             :                                               dbcsr_type
      22             :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_plus_fm_fm_t
      23             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_column_scale
      24             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      25             :                                               cp_fm_struct_release,&
      26             :                                               cp_fm_struct_type
      27             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      28             :                                               cp_fm_release,&
      29             :                                               cp_fm_to_fm,&
      30             :                                               cp_fm_type
      31             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      32             :                                               cp_logger_get_default_io_unit,&
      33             :                                               cp_logger_type
      34             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      35             :                                               cp_print_key_unit_nr
      36             :    USE cp_realspace_grid_cube,          ONLY: cp_pw_to_cube
      37             :    USE input_section_types,             ONLY: section_get_ivals,&
      38             :                                               section_vals_type,&
      39             :                                               section_vals_val_get
      40             :    USE kinds,                           ONLY: default_path_length,&
      41             :                                               default_string_length,&
      42             :                                               dp
      43             :    USE particle_list_types,             ONLY: particle_list_type
      44             :    USE pw_env_types,                    ONLY: pw_env_get,&
      45             :                                               pw_env_type
      46             :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
      47             :                                               pw_pool_type
      48             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      49             :                                               pw_r3d_rs_type
      50             :    USE qs_collocate_density,            ONLY: calculate_rho_elec
      51             :    USE qs_environment_types,            ONLY: get_qs_env,&
      52             :                                               qs_environment_type
      53             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      54             :    USE qs_mo_types,                     ONLY: get_mo_set,&
      55             :                                               mo_set_type
      56             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      57             :                                               qs_rho_type
      58             : #include "./base/base_uses.f90"
      59             : 
      60             :    IMPLICIT NONE
      61             :    PRIVATE
      62             : 
      63             :    ! Global parameters
      64             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'stm_images'
      65             :    PUBLIC :: th_stm_image
      66             : 
      67             : CONTAINS
      68             : ! **************************************************************************************************
      69             : !> \brief Driver for the calculation of STM image, as post processing of a
      70             : !>        ground-state electronic structure calculation.
      71             : !> \param qs_env ...
      72             : !> \param stm_section ...
      73             : !> \param particles ...
      74             : !> \param unoccupied_orbs ...
      75             : !> \param unoccupied_evals ...
      76             : !> \param
      77             : !> \par History
      78             : !>      02.2009 Created [MI]
      79             : !> \author MI
      80             : !> \note
      81             : !>   The Tersoff-Hamman
      82             : !>        approximation is applied, occupied and a sufficient number of
      83             : !>        unoccupied eigenstates are needed (depending on the given Bias potential)
      84             : !>        and should be computed in advance. Unoccupied states are calculated
      85             : !>        before enetering this module when NLUMO =/ 0
      86             : ! **************************************************************************************************
      87             : 
      88           8 :    SUBROUTINE th_stm_image(qs_env, stm_section, particles, unoccupied_orbs, &
      89             :                            unoccupied_evals)
      90             : 
      91             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      92             :       TYPE(section_vals_type), POINTER                   :: stm_section
      93             :       TYPE(particle_list_type), POINTER                  :: particles
      94             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN), &
      95             :          POINTER                                         :: unoccupied_orbs
      96             :       TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER        :: unoccupied_evals
      97             : 
      98             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'th_stm_image'
      99             : 
     100             :       INTEGER                                            :: handle, irep, ispin, n_rep, ndim, nmo, &
     101             :                                                             nspin, output_unit
     102           8 :       INTEGER, DIMENSION(:), POINTER                     :: nadd_unocc, stm_th_torb
     103             :       LOGICAL                                            :: append_cube, use_ref_energy
     104             :       REAL(KIND=dp)                                      :: efermi, ref_energy
     105           8 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: mo_eigenvalues, mo_occ, stm_biases
     106           8 :       TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:)    :: evals, occupation
     107             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_tmp
     108           8 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: mo_arrays
     109             :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
     110             :       TYPE(cp_logger_type), POINTER                      :: logger
     111           8 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: rho_ao
     112             :       TYPE(dbcsr_type), POINTER                          :: stm_density_ao
     113           8 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     114             :       TYPE(pw_c1d_gs_type)                               :: wf_g
     115             :       TYPE(pw_env_type), POINTER                         :: pw_env
     116           8 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     117             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     118             :       TYPE(pw_r3d_rs_type)                               :: wf_r
     119             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     120             :       TYPE(qs_rho_type), POINTER                         :: rho
     121             : 
     122           8 :       CALL timeset(routineN, handle)
     123           8 :       logger => cp_get_default_logger()
     124           8 :       output_unit = cp_logger_get_default_io_unit(logger)
     125             : 
     126           8 :       NULLIFY (ks_env, mos, rho, rho_ao, pw_env, stm_th_torb, fm_struct_tmp)
     127           8 :       NULLIFY (auxbas_pw_pool, pw_pools, stm_density_ao, mo_coeff)
     128             : 
     129             :       CALL get_qs_env(qs_env, &
     130             :                       ks_env=ks_env, &
     131             :                       mos=mos, &
     132             :                       rho=rho, &
     133           8 :                       pw_env=pw_env)
     134             : 
     135           8 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     136             : 
     137           8 :       CALL section_vals_val_get(stm_section, "APPEND", l_val=append_cube)
     138           8 :       CALL section_vals_val_get(stm_section, "BIAS", r_vals=stm_biases)
     139           8 :       CALL section_vals_val_get(stm_section, "REF_ENERGY", r_val=ref_energy, explicit=use_ref_energy)
     140           8 :       CALL section_vals_val_get(stm_section, "TH_TORB", n_rep_val=n_rep)
     141           8 :       IF (n_rep == 0) THEN
     142           0 :          ALLOCATE (stm_th_torb(1))
     143           0 :          stm_th_torb(1) = 0
     144             :       ELSE
     145          24 :          ALLOCATE (stm_th_torb(n_rep))
     146          20 :          DO irep = 1, n_rep
     147             :             CALL section_vals_val_get(stm_section, "TH_TORB", &
     148          20 :                                       i_rep_val=irep, i_val=stm_th_torb(irep))
     149             :          END DO
     150             :       END IF
     151             : 
     152           8 :       ALLOCATE (stm_density_ao)
     153             :       CALL dbcsr_copy(stm_density_ao, rho_ao(1)%matrix, &
     154           8 :                       name="stm_density_ao")
     155             : 
     156             :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
     157           8 :                       pw_pools=pw_pools)
     158           8 :       CALL auxbas_pw_pool%create_pw(wf_r)
     159           8 :       CALL auxbas_pw_pool%create_pw(wf_g)
     160             : 
     161           8 :       nspin = SIZE(mos, 1)
     162          24 :       ALLOCATE (nadd_unocc(nspin))
     163          18 :       nadd_unocc = 0
     164           8 :       IF (ASSOCIATED(unoccupied_orbs)) THEN
     165           8 :          DO ispin = 1, nspin
     166           8 :             nadd_unocc(ispin) = SIZE(unoccupied_evals(ispin)%array)
     167             :          END DO
     168             :       END IF
     169             : 
     170          34 :       ALLOCATE (mo_arrays(nspin))
     171          34 :       ALLOCATE (evals(nspin))
     172          26 :       ALLOCATE (occupation(nspin))
     173          18 :       DO ispin = 1, nspin
     174          18 :          IF (nadd_unocc(ispin) == 0) THEN
     175             :             CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
     176           6 :                             eigenvalues=mo_eigenvalues, nmo=nmo, mu=efermi, occupation_numbers=mo_occ)
     177           6 :             mo_arrays(ispin) = mo_coeff
     178           6 :             evals(ispin)%array => mo_eigenvalues
     179           6 :             occupation(ispin)%array => mo_occ
     180             :          ELSE
     181             :             CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
     182           4 :                             eigenvalues=mo_eigenvalues, nmo=nmo, mu=efermi, occupation_numbers=mo_occ)
     183           4 :             ndim = nmo + nadd_unocc(ispin)
     184          12 :             ALLOCATE (evals(ispin)%array(ndim))
     185          36 :             evals(ispin)%array(1:nmo) = mo_eigenvalues(1:nmo)
     186          84 :             evals(ispin)%array(1 + nmo:ndim) = unoccupied_evals(ispin)%array(1:nadd_unocc(ispin))
     187           8 :             ALLOCATE (occupation(ispin)%array(ndim))
     188          36 :             occupation(ispin)%array(1:nmo) = mo_occ(1:nmo)
     189          84 :             occupation(ispin)%array(1 + nmo:ndim) = 0.0_dp
     190             :             CALL cp_fm_struct_create(fm_struct_tmp, ncol_global=ndim, &
     191           4 :                                      template_fmstruct=mo_coeff%matrix_struct)
     192           4 :             CALL cp_fm_create(mo_arrays(ispin), fm_struct_tmp, name="mo_arrays")
     193           4 :             CALL cp_fm_struct_release(fm_struct_tmp)
     194           4 :             CALL cp_fm_to_fm(mo_coeff, mo_arrays(ispin), nmo, 1, 1)
     195             :             CALL cp_fm_to_fm(unoccupied_orbs(ispin), mo_arrays(ispin), &
     196           8 :                              nadd_unocc(ispin), 1, nmo + 1)
     197             :          END IF
     198             :       END DO
     199           8 :       IF (use_ref_energy) efermi = ref_energy
     200             : 
     201             :       CALL stm_cubes(ks_env, stm_section, stm_density_ao, wf_r, wf_g, mo_arrays, evals, &
     202             :                      occupation, efermi, stm_biases, stm_th_torb, particles, &
     203           8 :                      output_unit, append_cube)
     204          18 :       DO ispin = 1, nspin
     205          18 :          IF (nadd_unocc(ispin) > 0) THEN
     206           4 :             DEALLOCATE (evals(ispin)%array)
     207           4 :             DEALLOCATE (occupation(ispin)%array)
     208           4 :             CALL cp_fm_release(mo_arrays(ispin))
     209             :          END IF
     210             :       END DO
     211           8 :       DEALLOCATE (mo_arrays)
     212           8 :       DEALLOCATE (evals)
     213           8 :       DEALLOCATE (occupation)
     214             : 
     215           8 :       CALL dbcsr_deallocate_matrix(stm_density_ao)
     216           8 :       CALL auxbas_pw_pool%give_back_pw(wf_r)
     217           8 :       CALL auxbas_pw_pool%give_back_pw(wf_g)
     218             : 
     219           8 :       DEALLOCATE (stm_th_torb)
     220           8 :       DEALLOCATE (nadd_unocc)
     221             : 
     222           8 :       CALL timestop(handle)
     223             : 
     224          24 :    END SUBROUTINE th_stm_image
     225             : 
     226             : ! **************************************************************************************************
     227             : !> \brief computes a simple approximation to the tunneling current for STM
     228             : !> \param ks_env ...
     229             : !> \param stm_section ...
     230             : !> \param stm_density_ao ...
     231             : !> \param wf_r ...
     232             : !> \param wf_g ...
     233             : !> \param mo_arrays ...
     234             : !> \param evals ...
     235             : !> \param occupation ...
     236             : !> \param efermi ...
     237             : !> \param stm_biases ...
     238             : !> \param stm_th_torb ...
     239             : !> \param particles ...
     240             : !> \param output_unit ...
     241             : !> \param append_cube ...
     242             : !> \param
     243             : !> \par History
     244             : !>      7.2008 Created [Joost VandeVondele]
     245             : !>       07.2009 modified MI
     246             : !> \author Joost VandeVondele
     247             : !> \note
     248             : !>      requires the MOs that are passed to be eigenstates, and energy ordered
     249             : ! **************************************************************************************************
     250           8 :    SUBROUTINE stm_cubes(ks_env, stm_section, stm_density_ao, wf_r, wf_g, mo_arrays, evals, &
     251           8 :                         occupation, efermi, stm_biases, stm_th_torb, particles, &
     252             :                         output_unit, append_cube)
     253             : 
     254             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     255             :       TYPE(section_vals_type), POINTER                   :: stm_section
     256             :       TYPE(dbcsr_type), POINTER                          :: stm_density_ao
     257             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                :: wf_r
     258             :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                :: wf_g
     259             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mo_arrays
     260             :       TYPE(cp_1d_r_p_type), DIMENSION(:), INTENT(IN)     :: evals, occupation
     261             :       REAL(KIND=dp)                                      :: efermi
     262             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: stm_biases
     263             :       INTEGER, DIMENSION(:), POINTER                     :: stm_th_torb
     264             :       TYPE(particle_list_type), POINTER                  :: particles
     265             :       INTEGER, INTENT(IN)                                :: output_unit
     266             :       LOGICAL, INTENT(IN)                                :: append_cube
     267             : 
     268             :       CHARACTER(LEN=*), DIMENSION(0:9), PARAMETER :: &
     269             :          torb_string = (/"  s", " px", " py", " pz", "dxy", "dyz", "dzx", "dx2", "dy2", "dz2"/)
     270             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'stm_cubes'
     271             : 
     272             :       CHARACTER(LEN=default_path_length)                 :: filename
     273             :       CHARACTER(LEN=default_string_length)               :: my_pos, oname, title
     274             :       INTEGER                                            :: handle, i, ibias, imo, iorb, ispin, &
     275             :                                                             istates, nmo, nspin, nstates(2), &
     276             :                                                             state_start(2), unit_nr
     277             :       LOGICAL                                            :: mpi_io
     278             :       REAL(KIND=dp)                                      :: alpha
     279           8 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: occ_tot
     280             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_tmp
     281             :       TYPE(cp_fm_type)                                   :: matrix_v, matrix_vf
     282             :       TYPE(cp_logger_type), POINTER                      :: logger
     283             : 
     284           8 :       CALL timeset(routineN, handle)
     285             : 
     286           8 :       logger => cp_get_default_logger()
     287           8 :       NULLIFY (fm_struct_tmp)
     288             : 
     289           8 :       nspin = SIZE(mo_arrays)
     290             : 
     291           8 :       IF (output_unit > 0) WRITE (output_unit, '(T2,A)') ""
     292           8 :       IF (output_unit > 0) WRITE (output_unit, '(T2,A,F12.6, A)') "STM : Reference energy ", efermi, " a.u. "
     293          48 :       DO ibias = 1, SIZE(stm_biases)
     294             : 
     295          40 :          IF (output_unit > 0) WRITE (output_unit, '(T2,A)') ""
     296          40 :          IF (output_unit > 0) WRITE (output_unit, '(T2,A,F16.6)') &
     297          20 :             "Preparing for STM image at bias [a.u.] ", stm_biases(ibias)
     298             : 
     299          40 :          istates = 0
     300          40 :          nstates = 0
     301          40 :          state_start = 0
     302          92 :          DO ispin = 1, nspin
     303          52 :             IF (stm_biases(ibias) < 0.0_dp) THEN
     304          44 :                nmo = SIZE(evals(ispin)%array)
     305        1564 :                DO imo = 1, nmo
     306        1520 :                   IF (evals(ispin)%array(imo) > (efermi + stm_biases(ibias)) .AND. &
     307          44 :                       evals(ispin)%array(imo) <= efermi) THEN
     308          68 :                      IF (nstates(ispin) == 0) state_start(ispin) = imo
     309          68 :                      nstates(ispin) = nstates(ispin) + 1
     310             :                   END IF
     311             :                END DO
     312          44 :                IF ((output_unit > 0) .AND. evals(ispin)%array(1) > efermi + stm_biases(ibias)) &
     313           0 :                   WRITE (output_unit, '(T4,A)') "Warning: EFermi+bias below lowest computed occupied MO"
     314             :             ELSE
     315           8 :                nmo = SIZE(evals(ispin)%array)
     316         232 :                DO imo = 1, nmo
     317         224 :                   IF (evals(ispin)%array(imo) <= (efermi + stm_biases(ibias)) .AND. &
     318           8 :                       evals(ispin)%array(imo) > efermi) THEN
     319          10 :                      IF (nstates(ispin) == 0) state_start(ispin) = imo
     320          10 :                      nstates(ispin) = nstates(ispin) + 1
     321             :                   END IF
     322             :                END DO
     323           8 :                IF ((output_unit > 0) .AND. evals(ispin)%array(nmo) < efermi + stm_biases(ibias)) &
     324           0 :                   WRITE (output_unit, '(T4,A)') "Warning: E-Fermi+bias above highest computed unoccupied MO"
     325             :             END IF
     326          92 :             istates = istates + nstates(ispin)
     327             :          END DO
     328          40 :          IF ((output_unit > 0)) WRITE (output_unit, '(T4,A,I0,A)') "Using a total of ", istates, " states"
     329          40 :          IF (istates == 0) CYCLE
     330             : 
     331             :          CALL cp_fm_struct_create(fm_struct_tmp, ncol_global=istates, &
     332          36 :                                   template_fmstruct=mo_arrays(1)%matrix_struct)
     333          36 :          CALL cp_fm_create(matrix_v, fm_struct_tmp, name="matrix_v")
     334          36 :          CALL cp_fm_create(matrix_vf, fm_struct_tmp, name="matrix_vf")
     335          36 :          CALL cp_fm_struct_release(fm_struct_tmp)
     336             : 
     337         108 :          ALLOCATE (occ_tot(istates))
     338             : 
     339             :          ! we sum both alpha and beta electrons together for this density of states
     340          36 :          istates = 0
     341          36 :          alpha = 1.0_dp
     342          36 :          IF (nspin == 1) alpha = 2.0_dp
     343          84 :          DO ispin = 1, nspin
     344          48 :             CALL cp_fm_to_fm(mo_arrays(ispin), matrix_v, nstates(ispin), state_start(ispin), istates + 1)
     345          48 :             CALL cp_fm_to_fm(mo_arrays(ispin), matrix_vf, nstates(ispin), state_start(ispin), istates + 1)
     346          48 :             IF (stm_biases(ibias) < 0.0_dp) THEN
     347             :                occ_tot(istates + 1:istates + nstates(ispin)) = &
     348         112 :                   occupation(ispin)%array(state_start(ispin):state_start(ispin) - 1 + nstates(ispin))
     349             :             ELSE
     350             :                occ_tot(istates + 1:istates + nstates(ispin)) = &
     351          14 :                   alpha - occupation(ispin)%array(state_start(ispin):state_start(ispin) - 1 + nstates(ispin))
     352             :             END IF
     353          84 :             istates = istates + nstates(ispin)
     354             :          END DO
     355             : 
     356          36 :          CALL cp_fm_column_scale(matrix_vf, occ_tot(1:istates))
     357          36 :          alpha = 1.0_dp
     358             : 
     359          36 :          CALL dbcsr_set(stm_density_ao, 0.0_dp)
     360             :          CALL cp_dbcsr_plus_fm_fm_t(stm_density_ao, matrix_v=matrix_v, matrix_g=matrix_vf, ncol=istates, &
     361          36 :                                     alpha=alpha)
     362             : 
     363          84 :          DO i = 1, SIZE(stm_th_torb)
     364          48 :             iorb = stm_th_torb(i)
     365             :             CALL calculate_rho_elec(matrix_p=stm_density_ao, &
     366             :                                     rho=wf_r, rho_gspace=wf_g, &
     367          48 :                                     ks_env=ks_env, der_type=iorb)
     368             : 
     369          48 :             oname = torb_string(iorb)
     370             : !         fname = "STM_"//TRIM(torb_string(iorb))
     371          48 :             WRITE (filename, '(a4,I2.2,a1,I5.5)') "STM_d", iorb, "_", ibias
     372          48 :             my_pos = "REWIND"
     373          48 :             IF (append_cube) THEN
     374           0 :                my_pos = "APPEND"
     375             :             END IF
     376             : 
     377          48 :             mpi_io = .TRUE.
     378             :             unit_nr = cp_print_key_unit_nr(logger, stm_section, extension=".cube", &
     379             :                                            middle_name=TRIM(filename), file_position=my_pos, file_action="WRITE", &
     380          48 :                                            log_filename=.FALSE., mpi_io=mpi_io)
     381          48 :             WRITE (title, '(A,I0,A,I0,A,F16.8)') "STM cube ", ibias, " wfn deriv. ", iorb, " at bias ", stm_biases(ibias)
     382             :             CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
     383             :                                stride=section_get_ivals(stm_section, "STRIDE"), zero_tails=.TRUE., &
     384          48 :                                mpi_io=mpi_io)
     385             : 
     386          84 :             CALL cp_print_key_finished_output(unit_nr, logger, stm_section, mpi_io=mpi_io)
     387             :          END DO
     388             : 
     389          36 :          CALL cp_fm_release(matrix_v)
     390          36 :          CALL cp_fm_release(matrix_vf)
     391          84 :          DEALLOCATE (occ_tot)
     392             : 
     393             :       END DO
     394             : 
     395           8 :       CALL timestop(handle)
     396             : 
     397          16 :    END SUBROUTINE stm_cubes
     398             : 
     399             : END MODULE stm_images

Generated by: LCOV version 1.15