(git:b279b6b)
qs_fb_env_methods.F
Go to the documentation of this file.
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 
9 
10  USE atomic_kind_types, ONLY: atomic_kind_type,&
13  gto_basis_set_p_type,&
14  gto_basis_set_type
15  USE cell_types, ONLY: cell_type
16  USE cp_blacs_env, ONLY: cp_blacs_env_type
17  USE cp_control_types, ONLY: dft_control_type
21  USE cp_fm_basic_linalg, ONLY: cp_fm_gemm,&
22  cp_fm_symm,&
29  USE cp_fm_diag, ONLY: choose_eigv_solver,&
33  cp_fm_struct_type
34  USE cp_fm_types, ONLY: cp_fm_create,&
35  cp_fm_release,&
37  cp_fm_to_fm,&
38  cp_fm_type
40  cp_logger_type
43  USE cp_units, ONLY: cp_unit_from_cp2k
44  USE dbcsr_api, ONLY: &
45  dbcsr_create, dbcsr_finalize, dbcsr_get_info, dbcsr_iterator_blocks_left, &
46  dbcsr_iterator_next_block, dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, &
47  dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_reserve_blocks, dbcsr_set, dbcsr_type, &
48  dbcsr_type_no_symmetry
49  USE input_constants, ONLY: cholesky_dbcsr,&
51  cholesky_off,&
55  section_vals_type,&
57  USE kinds, ONLY: default_string_length,&
58  dp
59  USE message_passing, ONLY: mp_para_env_type
60  USE orbital_pointers, ONLY: nco,&
61  ncoset
62  USE parallel_gemm_api, ONLY: parallel_gemm
63  USE particle_types, ONLY: particle_type
64  USE qs_density_matrices, ONLY: calculate_density_matrix
65  USE qs_diis, ONLY: qs_diis_b_step
66  USE qs_environment_types, ONLY: get_qs_env,&
67  qs_environment_type
68  USE qs_fb_atomic_halo_types, ONLY: &
70  fb_atomic_halo_list_create, fb_atomic_halo_list_nullify, fb_atomic_halo_list_obj, &
74  USE qs_fb_env_types, ONLY: fb_env_get,&
76  fb_env_obj,&
82  fb_trial_fns_obj,&
86  USE qs_kind_types, ONLY: get_qs_kind,&
87  qs_kind_type
88  USE qs_mo_occupation, ONLY: set_mo_occupation
89  USE qs_mo_types, ONLY: allocate_mo_set,&
91  get_mo_set,&
92  init_mo_set,&
93  mo_set_type,&
95  USE qs_scf_types, ONLY: qs_scf_env_type
96  USE scf_control_types, ONLY: scf_control_type
97  USE string_utilities, ONLY: compress,&
98  uppercase
99 #include "./base/base_uses.f90"
100 
101  IMPLICIT NONE
102 
103  PRIVATE
104 
105  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fb_env_methods'
106 
107  PUBLIC :: fb_env_do_diag, &
112 
113 CONTAINS
114 
115 ! **************************************************************************************************
116 !> \brief Do filtered matrix method diagonalisation
117 !> \param fb_env : the filter matrix environment
118 !> \param qs_env : quickstep environment
119 !> \param matrix_ks : DBCSR system (unfiltered) input KS matrix
120 !> \param matrix_s : DBCSR system (unfiltered) input overlap matrix
121 !> \param scf_section : SCF input section
122 !> \param diis_step : whether we are doing a DIIS step
123 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
124 ! **************************************************************************************************
125  SUBROUTINE fb_env_do_diag(fb_env, &
126  qs_env, &
127  matrix_ks, &
128  matrix_s, &
129  scf_section, &
130  diis_step)
131  TYPE(fb_env_obj), INTENT(INOUT) :: fb_env
132  TYPE(qs_environment_type), POINTER :: qs_env
133  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
134  TYPE(section_vals_type), POINTER :: scf_section
135  LOGICAL, INTENT(INOUT) :: diis_step
136 
137  CHARACTER(LEN=*), PARAMETER :: routinen = 'fb_env_do_diag'
138 
139  CHARACTER(len=2) :: spin_string
140  CHARACTER(len=default_string_length) :: name
141  INTEGER :: filtered_nfullrowsorcols_total, handle, homo_filtered, ispin, lfomo_filtered, &
142  my_nmo, nao, ndep, nelectron, nmo, nmo_filtered, nspin, original_nfullrowsorcols_total
143  INTEGER, DIMENSION(:), POINTER :: filtered_roworcol_block_sizes, &
144  original_roworcol_block_sizes
145  LOGICAL :: collective_com
146  REAL(kind=dp) :: diis_error, eps_default, eps_diis, eps_eigval, fermi_level, filter_temp, &
147  flexible_electron_count, kts_filtered, maxocc, mu_filtered
148  REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues, eigenvalues_filtered, occ, &
149  occ_filtered
150  TYPE(cp_blacs_env_type), POINTER :: blacs_env
151  TYPE(cp_fm_struct_type), POINTER :: filter_fm_struct, fm_struct
152  TYPE(cp_fm_type) :: fm_matrix_filter, fm_matrix_filtered_ks, &
153  fm_matrix_filtered_s, fm_matrix_ortho, &
154  fm_matrix_work
155  TYPE(cp_fm_type), POINTER :: mo_coeff, mo_coeff_filtered
156  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_filter
157  TYPE(dbcsr_type) :: matrix_filtered_ks, matrix_filtered_s, &
158  matrix_tmp
159  TYPE(dbcsr_type), POINTER :: matrix_filtered_p
160  TYPE(fb_atomic_halo_list_obj) :: atomic_halos
161  TYPE(fb_trial_fns_obj) :: trial_fns
162  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos, mos_filtered
163  TYPE(mp_para_env_type), POINTER :: para_env
164  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
165  TYPE(qs_scf_env_type), POINTER :: scf_env
166  TYPE(scf_control_type), POINTER :: scf_control
167 
168 ! TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_orb
169 
170  CALL timeset(routinen, handle)
171 
172  NULLIFY (scf_env, scf_control, para_env, blacs_env, particle_set)
173  NULLIFY (eigenvalues, eigenvalues_filtered, occ, occ_filtered)
174  NULLIFY (mos, mos_filtered)
175  NULLIFY (matrix_filter, matrix_filtered_p)
176  NULLIFY (fm_struct, filter_fm_struct)
177  NULLIFY (mo_coeff_filtered, mo_coeff)
178  ! NULLIFY(sab_orb)
179  CALL fb_atomic_halo_list_nullify(atomic_halos)
180  CALL fb_trial_fns_nullify(trial_fns)
181  NULLIFY (original_roworcol_block_sizes, filtered_roworcol_block_sizes)
182 
183  ! get qs_env information
184  CALL get_qs_env(qs_env=qs_env, &
185  scf_env=scf_env, &
186  scf_control=scf_control, &
187  para_env=para_env, &
188  blacs_env=blacs_env, &
189  particle_set=particle_set, &
190  mos=mos)
191 
192  nspin = SIZE(matrix_ks)
193 
194  ! ----------------------------------------------------------------------
195  ! DIIS step - based on non-filtered matrices and MOs
196  ! ----------------------------------------------------------------------
197 
198  DO ispin = 1, nspin
199  CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
200  scf_env%scf_work1(ispin))
201  END DO
202 
203  eps_diis = scf_control%eps_diis
204  eps_eigval = epsilon(0.0_dp)
205 
206  IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
207  CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
208  scf_env%scf_work2, scf_env%iter_delta, &
209  diis_error, diis_step, eps_diis, scf_control%nmixing, &
210  s_matrix=matrix_s, scf_section=scf_section)
211  ELSE
212  diis_step = .false.
213  END IF
214 
215  IF (diis_step) THEN
216  scf_env%iter_param = diis_error
217  scf_env%iter_method = "DIIS/Filter"
218  ELSE
219  IF (scf_env%mixing_method == 0) THEN
220  scf_env%iter_method = "NoMix/Filter"
221  ELSE IF (scf_env%mixing_method == 1) THEN
222  scf_env%iter_param = scf_env%p_mix_alpha
223  scf_env%iter_method = "P_Mix/Filter"
224  ELSE IF (scf_env%mixing_method > 1) THEN
225  scf_env%iter_param = scf_env%mixing_store%alpha
226  scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Filter"
227  END IF
228  END IF
229 
230  ! ----------------------------------------------------------------------
231  ! Construct Filter Matrix
232  ! ----------------------------------------------------------------------
233 
234  CALL fb_env_get(fb_env=fb_env, &
235  filter_temperature=filter_temp, &
236  atomic_halos=atomic_halos, &
237  eps_default=eps_default)
238 
239  ! construct trial functions
240  CALL get_mo_set(mo_set=mos(1), maxocc=maxocc)
241  CALL fb_env_build_trial_fns_auto(fb_env, qs_env, maxocc)
242  CALL fb_env_get(fb_env=fb_env, &
243  trial_fns=trial_fns)
244 
245  ! allocate filter matrix (matrix_filter(ispin)%matrix are
246  ! nullified by dbcsr_allocate_matrix_set)
247  CALL dbcsr_allocate_matrix_set(matrix_filter, nspin)
248  DO ispin = 1, nspin
249  ! get system-wide fermi energy and occupancy, we use this to
250  ! define the filter function used for the filter matrix
251  CALL get_mo_set(mo_set=mos(ispin), &
252  mu=fermi_level, &
253  maxocc=maxocc)
254  ! get filter matrix name
255  WRITE (spin_string, fmt="(I1)") ispin
256  name = trim("FILTER MATRIX SPIN "//spin_string)
257  CALL compress(name)
258  CALL uppercase(name)
259  ! calculate filter matrix (matrix_s(1) is the overlap, the rest
260  ! in the array are its derivatives)
261  CALL fb_env_get(fb_env=fb_env, &
262  collective_com=collective_com)
263  IF (collective_com) THEN
264  CALL fb_fltrmat_build_2(h_mat=matrix_ks(ispin)%matrix, &
265  s_mat=matrix_s(1)%matrix, &
266  atomic_halos=atomic_halos, &
267  trial_fns=trial_fns, &
268  para_env=para_env, &
269  particle_set=particle_set, &
270  fermi_level=fermi_level, &
271  filter_temp=filter_temp, &
272  name=name, &
273  filter_mat=matrix_filter(ispin)%matrix, &
274  tolerance=eps_default)
275  ELSE
276  CALL fb_fltrmat_build(h_mat=matrix_ks(ispin)%matrix, &
277  s_mat=matrix_s(1)%matrix, &
278  atomic_halos=atomic_halos, &
279  trial_fns=trial_fns, &
280  para_env=para_env, &
281  particle_set=particle_set, &
282  fermi_level=fermi_level, &
283  filter_temp=filter_temp, &
284  name=name, &
285  filter_mat=matrix_filter(ispin)%matrix, &
286  tolerance=eps_default)
287  END IF
288  END DO ! ispin
289 
290  ! ----------------------------------------------------------------------
291  ! Do Filtered Diagonalisation
292  ! ----------------------------------------------------------------------
293 
294  ! Obtain matrix dimensions. KS and S matrices are symmetric, so
295  ! row_block_sizes and col_block_sizes should be identical. The
296  ! same applies to the filtered block sizes. Note that filter
297  ! matrix will have row_block_sizes equal to that of the original,
298  ! and col_block_sizes equal to that of the filtered. We assume
299  ! also that the matrix dimensions are identical for both spin
300  ! channels.
301  CALL dbcsr_get_info(matrix_ks(1)%matrix, &
302  row_blk_size=original_roworcol_block_sizes, &
303  nfullrows_total=original_nfullrowsorcols_total)
304  CALL dbcsr_get_info(matrix_filter(1)%matrix, &
305  col_blk_size=filtered_roworcol_block_sizes, &
306  nfullcols_total=filtered_nfullrowsorcols_total)
307 
308  ! filter diagonalisation works on a smaller basis set, and thus
309  ! requires a new mo_set (molecular orbitals | eigenvectors) and
310  ! the corresponding matrix pools for the eigenvector coefficients
311  ALLOCATE (mos_filtered(nspin))
312  DO ispin = 1, nspin
313  CALL get_mo_set(mo_set=mos(ispin), &
314  maxocc=maxocc, &
315  nelectron=nelectron, &
316  flexible_electron_count=flexible_electron_count)
317  CALL allocate_mo_set(mo_set=mos_filtered(ispin), &
318  nao=filtered_nfullrowsorcols_total, &
319  nmo=filtered_nfullrowsorcols_total, &
320  nelectron=nelectron, &
321  n_el_f=real(nelectron, dp), &
322  maxocc=maxocc, &
323  flexible_electron_count=flexible_electron_count)
324  END DO ! ispin
325 
326  ! create DBCSR filtered KS matrix, this is reused for each spin
327  ! channel
328  ! both row_blk_size and col_blk_size should be that of
329  ! col_blk_size of the filter matrix
330  CALL dbcsr_create(matrix=matrix_filtered_ks, template=matrix_ks(1)%matrix, &
331  name=trim("FILTERED_KS_MATRIX"), &
332  matrix_type=dbcsr_type_no_symmetry, &
333  row_blk_size=filtered_roworcol_block_sizes, &
334  col_blk_size=filtered_roworcol_block_sizes, &
335  nze=0)
336  CALL dbcsr_finalize(matrix_filtered_ks)
337 
338  ! create DBCSR filtered S (overlap) matrix. Note that
339  ! matrix_s(1)%matrix is the original overlap matrix---the rest in
340  ! the array are derivatives, and it should not depend on
341  ! spin. HOWEVER, since the filter matrix is constructed from KS
342  ! matrix, and does depend on spin, the filtered S also becomes
343  ! spin dependent. Nevertheless this matrix is reused for each spin
344  ! channel
345  ! both row_blk_size and col_blk_size should be that of
346  ! col_blk_size of the filter matrix
347  CALL dbcsr_create(matrix=matrix_filtered_s, template=matrix_s(1)%matrix, &
348  name=trim("FILTERED_S_MATRIX"), &
349  matrix_type=dbcsr_type_no_symmetry, &
350  row_blk_size=filtered_roworcol_block_sizes, &
351  col_blk_size=filtered_roworcol_block_sizes, &
352  nze=0)
353  CALL dbcsr_finalize(matrix_filtered_s)
354 
355  ! create temporary matrix for constructing filtered KS and S
356  ! the temporary matrix won't be square
357  CALL dbcsr_create(matrix=matrix_tmp, template=matrix_s(1)%matrix, &
358  name=trim("TEMPORARY_MATRIX"), &
359  matrix_type=dbcsr_type_no_symmetry, &
360  row_blk_size=original_roworcol_block_sizes, &
361  col_blk_size=filtered_roworcol_block_sizes, &
362  nze=0)
363  CALL dbcsr_finalize(matrix_tmp)
364 
365  ! create fm format matrices used for diagonalisation
366  CALL cp_fm_struct_create(fmstruct=fm_struct, &
367  para_env=para_env, &
368  context=blacs_env, &
369  nrow_global=filtered_nfullrowsorcols_total, &
370  ncol_global=filtered_nfullrowsorcols_total)
371  ! both fm_matrix_filtered_s and fm_matrix_filtered_ks are reused
372  ! for each spin channel
373  CALL cp_fm_create(fm_matrix_filtered_s, &
374  fm_struct, &
375  name="FM_MATRIX_FILTERED_S")
376  CALL cp_fm_create(fm_matrix_filtered_ks, &
377  fm_struct, &
378  name="FM_MATRIX_FILTERED_KS")
379  ! creaate work matrix
380  CALL cp_fm_create(fm_matrix_work, fm_struct, name="FM_MATRIX_WORK")
381  CALL cp_fm_create(fm_matrix_ortho, fm_struct, name="FM_MATRIX_ORTHO")
382  ! all fm matrices are created, so can release fm_struct
383  CALL cp_fm_struct_release(fm_struct)
384 
385  ! construct filtered KS, S matrix and diagonalise
386  DO ispin = 1, nspin
387 
388  ! construct filtered KS matrix
389  CALL dbcsr_multiply("N", "N", 1.0_dp, &
390  matrix_ks(ispin)%matrix, matrix_filter(ispin)%matrix, &
391  0.0_dp, matrix_tmp)
392  CALL dbcsr_multiply("T", "N", 1.0_dp, &
393  matrix_filter(ispin)%matrix, matrix_tmp, &
394  0.0_dp, matrix_filtered_ks)
395  ! construct filtered S_matrix
396  CALL dbcsr_multiply("N", "N", 1.0_dp, &
397  matrix_s(1)%matrix, matrix_filter(ispin)%matrix, &
398  0.0_dp, matrix_tmp)
399  CALL dbcsr_multiply("T", "N", 1.0_dp, &
400  matrix_filter(ispin)%matrix, matrix_tmp, &
401  0.0_dp, matrix_filtered_s)
402 
403  ! now that we have the filtered KS and S matrices for this spin
404  ! channel, perform ordinary diagonalisation
405 
406  ! convert DBCSR matrices to fm format
407  CALL copy_dbcsr_to_fm(matrix_filtered_s, fm_matrix_filtered_s)
408  CALL copy_dbcsr_to_fm(matrix_filtered_ks, fm_matrix_filtered_ks)
409 
410  CALL get_mo_set(mos_filtered(ispin), nmo=nmo, nao=nao)
411 
412  CALL cp_fm_struct_create(fm_struct, nrow_global=nao, &
413  ncol_global=nmo, para_env=para_env, &
414  context=blacs_env)
415 
416  ! setup matrix pools for the molecular orbitals
417  CALL init_mo_set(mos_filtered(ispin), &
418  fm_struct=fm_struct, &
419  name="FILTERED_MOS")
420  CALL cp_fm_struct_release(fm_struct)
421 
422  ! now diagonalise
423  CALL fb_env_eigensolver(fm_matrix_filtered_ks, &
424  fm_matrix_filtered_s, &
425  mos_filtered(ispin), &
426  fm_matrix_ortho, &
427  fm_matrix_work, &
428  eps_eigval, &
429  ndep, &
430  scf_env%cholesky_method)
431  END DO ! ispin
432 
433  ! release temporary matrices
434  CALL dbcsr_release(matrix_filtered_s)
435  CALL dbcsr_release(matrix_filtered_ks)
436  CALL cp_fm_release(fm_matrix_filtered_s)
437  CALL cp_fm_release(fm_matrix_filtered_ks)
438  CALL cp_fm_release(fm_matrix_work)
439  CALL cp_fm_release(fm_matrix_ortho)
440 
441  ! ----------------------------------------------------------------------
442  ! Construct New Density Matrix
443  ! ----------------------------------------------------------------------
444 
445  ! calculate filtered molecular orbital occupation numbers and fermi
446  ! level etc
447  CALL set_mo_occupation(mo_array=mos_filtered, &
448  smear=scf_control%smear)
449 
450  ! get the filtered density matrix and then convert back to the
451  ! full basis version in scf_env ready to be used outside this
452  ! subroutine
453  ALLOCATE (matrix_filtered_p)
454  ! the filtered density matrix should have the same sparse
455  ! structure as the original density matrix, we must copy the
456  ! sparse structure here, since construction of the density matrix
457  ! preserves its sparse form, and therefore matrix_filtered_p must
458  ! have its blocks allocated here now. We assume the original
459  ! density matrix scf_env%p_mix_new has the same sparse structure
460  ! in both spin channels.
461  CALL dbcsr_create(matrix=matrix_filtered_p, template=scf_env%p_mix_new(1, 1)%matrix, &
462  name=trim("FILTERED_MATRIX_P"), &
463  row_blk_size=filtered_roworcol_block_sizes, &
464  col_blk_size=filtered_roworcol_block_sizes, &
465  nze=0)
466  CALL dbcsr_finalize(matrix_filtered_p)
467  CALL fb_dbcsr_copy_sparse_struct(matrix_filtered_p, &
468  scf_env%p_mix_new(1, 1)%matrix)
469  ! old implementation, using sab_orb to allocate the blocks in matrix_filtered_p
470  ! CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
471  ! CALL cp_dbcsr_alloc_block_from_nbl(matrix_filtered_p, sab_orb)
472  CALL dbcsr_set(matrix_filtered_p, 0.0_dp)
473 
474  DO ispin = 1, nspin
475  ! calculate matrix_filtered_p
476  CALL calculate_density_matrix(mos_filtered(ispin), &
477  matrix_filtered_p)
478  ! convert back to full basis p
479  CALL dbcsr_multiply("N", "N", 1.0_dp, &
480  matrix_filter(ispin)%matrix, matrix_filtered_p, &
481  0.0_dp, matrix_tmp)
482  CALL dbcsr_multiply("N", "T", 1.0_dp, &
483  matrix_tmp, matrix_filter(ispin)%matrix, &
484  0.0_dp, scf_env%p_mix_new(ispin, 1)%matrix, &
485  retain_sparsity=.true.)
486  ! note that we want to retain the sparse structure of
487  ! scf_env%p_mix_new
488  END DO ! ispin
489 
490  ! release temporary matrices
491  CALL dbcsr_release(matrix_tmp)
492  CALL dbcsr_release(matrix_filtered_p)
493  DEALLOCATE (matrix_filtered_p)
494 
495  ! ----------------------------------------------------------------------
496  ! Update MOs
497  ! ----------------------------------------------------------------------
498 
499  ! we still need to convert mos_filtered back to the full basis
500  ! version (mos) for this, we need to update mo_coeff (and/or
501  ! mo_coeff_b --- the DBCSR version, if used) of mos
502 
503  ! note also that mo_eigenvalues cannot be fully updated, given
504  ! that the eigenvalues are computed in a smaller basis, and thus
505  ! do not give the full spectron. Printing of molecular states
506  ! (molecular DOS) at each SCF step is therefore not recommended
507  ! when using this method. The idea is that if one wants a full
508  ! molecular DOS, then one should perform a full diagonalisation
509  ! without the filters once the SCF has been achieved.
510 
511  ! NOTE: from reading the source code, it appears that mo_coeff_b
512  ! is actually never used by default (DOUBLE CHECK?!). Even
513  ! subroutine eigensolver_dbcsr updates mo_coeff, and not
514  ! mo_coeff_b.
515 
516  ! create FM format filter matrix
517  CALL cp_fm_struct_create(fmstruct=filter_fm_struct, &
518  para_env=para_env, &
519  context=blacs_env, &
520  nrow_global=original_nfullrowsorcols_total, &
521  ncol_global=filtered_nfullrowsorcols_total)
522  CALL cp_fm_create(fm_matrix_filter, &
523  filter_fm_struct, &
524  name="FM_MATRIX_FILTER")
525  CALL cp_fm_struct_release(filter_fm_struct)
526 
527  DO ispin = 1, nspin
528  ! now the full basis mo_set should only contain the reduced
529  ! number of eigenvectors and eigenvalues
530  CALL get_mo_set(mo_set=mos_filtered(ispin), &
531  homo=homo_filtered, &
532  lfomo=lfomo_filtered, &
533  nmo=nmo_filtered, &
534  eigenvalues=eigenvalues_filtered, &
535  occupation_numbers=occ_filtered, &
536  mo_coeff=mo_coeff_filtered, &
537  kts=kts_filtered, &
538  mu=mu_filtered)
539  ! first set all the relevant scalars
540  CALL set_mo_set(mo_set=mos(ispin), &
541  homo=homo_filtered, &
542  lfomo=lfomo_filtered, &
543  kts=kts_filtered, &
544  mu=mu_filtered)
545  ! now set the arrays and fm_matrices
546  CALL get_mo_set(mo_set=mos(ispin), &
547  nmo=nmo, &
548  occupation_numbers=occ, &
549  eigenvalues=eigenvalues, &
550  mo_coeff=mo_coeff)
551  ! number of mos in original mo_set may sometimes be less than
552  ! nmo_filtered, so we must make sure we do not go out of bounds
553  my_nmo = min(nmo, nmo_filtered)
554  eigenvalues(:) = 0.0_dp
555  eigenvalues(1:my_nmo) = eigenvalues_filtered(1:my_nmo)
556  occ(:) = 0.0_dp
557  occ(1:my_nmo) = occ_filtered(1:my_nmo)
558  ! convert mo_coeff_filtered back to original basis
559  CALL cp_fm_set_all(matrix=mo_coeff, alpha=0.0_dp)
560  CALL copy_dbcsr_to_fm(matrix_filter(ispin)%matrix, fm_matrix_filter)
561  CALL cp_fm_gemm("N", "N", &
562  original_nfullrowsorcols_total, &
563  my_nmo, &
564  filtered_nfullrowsorcols_total, &
565  1.0_dp, fm_matrix_filter, mo_coeff_filtered, &
566  0.0_dp, mo_coeff)
567 
568  END DO ! ispin
569 
570  ! release temporary matrices
571  CALL cp_fm_release(fm_matrix_filter)
572 
573  ! ----------------------------------------------------------------------
574  ! Final Clean Up
575  ! ----------------------------------------------------------------------
576 
577  DO ispin = 1, nspin
578  CALL deallocate_mo_set(mo_set=mos_filtered(ispin))
579  END DO
580  DEALLOCATE (mos_filtered)
581  CALL dbcsr_deallocate_matrix_set(matrix_filter)
582 
583  CALL timestop(handle)
584 
585  END SUBROUTINE fb_env_do_diag
586 
587 ! **************************************************************************************************
588 !> \brief The main parallel eigensolver engine for filter matrix diagonalisation
589 !> \param fm_KS : the BLACS distributed Kohn-Sham matrix, input only
590 !> \param fm_S : the BLACS distributed overlap matrix, input only
591 !> \param mo_set : upon output contains the molecular orbitals (eigenvectors)
592 !> and eigenvalues
593 !> \param fm_ortho : one of the work matrices, on output, the BLACS distributed
594 !> matrix for orthogalising the eigen problem. E.g. if using
595 !> Cholesky inversse, then the upper triangle part contains
596 !> the inverse of Cholesky U; if not using Cholesky, then it
597 !> contains the S^-1/2.
598 !> \param fm_work : work matrix used by eigen solver
599 !> \param eps_eigval : used for quenching the small numbers when computing S^-1/2
600 !> any values less than eps_eigval is truncated to zero.
601 !> \param ndep : if the overlap is not positive definite, then ndep > 0,
602 !> and equals to the number of linear dependent basis functions
603 !> in the filtered basis set
604 !> \param method : method for solving generalised eigenvalue problem
605 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
606 ! **************************************************************************************************
607  SUBROUTINE fb_env_eigensolver(fm_KS, fm_S, mo_set, fm_ortho, &
608  fm_work, eps_eigval, ndep, method)
609  TYPE(cp_fm_type), INTENT(IN) :: fm_ks, fm_s
610  TYPE(mo_set_type), INTENT(IN) :: mo_set
611  TYPE(cp_fm_type), INTENT(IN) :: fm_ortho, fm_work
612  REAL(kind=dp), INTENT(IN) :: eps_eigval
613  INTEGER, INTENT(OUT) :: ndep
614  INTEGER, INTENT(IN) :: method
615 
616  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_eigensolver'
617 
618  CHARACTER(len=8) :: ndep_string
619  INTEGER :: handle, info, my_method, nao, nmo
620  REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues
621  TYPE(cp_fm_type), POINTER :: mo_coeff
622 
623  CALL timeset(routinen, handle)
624 
625  CALL get_mo_set(mo_set=mo_set, &
626  nao=nao, &
627  nmo=nmo, &
628  eigenvalues=mo_eigenvalues, &
629  mo_coeff=mo_coeff)
630  my_method = method
631  ndep = 0
632 
633  ! first, obtain orthogonalisation (ortho) matrix
634  IF (my_method .NE. cholesky_off) THEN
635  CALL cp_fm_to_fm(fm_s, fm_ortho)
636  CALL cp_fm_cholesky_decompose(fm_ortho, info_out=info)
637  IF (info .NE. 0) THEN
638  CALL cp_warn(__location__, &
639  "Unable to perform Cholesky decomposition on the overlap "// &
640  "matrix. The new filtered basis may not be linearly "// &
641  "independent set. Revert to using inverse square-root "// &
642  "of the overlap. To avoid this warning, you can try "// &
643  "to use a higher filter termperature.")
644  my_method = cholesky_off
645  ELSE
646  SELECT CASE (my_method)
647  CASE (cholesky_dbcsr)
648  CALL cp_abort(__location__, &
649  "filter matrix method with CHOLESKY_DBCSR is not yet implemented")
650  CASE (cholesky_reduce)
651  CALL cp_fm_cholesky_reduce(fm_ks, fm_ortho)
652  CALL choose_eigv_solver(fm_ks, fm_work, mo_eigenvalues)
653  CALL cp_fm_cholesky_restore(fm_work, nmo, fm_ortho, mo_coeff, "SOLVE")
654  CASE (cholesky_restore)
655  CALL cp_fm_upper_to_full(fm_ks, fm_work)
656  CALL cp_fm_cholesky_restore(fm_ks, nao, fm_ortho, fm_work, "SOLVE", &
657  pos="RIGHT")
658  CALL cp_fm_cholesky_restore(fm_work, nao, fm_ortho, fm_ks, "SOLVE", &
659  pos="LEFT", transa="T")
660  CALL choose_eigv_solver(fm_ks, fm_work, mo_eigenvalues)
661  CALL cp_fm_cholesky_restore(fm_work, nmo, fm_ortho, mo_coeff, "SOLVE")
662  CASE (cholesky_inverse)
663  CALL cp_fm_triangular_invert(fm_ortho)
664  CALL cp_fm_upper_to_full(fm_ks, fm_work)
665  CALL cp_fm_triangular_multiply(fm_ortho, &
666  fm_ks, &
667  side="R", &
668  transpose_tr=.false., &
669  invert_tr=.false., &
670  uplo_tr="U", &
671  n_rows=nao, &
672  n_cols=nao, &
673  alpha=1.0_dp)
674  CALL cp_fm_triangular_multiply(fm_ortho, &
675  fm_ks, &
676  side="L", &
677  transpose_tr=.true., &
678  invert_tr=.false., &
679  uplo_tr="U", &
680  n_rows=nao, &
681  n_cols=nao, &
682  alpha=1.0_dp)
683  CALL choose_eigv_solver(fm_ks, fm_work, mo_eigenvalues)
684  CALL cp_fm_triangular_multiply(fm_ortho, &
685  fm_work, &
686  side="L", &
687  transpose_tr=.false., &
688  invert_tr=.false., &
689  uplo_tr="U", &
690  n_rows=nao, &
691  n_cols=nmo, &
692  alpha=1.0_dp)
693  CALL cp_fm_to_fm(fm_work, mo_coeff, nmo, 1, 1)
694  END SELECT
695  END IF
696  END IF
697  IF (my_method == cholesky_off) THEN
698  ! calculating ortho as S^-1/2 using diagonalisation of S, and
699  ! solve accordingly
700  CALL cp_fm_to_fm(fm_s, fm_ortho)
701  CALL cp_fm_power(fm_ortho, fm_work, -0.5_dp, &
702  eps_eigval, ndep)
703  IF (ndep > 0) THEN
704  WRITE (ndep_string, fmt="(I8)") ndep
705  CALL cp_warn(__location__, &
706  "Number of linearly dependent filtered orbitals: "//ndep_string)
707  END IF
708  ! solve eigen equatoin using S^-1/2
709  CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, fm_ks, fm_ortho, &
710  0.0_dp, fm_work)
711  CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, fm_ortho, &
712  fm_work, 0.0_dp, fm_ks)
713  CALL choose_eigv_solver(fm_ks, fm_work, mo_eigenvalues)
714  CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, fm_ortho, &
715  fm_work, 0.0_dp, mo_coeff)
716  END IF
717 
718  CALL timestop(handle)
719 
720  END SUBROUTINE fb_env_eigensolver
721 
722 ! **************************************************************************************************
723 !> \brief Read input sections for filter matrix method
724 !> \param fb_env : the filter matrix environment
725 !> \param scf_section : SCF input section
726 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
727 ! **************************************************************************************************
728  SUBROUTINE fb_env_read_input(fb_env, scf_section)
729 
730  TYPE(fb_env_obj), INTENT(INOUT) :: fb_env
731  TYPE(section_vals_type), POINTER :: scf_section
732 
733  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_read_input'
734 
735  INTEGER :: handle
736  LOGICAL :: l_val
737  REAL(kind=dp) :: r_val
738  TYPE(section_vals_type), POINTER :: fb_section
739 
740  CALL timeset(routinen, handle)
741 
742  NULLIFY (fb_section)
743  fb_section => section_vals_get_subs_vals(scf_section, &
744  "DIAGONALIZATION%FILTER_MATRIX")
745  ! filter_temperature
746  CALL section_vals_val_get(fb_section, "FILTER_TEMPERATURE", &
747  r_val=r_val)
748  CALL fb_env_set(fb_env=fb_env, &
749  filter_temperature=r_val)
750  ! auto_cutoff_scale
751  CALL section_vals_val_get(fb_section, "AUTO_CUTOFF_SCALE", &
752  r_val=r_val)
753  CALL fb_env_set(fb_env=fb_env, &
754  auto_cutoff_scale=r_val)
755  ! communication model
756  CALL section_vals_val_get(fb_section, "COLLECTIVE_COMMUNICATION", &
757  l_val=l_val)
758  CALL fb_env_set(fb_env=fb_env, &
759  collective_com=l_val)
760  ! eps_default
761  CALL section_vals_val_get(fb_section, "EPS_FB", &
762  r_val=r_val)
763  CALL fb_env_set(fb_env=fb_env, &
764  eps_default=r_val)
765 
766  CALL timestop(handle)
767 
768  END SUBROUTINE fb_env_read_input
769 
770 ! **************************************************************************************************
771 !> \brief Automatically generate the cutoff radii of atoms used for
772 !> constructing the atomic halos, based on basis set cutoff
773 !> ranges for each kind
774 !> \param fb_env : the filter matrix environment
775 !> \param qs_env : quickstep environment
776 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
777 ! **************************************************************************************************
778  SUBROUTINE fb_env_build_rcut_auto(fb_env, qs_env)
779  TYPE(fb_env_obj), INTENT(INOUT) :: fb_env
780  TYPE(qs_environment_type), POINTER :: qs_env
781 
782  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_build_rcut_auto'
783 
784  INTEGER :: handle, ikind, nkinds
785  REAL(kind=dp) :: auto_cutoff_scale, kind_radius
786  REAL(kind=dp), DIMENSION(:), POINTER :: rcut
787  TYPE(dft_control_type), POINTER :: dft_control
788  TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
789  TYPE(gto_basis_set_type), POINTER :: basis_set
790  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
791 
792  CALL timeset(routinen, handle)
793 
794  NULLIFY (rcut, qs_kind_set, dft_control)
795 
796  CALL get_qs_env(qs_env=qs_env, &
797  qs_kind_set=qs_kind_set, &
798  dft_control=dft_control)
799  CALL fb_env_get(fb_env=fb_env, &
800  auto_cutoff_scale=auto_cutoff_scale)
801 
802  nkinds = SIZE(qs_kind_set)
803  ALLOCATE (rcut(nkinds))
804 
805  ! reading from the other parts of the code, it seemed that
806  ! aux_fit_basis_set is only used when do_admm is TRUE. This can be
807  ! seen from the calls to generate_qs_task_list subroutine in
808  ! qs_create_task_list, found in qs_environment_methods.F:
809  ! basis_type is only set as input parameter for do_admm
810  ! calculations, and if not set, the task list is generated using
811  ! the default basis_set="ORB".
812  ALLOCATE (basis_set_list(nkinds))
813  IF (dft_control%do_admm) THEN
814  CALL basis_set_list_setup(basis_set_list, "AUX_FIT", qs_kind_set)
815  ELSE
816  CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
817  END IF
818 
819  DO ikind = 1, nkinds
820  basis_set => basis_set_list(ikind)%gto_basis_set
821  CALL get_gto_basis_set(gto_basis_set=basis_set, kind_radius=kind_radius)
822  rcut(ikind) = kind_radius*auto_cutoff_scale
823  END DO
824 
825  CALL fb_env_set(fb_env=fb_env, &
826  rcut=rcut)
827 
828  ! cleanup
829  DEALLOCATE (basis_set_list)
830 
831  CALL timestop(handle)
832 
833  END SUBROUTINE fb_env_build_rcut_auto
834 
835 ! **************************************************************************************************
836 !> \brief Builds an fb_atomic_halo_list object using information
837 !> from fb_env
838 !> \param fb_env the fb_env object
839 !> \param qs_env : quickstep environment (need this to access particle)
840 !> positions and their kinds as well as which particles
841 !> are local to this process
842 !> \param scf_section : SCF input section, for printing output
843 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
844 ! **************************************************************************************************
845  SUBROUTINE fb_env_build_atomic_halos(fb_env, qs_env, scf_section)
846  TYPE(fb_env_obj), INTENT(INOUT) :: fb_env
847  TYPE(qs_environment_type), POINTER :: qs_env
848  TYPE(section_vals_type), POINTER :: scf_section
849 
850  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_build_atomic_halos'
851 
852  INTEGER :: handle, iatom, ihalo, max_natoms_local, natoms_global, natoms_local, nelectrons, &
853  nhalo_atoms, nkinds_global, owner_id_in_halo
854  INTEGER, DIMENSION(:), POINTER :: halo_atoms, local_atoms
855  REAL(kind=dp) :: cost
856  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radii
857  REAL(kind=dp), DIMENSION(:), POINTER :: rcut
858  TYPE(cell_type), POINTER :: cell
859  TYPE(fb_atomic_halo_list_obj) :: atomic_halos
860  TYPE(fb_atomic_halo_obj), DIMENSION(:), POINTER :: halos
861  TYPE(mp_para_env_type), POINTER :: para_env
862  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
863  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
864 
865  CALL timeset(routinen, handle)
866 
867  cpassert(fb_env_has_data(fb_env))
868 
869  NULLIFY (cell, halos, halo_atoms, rcut, particle_set, para_env, &
870  qs_kind_set, local_atoms)
871  CALL fb_atomic_halo_list_nullify(atomic_halos)
872 
873  ! get relevant data from fb_env
874  CALL fb_env_get(fb_env=fb_env, &
875  rcut=rcut, &
876  local_atoms=local_atoms, &
877  nlocal_atoms=natoms_local)
878 
879  ! create atomic_halos
880  CALL fb_atomic_halo_list_create(atomic_halos)
881 
882  ! get the number of atoms and kinds:
883  CALL get_qs_env(qs_env=qs_env, &
884  natom=natoms_global, &
885  particle_set=particle_set, &
886  qs_kind_set=qs_kind_set, &
887  nkind=nkinds_global, &
888  para_env=para_env, &
889  cell=cell)
890 
891  ! get the maximum number of local atoms across the procs.
892  max_natoms_local = natoms_local
893  CALL para_env%max(max_natoms_local)
894 
895  ! create the halos, one for each local atom
896  ALLOCATE (halos(natoms_local))
897  DO ihalo = 1, natoms_local
898  CALL fb_atomic_halo_nullify(halos(ihalo))
899  CALL fb_atomic_halo_create(halos(ihalo))
900  END DO
901  CALL fb_atomic_halo_list_set(atomic_halos=atomic_halos, &
902  nhalos=natoms_local, &
903  max_nhalos=max_natoms_local)
904  ! build halos
905  ALLOCATE (pair_radii(nkinds_global, nkinds_global))
906  CALL fb_build_pair_radii(rcut, nkinds_global, pair_radii)
907  ihalo = 0
908  DO iatom = 1, natoms_local
909  ihalo = ihalo + 1
910  CALL fb_atomic_halo_build_halo_atoms(local_atoms(iatom), &
911  particle_set, &
912  cell, &
913  pair_radii, &
914  halo_atoms, &
915  nhalo_atoms, &
916  owner_id_in_halo)
917  CALL fb_atomic_halo_set(atomic_halo=halos(ihalo), &
918  owner_atom=local_atoms(iatom), &
919  owner_id_in_halo=owner_id_in_halo, &
920  natoms=nhalo_atoms, &
921  halo_atoms=halo_atoms)
922  ! prepare halo_atoms for another halo, do not deallocate, as
923  ! original data is being pointed at by the atomic halo data
924  ! structure
925  NULLIFY (halo_atoms)
926  ! calculate the number of electrons in each halo
927  nelectrons = fb_atomic_halo_nelectrons_estimate_z(halos(ihalo), &
928  particle_set)
929  ! calculate cost
930  cost = fb_atomic_halo_cost(halos(ihalo), particle_set, qs_kind_set)
931  CALL fb_atomic_halo_set(atomic_halo=halos(ihalo), &
932  nelectrons=nelectrons, &
933  cost=cost)
934  ! sort atomic halo
935  CALL fb_atomic_halo_sort(halos(ihalo))
936  END DO ! iatom
937  DEALLOCATE (pair_radii)
938 
939  ! finalise
940  CALL fb_atomic_halo_list_set(atomic_halos=atomic_halos, &
941  halos=halos)
942  CALL fb_env_set(fb_env=fb_env, &
943  atomic_halos=atomic_halos)
944 
945  ! print info
946  CALL fb_atomic_halo_list_write_info(atomic_halos, &
947  para_env, &
948  scf_section)
949 
950  CALL timestop(handle)
951 
952  END SUBROUTINE fb_env_build_atomic_halos
953 
954 ! **************************************************************************************************
955 !> \brief Automatically construct the trial functiosn used for generating
956 !> the filter matrix. It tries to use the single zeta subset from
957 !> the system GTO basis set as the trial functions
958 !> \param fb_env : the filter matrix environment
959 !> \param qs_env : quickstep environment
960 !> \param maxocc : maximum occupancy for an orbital
961 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
962 ! **************************************************************************************************
963  SUBROUTINE fb_env_build_trial_fns_auto(fb_env, qs_env, maxocc)
964 
965  TYPE(fb_env_obj), INTENT(INOUT) :: fb_env
966  TYPE(qs_environment_type), POINTER :: qs_env
967  REAL(kind=dp), INTENT(IN) :: maxocc
968 
969  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_build_trial_fns_auto'
970 
971  INTEGER :: counter, handle, icgf, ico, ikind, iset, &
972  ishell, itrial, lshell, max_n_trial, &
973  nkinds, nset, old_lshell
974  INTEGER, DIMENSION(:), POINTER :: lmax, nfunctions, nshell
975  INTEGER, DIMENSION(:, :), POINTER :: functions
976  REAL(kind=dp) :: zeff
977  TYPE(dft_control_type), POINTER :: dft_control
978  TYPE(fb_trial_fns_obj) :: trial_fns
979  TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
980  TYPE(gto_basis_set_type), POINTER :: basis_set
981  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
982 
983  CALL timeset(routinen, handle)
984 
985  cpassert(fb_env_has_data(fb_env))
986  NULLIFY (nfunctions, functions, basis_set, basis_set_list, qs_kind_set, dft_control)
987  CALL fb_trial_fns_nullify(trial_fns)
988 
989  ! create a new trial_fn object
990  CALL fb_trial_fns_create(trial_fns)
991 
992  CALL get_qs_env(qs_env=qs_env, &
993  qs_kind_set=qs_kind_set, &
994  dft_control=dft_control)
995 
996  nkinds = SIZE(qs_kind_set)
997 
998  ! reading from the other parts of the code, it seemed that
999  ! aux_fit_basis_set is only used when do_admm is TRUE. This can be
1000  ! seen from the calls to generate_qs_task_list subroutine in
1001  ! qs_create_task_list, found in qs_environment_methods.F:
1002  ! basis_type is only set as input parameter for do_admm
1003  ! calculations, and if not set, the task list is generated using
1004  ! the default basis_set="ORB".
1005  ALLOCATE (basis_set_list(nkinds))
1006  IF (dft_control%do_admm) THEN
1007  CALL basis_set_list_setup(basis_set_list, "AUX_FIT", qs_kind_set)
1008  ELSE
1009  CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
1010  END IF
1011 
1012  ALLOCATE (nfunctions(nkinds))
1013  nfunctions = 0
1014 
1015  DO ikind = 1, nkinds
1016  ! "gto = gaussian type orbital"
1017  basis_set => basis_set_list(ikind)%gto_basis_set
1018  CALL get_gto_basis_set(gto_basis_set=basis_set, &
1019  nset=nset, &
1020  lmax=lmax, &
1021  nshell=nshell)
1022  CALL get_qs_kind(qs_kind=qs_kind_set(ikind), &
1023  zeff=zeff)
1024 
1025  bset1: DO iset = 1, nset
1026 ! old_lshell = lmax(iset)
1027  old_lshell = -1
1028  DO ishell = 1, nshell(iset)
1029  lshell = basis_set%l(ishell, iset)
1030  counter = 0
1031  ! loop over orbitals within the same l
1032  DO ico = ncoset(lshell - 1) + 1, ncoset(lshell)
1033  counter = counter + 1
1034  ! only include the first zeta orbitals
1035  IF ((lshell .GT. old_lshell) .AND. (counter .LE. nco(lshell))) THEN
1036  nfunctions(ikind) = nfunctions(ikind) + 1
1037  END IF
1038  END DO
1039  ! we have got enough trial functions when we have enough
1040  ! basis functions to accommodate the number of electrons,
1041  ! AND that that we have included all the first zeta
1042  ! orbitals of an angular momentum quantum number l
1043  IF (((lshell .GT. old_lshell) .OR. (lshell .EQ. lmax(iset))) .AND. &
1044  (maxocc*real(nfunctions(ikind), dp) .GE. zeff)) THEN
1045  EXIT bset1
1046  END IF
1047  old_lshell = lshell
1048  END DO
1049  END DO bset1
1050  END DO ! ikind
1051 
1052  ! now that we have the number of trial functions get the trial
1053  ! functions
1054  max_n_trial = maxval(nfunctions)
1055  ALLOCATE (functions(max_n_trial, nkinds))
1056  functions(:, :) = 0
1057  ! redo the loops to get the trial function indices within the basis set
1058  DO ikind = 1, nkinds
1059  ! "gto = gaussian type orbital"
1060  basis_set => basis_set_list(ikind)%gto_basis_set
1061  CALL get_gto_basis_set(gto_basis_set=basis_set, &
1062  nset=nset, &
1063  lmax=lmax, &
1064  nshell=nshell)
1065  CALL get_qs_kind(qs_kind=qs_kind_set(ikind), &
1066  zeff=zeff)
1067  icgf = 0
1068  itrial = 0
1069  bset2: DO iset = 1, nset
1070  old_lshell = -1
1071  DO ishell = 1, nshell(iset)
1072  lshell = basis_set%l(ishell, iset)
1073  counter = 0
1074  ! loop over orbitals within the same l
1075  DO ico = ncoset(lshell - 1) + 1, ncoset(lshell)
1076  icgf = icgf + 1
1077  counter = counter + 1
1078  ! only include the first zeta orbitals
1079  IF ((lshell .GT. old_lshell) .AND. (counter .LE. nco(lshell))) THEN
1080  itrial = itrial + 1
1081  functions(itrial, ikind) = icgf
1082  END IF
1083  END DO
1084  ! we have got enough trial functions when we have more
1085  ! basis functions than the number of electrons (obtained
1086  ! from atomic z), AND that that we have included all the
1087  ! first zeta orbitals of an angular momentum quantum
1088  ! number l
1089  IF (((lshell .GT. old_lshell) .OR. (lshell .EQ. lmax(iset))) .AND. &
1090  (maxocc*real(itrial, dp) .GE. zeff)) THEN
1091  EXIT bset2
1092  END IF
1093  old_lshell = lshell
1094  END DO
1095  END DO bset2
1096  END DO ! ikind
1097 
1098  ! set trial_functions
1099  CALL fb_trial_fns_set(trial_fns=trial_fns, &
1100  nfunctions=nfunctions, &
1101  functions=functions)
1102  ! set fb_env
1103  CALL fb_env_set(fb_env=fb_env, &
1104  trial_fns=trial_fns)
1105  CALL fb_trial_fns_release(trial_fns)
1106 
1107  ! cleanup
1108  DEALLOCATE (basis_set_list)
1109 
1110  CALL timestop(handle)
1111 
1112  END SUBROUTINE fb_env_build_trial_fns_auto
1113 
1114 ! **************************************************************************************************
1115 !> \brief Copy the sparse structure of a DBCSR matrix to another, this
1116 !> means the other matrix will have the same number of blocks
1117 !> and their corresponding logical locations allocated, although
1118 !> the blocks does not have to be the same size as the original
1119 !> \param matrix_out : DBCSR matrix whose blocks are to be allocated
1120 !> \param matrix_in : DBCSR matrix with existing sparse structure that
1121 !> is to be copied
1122 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
1123 ! **************************************************************************************************
1124  SUBROUTINE fb_dbcsr_copy_sparse_struct(matrix_out, matrix_in)
1125 
1126  TYPE(dbcsr_type), INTENT(INOUT) :: matrix_out
1127  TYPE(dbcsr_type), INTENT(IN) :: matrix_in
1128 
1129  INTEGER :: iatom, iblk, jatom, nblkcols_total, &
1130  nblkrows_total, nblks
1131  INTEGER, ALLOCATABLE, DIMENSION(:) :: cols, rows
1132  REAL(dp), DIMENSION(:, :), POINTER :: mat_block
1133  TYPE(dbcsr_iterator_type) :: iter
1134 
1135  CALL dbcsr_get_info(matrix=matrix_in, &
1136  nblkrows_total=nblkrows_total, &
1137  nblkcols_total=nblkcols_total)
1138 
1139  nblks = nblkrows_total*nblkcols_total
1140  ALLOCATE (rows(nblks))
1141  ALLOCATE (cols(nblks))
1142  rows(:) = 0
1143  cols(:) = 0
1144  iblk = 0
1145  nblks = 0
1146  CALL dbcsr_iterator_start(iter, matrix_in)
1147  DO WHILE (dbcsr_iterator_blocks_left(iter))
1148  CALL dbcsr_iterator_next_block(iter, iatom, jatom, mat_block, iblk)
1149  rows(iblk) = iatom
1150  cols(iblk) = jatom
1151  nblks = nblks + 1
1152  END DO
1153  CALL dbcsr_iterator_stop(iter)
1154  CALL dbcsr_reserve_blocks(matrix_out, rows(1:nblks), cols(1:nblks))
1155  CALL dbcsr_finalize(matrix_out)
1156 
1157  ! cleanup
1158  DEALLOCATE (rows)
1159  DEALLOCATE (cols)
1160 
1161  END SUBROUTINE fb_dbcsr_copy_sparse_struct
1162 
1163 ! **************************************************************************************************
1164 !> \brief Write out parameters used for the filter matrix method to
1165 !> output
1166 !> \param fb_env : the filter matrix environment
1167 !> \param qs_env : quickstep environment
1168 !> \param scf_section : SCF input section
1169 !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
1170 ! **************************************************************************************************
1171  SUBROUTINE fb_env_write_info(fb_env, qs_env, scf_section)
1172  TYPE(fb_env_obj), INTENT(IN) :: fb_env
1173  TYPE(qs_environment_type), POINTER :: qs_env
1174  TYPE(section_vals_type), POINTER :: scf_section
1175 
1176  CHARACTER(len=*), PARAMETER :: routinen = 'fb_env_write_info'
1177 
1178  CHARACTER(LEN=2) :: element_symbol
1179  INTEGER :: handle, ikind, nkinds, unit_nr
1180  LOGICAL :: collective_com
1181  REAL(kind=dp) :: auto_cutoff_scale, filter_temperature
1182  REAL(kind=dp), DIMENSION(:), POINTER :: rcut
1183  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1184  TYPE(cp_logger_type), POINTER :: logger
1185 
1186  CALL timeset(routinen, handle)
1187 
1188  NULLIFY (rcut, atomic_kind_set, logger)
1189 
1190  CALL get_qs_env(qs_env=qs_env, &
1191  atomic_kind_set=atomic_kind_set)
1192  CALL fb_env_get(fb_env=fb_env, &
1193  filter_temperature=filter_temperature, &
1194  auto_cutoff_scale=auto_cutoff_scale, &
1195  rcut=rcut, &
1196  collective_com=collective_com)
1197 
1198  nkinds = SIZE(atomic_kind_set)
1199 
1200  logger => cp_get_default_logger()
1201  unit_nr = cp_print_key_unit_nr(logger, scf_section, &
1202  "PRINT%FILTER_MATRIX", &
1203  extension="")
1204  IF (unit_nr > 0) THEN
1205  IF (collective_com) THEN
1206  WRITE (unit=unit_nr, fmt="(/,A,T71,A)") &
1207  " FILTER_MAT_DIAG| MPI communication method:", &
1208  "Collective"
1209  ELSE
1210  WRITE (unit=unit_nr, fmt="(/,A,T71,A)") &
1211  " FILTER_MAT_DIAG| MPI communication method:", &
1212  "At each step"
1213  END IF
1214  WRITE (unit=unit_nr, fmt="(A,T71,g10.4)") &
1215  " FILTER_MAT_DIAG| Filter temperature [K]:", &
1216  cp_unit_from_cp2k(filter_temperature, "K")
1217  WRITE (unit=unit_nr, fmt="(A,T71,f10.4)") &
1218  " FILTER_MAT_DIAG| Filter temperature [a.u.]:", &
1219  filter_temperature
1220  WRITE (unit=unit_nr, fmt="(A,T71,f10.4)") &
1221  " FILTER_MAT_DIAG| Auto atomic cutoff radius scale:", &
1222  auto_cutoff_scale
1223  WRITE (unit=unit_nr, fmt="(A)") &
1224  " FILTER_MAT_DIAG| atomic cutoff radii [a.u.]"
1225  DO ikind = 1, nkinds
1226  CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), &
1227  element_symbol=element_symbol)
1228  WRITE (unit=unit_nr, fmt="(A,A,T71,f10.4)") &
1229  " FILTER_MAT_DIAG| ", element_symbol, rcut(ikind)
1230  END DO ! ikind
1231  END IF
1232  CALL cp_print_key_finished_output(unit_nr, logger, scf_section, &
1233  "PRINT%FILTER_MATRIX")
1234 
1235  CALL timestop(handle)
1236 
1237  END SUBROUTINE fb_env_write_info
1238 
1239 END MODULE qs_fb_env_methods
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius)
...
Handles all functions related to the CELL.
Definition: cell_types.F:15
methods related to the blacs parallel environment
Definition: cp_blacs_env.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
basic linear algebra operations for full matrices
subroutine, public cp_fm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
computes matrix_c = beta * matrix_c + alpha * ( matrix_a ** transa ) * ( matrix_b ** transb )
subroutine, public cp_fm_upper_to_full(matrix, work)
given an upper triangular matrix computes the corresponding full matrix
subroutine, public cp_fm_triangular_invert(matrix_a, uplo_tr)
inverts a triangular matrix
subroutine, public cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
computes matrix_c = beta * matrix_c + alpha * matrix_a * matrix_b computes matrix_c = beta * matrix_c...
subroutine, public cp_fm_triangular_multiply(triangular_matrix, matrix_b, side, transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, alpha)
multiplies in place by a triangular matrix: matrix_b = alpha op(triangular_matrix) matrix_b or (if si...
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_fm_cholesky_reduce(matrix, matrixb, itype)
reduce a matrix pencil A,B to normal form B has to be cholesky decomposed with cp_fm_cholesky_decompo...
subroutine, public cp_fm_cholesky_restore(matrix, neig, matrixb, matrixout, op, pos, transa)
...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition: cp_fm_diag.F:17
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
Definition: cp_fm_diag.F:896
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
Definition: cp_fm_diag.F:208
represent the structure of a full matrix
Definition: cp_fm_struct.F:14
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
Definition: cp_fm_struct.F:125
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
represent a full matrix distributed on many processors
Definition: cp_fm_types.F:15
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
Definition: cp_fm_types.F:535
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
unit conversion facility
Definition: cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition: cp_units.F:1179
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public cholesky_restore
integer, parameter, public cholesky_dbcsr
integer, parameter, public cholesky_off
integer, parameter, public cholesky_reduce
integer, parameter, public cholesky_inverse
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nco
integer, dimension(:), allocatable, public ncoset
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
collects routines that calculate density matrices
Apply the direct inversion in the iterative subspace (DIIS) of Pulay in the framework of an SCF itera...
Definition: qs_diis.F:21
subroutine, public qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
Update the SCF DIIS buffer, and if appropriate does a diis step.
Definition: qs_diis.F:228
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
real(kind=dp) function, public fb_atomic_halo_cost(atomic_halo, particle_set, qs_kind_set)
Estimates the computational cost with respect to the filter matrix calculation associated to an atomi...
subroutine, public fb_atomic_halo_build_halo_atoms(owner_atom, particle_set, cell, pair_radii, halo_atoms, nhalo_atoms, owner_id_in_halo)
Builds halo atoms for a given (owner) atom.
subroutine, public fb_atomic_halo_set(atomic_halo, owner_atom, owner_id_in_halo, natoms, nelectrons, halo_atoms, sorted, cost)
Sets attributes in a fb_atomic_halo object, one should only set the data content in a fb_atomic_halo ...
subroutine, public fb_atomic_halo_sort(atomic_halo)
Sort the list of atomic indices in the halo in ascending order. The atomic_halo must not be empty.
subroutine, public fb_atomic_halo_create(atomic_halo)
Creates and initialises an empty fb_atomic_halo object.
subroutine, public fb_atomic_halo_list_create(atomic_halos)
Creates and initialises an empty fb_atomic_halo_list object.
pure subroutine, public fb_build_pair_radii(rcut, nkinds, pair_radii)
Builds the required pair_radii array required for building the halo atoms from a given set of cut off...
subroutine, public fb_atomic_halo_list_set(atomic_halos, nhalos, max_nhalos, halos)
Sets attributes from an fb_atomic_halo_list object, one should only set the data content in a fb_atom...
subroutine, public fb_atomic_halo_nullify(atomic_halo)
Nullifies a fb_atomic_halo object, note that it does not release the original object....
integer function, public fb_atomic_halo_nelectrons_estimate_z(atomic_halo, particle_set)
Estimates the total number of electrons in a halo using atomic numbers.
subroutine, public fb_atomic_halo_list_write_info(atomic_halos, para_env, scf_section)
Writes out the atomic halo list summary, no detailed neighbour lists, just average,...
subroutine, public fb_atomic_halo_list_nullify(atomic_halos)
Nullifies a fb_atomic_halo_list object, note that it does not release the original object....
subroutine, public fb_env_do_diag(fb_env, qs_env, matrix_ks, matrix_s, scf_section, diis_step)
Do filtered matrix method diagonalisation.
subroutine, public fb_env_read_input(fb_env, scf_section)
Read input sections for filter matrix method.
subroutine, public fb_env_build_atomic_halos(fb_env, qs_env, scf_section)
Builds an fb_atomic_halo_list object using information from fb_env.
subroutine, public fb_env_write_info(fb_env, qs_env, scf_section)
Write out parameters used for the filter matrix method to output.
subroutine, public fb_env_build_rcut_auto(fb_env, qs_env)
Automatically generate the cutoff radii of atoms used for constructing the atomic halos,...
logical function, public fb_env_has_data(fb_env)
Checks if a fb_env object is associated with an actual data content or not.
subroutine, public fb_env_get(fb_env, rcut, filter_temperature, auto_cutoff_scale, eps_default, atomic_halos, trial_fns, collective_com, local_atoms, nlocal_atoms)
method to get attributes from a given fb_env object
subroutine, public fb_env_set(fb_env, rcut, filter_temperature, auto_cutoff_scale, eps_default, atomic_halos, trial_fns, collective_com, local_atoms, nlocal_atoms)
method to set attributes from a given fb_env object
subroutine, public fb_fltrmat_build_2(H_mat, S_mat, atomic_halos, trial_fns, para_env, particle_set, fermi_level, filter_temp, name, filter_mat, tolerance)
Build the filter matrix, with MPI communications grouped together. More effcient on communication,...
subroutine, public fb_fltrmat_build(H_mat, S_mat, atomic_halos, trial_fns, para_env, particle_set, fermi_level, filter_temp, name, filter_mat, tolerance)
Build the filter matrix, with MPI communications happening at each step. Less efficient on communicat...
subroutine, public fb_trial_fns_set(trial_fns, nfunctions, functions)
sets the attributes of a fb_trial_fns object
subroutine, public fb_trial_fns_nullify(trial_fns)
nullifies the content of given object
subroutine, public fb_trial_fns_release(trial_fns)
releases given object
subroutine, public fb_trial_fns_create(trial_fns)
creates an fb_trial_fns object and initialises it
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
Define the quickstep kind type and their sub types.
Definition: qs_kind_types.F:23
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, U_of_dft_plus_u, J_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, J0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Set occupation of molecular orbitals.
Definition and initialisation of the mo data type.
Definition: qs_mo_types.F:22
subroutine, public set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, uniform_occupation, kTS, mu, flexible_electron_count)
Set the components of a MO set data structure.
Definition: qs_mo_types.F:452
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
Definition: qs_mo_types.F:206
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
Definition: qs_mo_types.F:352
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kTS, mu, flexible_electron_count)
Get the components of a MO set data structure.
Definition: qs_mo_types.F:397
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
Definition: qs_mo_types.F:245
module that contains the definitions of the scf types
Definition: qs_scf_types.F:14
parameters that control an scf iteration
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.