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 Subroutines to perform calculations on molecules from a bigger
10 : !> system. Useful to generate a high-quality MO guess for systems
11 : !> of many molecules with complex electronic structure, to bootstrap
12 : !> ALMO simulations, etc.
13 : !> \par History
14 : !> 10.2014 Rustam Z Khaliullin
15 : !> 09.2018 ALMO smearing support and ALMO diag+molecular_guess patch [Ruben Staub]
16 : !> \author Rustam Z Khaliullin
17 : ! **************************************************************************************************
18 : MODULE mscfg_methods
19 : USE almo_scf_types, ONLY: almo_scf_env_type
20 : USE atomic_kind_types, ONLY: get_atomic_kind
21 : USE cp_dbcsr_api, ONLY: dbcsr_copy,&
22 : dbcsr_create,&
23 : dbcsr_type_no_symmetry
24 : USE cp_dbcsr_operations, ONLY: copy_fm_to_dbcsr
25 : USE cp_log_handling, ONLY: cp_get_default_logger,&
26 : cp_logger_get_default_unit_nr,&
27 : cp_logger_type
28 : USE cp_subsys_methods, ONLY: create_small_subsys
29 : USE cp_subsys_types, ONLY: cp_subsys_get,&
30 : cp_subsys_release,&
31 : cp_subsys_type
32 : USE force_env_types, ONLY: force_env_get,&
33 : force_env_type
34 : USE global_types, ONLY: global_environment_type
35 : USE input_constants, ONLY: almo_frz_crystal,&
36 : almo_frz_none,&
37 : do_qs,&
38 : molecular_guess
39 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
40 : section_vals_type,&
41 : section_vals_val_get,&
42 : section_vals_val_set
43 : USE kinds, ONLY: default_string_length
44 : USE message_passing, ONLY: mp_para_env_type
45 : USE molecule_types, ONLY: get_molecule_set_info,&
46 : molecule_type
47 : USE mscfg_types, ONLY: molecular_scf_guess_env_init,&
48 : molecular_scf_guess_env_type,&
49 : mscfg_max_moset_size
50 : USE particle_list_types, ONLY: particle_list_type
51 : USE qs_energy, ONLY: qs_energies
52 : USE qs_energy_types, ONLY: qs_energy_type
53 : USE qs_environment, ONLY: qs_init
54 : USE qs_environment_types, ONLY: get_qs_env,&
55 : qs_env_create,&
56 : qs_env_release,&
57 : qs_environment_type
58 : USE qs_mo_types, ONLY: get_mo_set,&
59 : mo_set_type
60 : #include "./base/base_uses.f90"
61 :
62 : IMPLICIT NONE
63 : PRIVATE
64 :
65 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mscfg_methods'
66 :
67 : PUBLIC :: loop_over_molecules, do_mol_loop
68 :
69 : CONTAINS
70 :
71 : ! **************************************************************************************************
72 : !> \brief Prepare data for calculations on isolated molecules.
73 : !> \param globenv ...
74 : !> \param force_env ...
75 : !> \par History
76 : !> 10.2014 created [Rustam Z Khaliullin]
77 : !> \author Rustam Z Khaliullin
78 : ! **************************************************************************************************
79 10 : SUBROUTINE loop_over_molecules(globenv, force_env)
80 :
81 : TYPE(global_environment_type), POINTER :: globenv
82 : TYPE(force_env_type), POINTER :: force_env
83 :
84 : INTEGER :: nmols
85 : INTEGER, ALLOCATABLE, DIMENSION(:) :: charge_of_frag, first_atom_of_frag, &
86 : last_atom_of_frag, multip_of_frag
87 10 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
88 : TYPE(qs_environment_type), POINTER :: qs_env
89 :
90 10 : CALL force_env_get(force_env, qs_env=qs_env)
91 10 : CPASSERT(ASSOCIATED(qs_env))
92 : CALL get_qs_env(qs_env, &
93 10 : molecule_set=molecule_set)
94 :
95 10 : nmols = SIZE(molecule_set)
96 :
97 30 : ALLOCATE (first_atom_of_frag(nmols))
98 30 : ALLOCATE (last_atom_of_frag(nmols))
99 30 : ALLOCATE (charge_of_frag(nmols))
100 30 : ALLOCATE (multip_of_frag(nmols))
101 :
102 : CALL get_molecule_set_info(molecule_set, &
103 : mol_to_first_atom=first_atom_of_frag, &
104 : mol_to_last_atom=last_atom_of_frag, &
105 : mol_to_charge=charge_of_frag, &
106 10 : mol_to_multiplicity=multip_of_frag)
107 :
108 : CALL calcs_on_isolated_molecules(force_env, globenv, nmols, &
109 10 : first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
110 :
111 10 : DEALLOCATE (first_atom_of_frag)
112 10 : DEALLOCATE (last_atom_of_frag)
113 10 : DEALLOCATE (charge_of_frag)
114 10 : DEALLOCATE (multip_of_frag)
115 :
116 10 : END SUBROUTINE loop_over_molecules
117 :
118 : ! **************************************************************************************************
119 : !> \brief Run calculations on isolated molecules. The ideas for setting up
120 : !> the calculations are borrowed from BSSE files
121 : !> \param force_env ...
122 : !> \param globenv ...
123 : !> \param nfrags ...
124 : !> \param first_atom_of_frag ...
125 : !> \param last_atom_of_frag ...
126 : !> \param charge_of_frag ...
127 : !> \param multip_of_frag ...
128 : !> \par History
129 : !> 10.2014 created
130 : !> 09.2018 ALMO smearing support, and ALMO diag+molecular_guess patch [Ruben Staub]
131 : !> \author Rustam Z Khaliullin
132 : ! **************************************************************************************************
133 60 : SUBROUTINE calcs_on_isolated_molecules(force_env, globenv, nfrags, &
134 10 : first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
135 :
136 : TYPE(force_env_type), POINTER :: force_env
137 : TYPE(global_environment_type), POINTER :: globenv
138 : INTEGER, INTENT(IN) :: nfrags
139 : INTEGER, DIMENSION(:), INTENT(IN) :: first_atom_of_frag, last_atom_of_frag, &
140 : charge_of_frag, multip_of_frag
141 :
142 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calcs_on_isolated_molecules'
143 :
144 : CHARACTER(LEN=default_string_length) :: name
145 : CHARACTER(LEN=default_string_length), &
146 10 : DIMENSION(:), POINTER :: atom_type
147 : INTEGER :: first_atom, force_method, global_charge, global_multpl, handle, i, ifrag, imo, &
148 : isize, j, k, last_atom, my_targ, nb_eigenval_stored, nmo, nmo_of_frag, nmosets_of_frag, &
149 : tot_added_mos, tot_isize
150 10 : INTEGER, DIMENSION(:), POINTER :: atom_index, atom_list
151 : LOGICAL :: global_almo_scf_keyword, smear_almo_scf
152 : TYPE(almo_scf_env_type), POINTER :: almo_scf_env
153 : TYPE(cp_subsys_type), POINTER :: subsys, subsys_loc
154 10 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos, mos_of_frag
155 : TYPE(molecular_scf_guess_env_type), POINTER :: mscfg_env
156 : TYPE(mp_para_env_type), POINTER :: para_env
157 : TYPE(particle_list_type), POINTER :: particles
158 : TYPE(qs_energy_type), POINTER :: qs_energy
159 : TYPE(qs_environment_type), POINTER :: qs_env, qs_env_loc
160 : TYPE(section_vals_type), POINTER :: dft_section, force_env_section, &
161 : qs_section, root_section, scf_section, &
162 : subsys_section
163 :
164 10 : CALL timeset(routineN, handle)
165 :
166 10 : NULLIFY (subsys_loc, subsys, particles, para_env, atom_index, atom_type, &
167 10 : force_env_section, qs_env_loc, mscfg_env, qs_env, qs_energy)
168 : CALL force_env_get(force_env, force_env_section=force_env_section, &
169 10 : qs_env=qs_env)
170 10 : CALL section_vals_val_get(force_env_section, "METHOD", i_val=force_method)
171 10 : CPASSERT(force_method == do_qs)
172 10 : root_section => force_env%root_section
173 10 : subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
174 10 : dft_section => section_vals_get_subs_vals(force_env_section, "DFT")
175 : !
176 : ! Save several global settings to restore them after the loop:
177 : ! charge, multiplicity, ALMO flag
178 : !
179 10 : CALL section_vals_val_get(dft_section, "CHARGE", i_val=global_charge)
180 10 : CALL section_vals_val_get(dft_section, "MULTIPLICITY", i_val=global_multpl)
181 10 : qs_section => section_vals_get_subs_vals(dft_section, "QS")
182 10 : CALL section_vals_val_get(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
183 : !
184 : ! Get access to critical data before the loop
185 : !
186 10 : CALL force_env_get(force_env=force_env, subsys=subsys, para_env=para_env)
187 10 : CALL cp_subsys_get(subsys, particles=particles)
188 10 : CALL get_qs_env(qs_env, mscfg_env=mscfg_env, almo_scf_env=almo_scf_env)
189 10 : CPASSERT(ASSOCIATED(mscfg_env))
190 10 : IF (global_almo_scf_keyword) THEN !! Check if smearing is on, and retrieve smearing parameters accordingly
191 10 : smear_almo_scf = qs_env%scf_control%smear%do_smear
192 10 : IF (smear_almo_scf) THEN
193 4 : scf_section => section_vals_get_subs_vals(dft_section, "SCF")
194 4 : CALL section_vals_val_get(scf_section, "added_mos", i_val=tot_added_mos) !! Get total number of added MOs
195 4 : tot_isize = last_atom_of_frag(nfrags) - first_atom_of_frag(1) + 1 !! Get total number of atoms (assume consecutive atoms)
196 : !! Check that number of added MOs matches the number of atoms
197 : !! (to ensure compatibility, since each fragment will be computed with such parameters)
198 4 : IF (tot_isize /= tot_added_mos) THEN
199 0 : CPABORT("ALMO smearing currently requires ADDED_MOS == total number of atoms")
200 : END IF
201 : !! Get total number of MOs
202 4 : CALL get_qs_env(qs_env, mos=mos)
203 4 : IF (SIZE(mos) > 1) CPABORT("Unrestricted ALMO methods are NYI") !! Unrestricted ALMO is not implemented yet
204 4 : CALL get_mo_set(mo_set=mos(1), nmo=nmo)
205 : !! Initialize storage of MO energies for ALMO smearing
206 4 : CPASSERT(ASSOCIATED(almo_scf_env))
207 16 : ALLOCATE (almo_scf_env%mo_energies(nmo, SIZE(mos)))
208 12 : ALLOCATE (almo_scf_env%kTS(SIZE(mos)))
209 12 : nb_eigenval_stored = 0 !! Keep track of how many eigenvalues were stored in mo_energies
210 : END IF
211 : ELSE
212 : smear_almo_scf = .FALSE.
213 : END IF
214 : !
215 : ! These flags determine the options of molecular runs (e.g. cell size)
216 : !
217 : !!!LATER is_fast_dirty = mscfg_env%is_fast_dirty - shrink the cell
218 : !!!LATER is_crystal = mscfg_env%is_crystal - remove periodicity
219 : !
220 : ! Prepare storage for the results
221 : ! Until molecular_scf_guess_env is destroyed it will keep
222 : ! the results of fragment calculations
223 : !
224 10 : CALL molecular_scf_guess_env_init(mscfg_env, nfrags)
225 :
226 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
227 : !
228 : ! Start the loop over molecules
229 : !
230 : ! Here is the list of modifications necessary to run isolated molecules:
231 : ! * Atom list of a subsystem and their names
232 : ! * Charge and multiplicity of a subsystem
233 : ! * ALMO SCF flag off (unless several levels of recursion is desired)
234 : ! * Smaller cell can be provided if a fast-and-dirty approach is ok
235 : ! * Set ADDED_MOS to number of atoms in the fragment, if smearing requested (VASP default)
236 : ! * ... add your own and explain it here ...
237 : !
238 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
239 42 : DO ifrag = 1, nfrags
240 : !
241 : ! Turn ALMO SCF flag off
242 : !
243 32 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=.FALSE.)
244 : !
245 : ! Setup the charge and multiplicity of the molecule
246 : !
247 32 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=charge_of_frag(ifrag))
248 32 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=multip_of_frag(ifrag))
249 : !
250 : ! Create a list of atoms in the current molecule
251 : !
252 : ! Assume that atoms arranged consecutively (in ALMO SCF it is always the case)
253 : ! It is important to have a linear scaling procedure here
254 32 : first_atom = first_atom_of_frag(ifrag)
255 32 : last_atom = last_atom_of_frag(ifrag)
256 32 : isize = last_atom - first_atom + 1
257 96 : ALLOCATE (atom_index(isize))
258 352 : atom_index(1:isize) = [(i, i=first_atom, last_atom)]
259 : !
260 : ! Get atom type names
261 : !
262 96 : ALLOCATE (atom_type(isize))
263 176 : DO j = 1, isize
264 144 : my_targ = atom_index(j)
265 416 : DO k = 1, SIZE(particles%els)
266 416 : CALL get_atomic_kind(particles%els(k)%atomic_kind, atom_list=atom_list, name=name)
267 3658 : IF (ANY(atom_list == my_targ)) EXIT
268 : END DO
269 176 : atom_type(j) = name
270 : END DO
271 : !
272 : ! If smearing requested, setup ADDED_MOS correctly for each fragment (i.e. number of atoms in fragment)
273 : !
274 32 : IF (smear_almo_scf) THEN
275 8 : CALL section_vals_val_set(scf_section, "added_mos", i_val=isize)
276 : END IF
277 : !
278 : ! Create the environment of a subsystem
279 : !
280 : CALL create_small_subsys(subsys_loc, big_subsys=subsys, small_para_env=para_env, &
281 : small_cell=subsys%cell, sub_atom_index=atom_index, &
282 : sub_atom_kind_name=atom_type, para_env=para_env, &
283 32 : force_env_section=force_env_section, subsys_section=subsys_section)
284 32 : ALLOCATE (qs_env_loc)
285 32 : CALL qs_env_create(qs_env_loc, globenv)
286 : CALL qs_init(qs_env_loc, para_env, root_section, globenv=globenv, cp_subsys=subsys_loc, &
287 : force_env_section=force_env_section, subsys_section=subsys_section, &
288 32 : use_motion_section=.FALSE.)
289 32 : CALL cp_subsys_release(subsys_loc)
290 :
291 : !
292 : ! Print-out fragment info
293 : !
294 : CALL print_frag_info(atom_index, atom_type, ifrag, nfrags, &
295 32 : charge_of_frag(ifrag), multip_of_frag(ifrag))
296 : !
297 : ! Run calculations on a subsystem
298 : !
299 32 : CALL qs_energies(qs_env_loc)
300 : !
301 : ! Get the desired results (energy and MOs) out
302 : !
303 32 : CALL get_qs_env(qs_env_loc, mos=mos_of_frag, energy=qs_energy)
304 : !
305 : ! Store all desired results of fragment calculations in the fragment_env
306 : ! of the qs_env to use them later as needed
307 : !
308 32 : mscfg_env%energy_of_frag(ifrag) = qs_energy%total
309 32 : nmosets_of_frag = SIZE(mos_of_frag)
310 32 : CPASSERT(nmosets_of_frag <= mscfg_max_moset_size)
311 32 : mscfg_env%nmosets_of_frag(ifrag) = nmosets_of_frag
312 64 : DO imo = 1, nmosets_of_frag
313 : !! Forcing compatibility for ALMO smearing
314 32 : IF (global_almo_scf_keyword) THEN
315 : !! Manually add compatibility between ALMO SCF and diag SCF (used for smearing compatibility)
316 : !! MOs are required to compute ALMO orbitals, but not stored with diag SCF algorithm...
317 : !! RS-WARNING: Should be properly fixed, this is just a raw fix.
318 : CALL copy_fm_to_dbcsr(mos_of_frag(imo)%mo_coeff, &
319 32 : mos_of_frag(imo)%mo_coeff_b)
320 32 : IF (smear_almo_scf) THEN
321 : !! Store MOs energies for ALMO smearing purpose
322 8 : nmo_of_frag = SIZE(mos_of_frag(imo)%eigenvalues)
323 : almo_scf_env%mo_energies(nb_eigenval_stored + 1:nb_eigenval_stored + nmo_of_frag, imo) &
324 272 : = mos_of_frag(imo)%eigenvalues(:)
325 : !! update stored energies offset. Assumes nmosets_of_frag == 1 (general smearing ALMO assumption)
326 8 : nb_eigenval_stored = nb_eigenval_stored + nmo_of_frag
327 : END IF
328 : END IF !! ALMO
329 :
330 : ! the matrices have been allocated already - copy the results there
331 : CALL dbcsr_create(mscfg_env%mos_of_frag(ifrag, imo), &
332 : template=mos_of_frag(imo)%mo_coeff_b, &
333 32 : matrix_type=dbcsr_type_no_symmetry)
334 : CALL dbcsr_copy(mscfg_env%mos_of_frag(ifrag, imo), &
335 64 : mos_of_frag(imo)%mo_coeff_b)
336 : END DO
337 : !
338 : ! Clean up
339 : !
340 32 : NULLIFY (qs_energy)
341 32 : CALL qs_env_release(qs_env_loc)
342 32 : DEALLOCATE (qs_env_loc)
343 32 : DEALLOCATE (atom_index)
344 74 : DEALLOCATE (atom_type)
345 :
346 : END DO
347 :
348 10 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=global_charge)
349 10 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=global_multpl)
350 10 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
351 :
352 10 : CALL timestop(handle)
353 :
354 10 : END SUBROUTINE calcs_on_isolated_molecules
355 :
356 : ! **************************************************************************************************
357 : !> \brief Print info about fragment
358 : !> \param atom_index ...
359 : !> \param atom_type ...
360 : !> \param frag ...
361 : !> \param nfrags ...
362 : !> \param charge ...
363 : !> \param multpl ...
364 : !> \par History
365 : !> 07.2005 created as a part of BSSE calculations [tlaino]
366 : !> 10.2014 adapted to ALMO guess calculations [Rustam Z Khaliullin]
367 : !> \author Rustam Z Khaliullin
368 : ! **************************************************************************************************
369 32 : SUBROUTINE print_frag_info(atom_index, atom_type, frag, nfrags, charge, &
370 : multpl)
371 :
372 : INTEGER, DIMENSION(:), POINTER :: atom_index
373 : CHARACTER(len=default_string_length), &
374 : DIMENSION(:), POINTER :: atom_type
375 : INTEGER, INTENT(IN) :: frag, nfrags, charge, multpl
376 :
377 : CHARACTER(len=11) :: charI
378 : INTEGER :: i, iw
379 : TYPE(cp_logger_type), POINTER :: logger
380 :
381 32 : NULLIFY (logger)
382 32 : logger => cp_get_default_logger()
383 32 : IF (logger%para_env%is_source()) THEN
384 16 : iw = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
385 : ELSE
386 : iw = -1
387 : END IF
388 :
389 16 : IF (iw > 0) THEN
390 :
391 16 : WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
392 16 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
393 : WRITE (UNIT=iw, FMT="(T2,A,T5,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") &
394 16 : "-", "MOLECULAR GUESS:", "FRAGMENT", frag, "OUT OF", nfrags, "-"
395 16 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") "-", "CHARGE", charge, "MULTIPLICITY", &
396 32 : multpl, "-"
397 16 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
398 16 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "ATOM INDEX", "ATOM NAME", "-"
399 16 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "----------", "---------", "-"
400 88 : DO i = 1, SIZE(atom_index)
401 72 : WRITE (charI, '(I11)') atom_index(i)
402 88 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", ADJUSTL(charI), TRIM(atom_type(i)), "-"
403 : END DO
404 16 : WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
405 : END IF
406 :
407 32 : END SUBROUTINE print_frag_info
408 :
409 : ! **************************************************************************************************
410 : !> \brief Is the loop over molecules requested?
411 : !> \param force_env ...
412 : !> \return ...
413 : !> \par History
414 : !> 10.2014 created [Rustam Z. Khaliullin]
415 : !> \author Rustam Z. Khaliullin
416 : ! **************************************************************************************************
417 10572 : FUNCTION do_mol_loop(force_env)
418 :
419 : TYPE(force_env_type), POINTER :: force_env
420 : LOGICAL :: do_mol_loop
421 :
422 : INTEGER :: almo_guess_type, frz_term_type, &
423 : method_name_id, scf_guess_type
424 : LOGICAL :: almo_scf_is_on, is_crystal, is_fast_dirty
425 : TYPE(molecular_scf_guess_env_type), POINTER :: mscfg_env
426 : TYPE(qs_environment_type), POINTER :: qs_env
427 : TYPE(section_vals_type), POINTER :: force_env_section, subsection
428 :
429 5286 : do_mol_loop = .FALSE.
430 : ! What kind of options are we using in the loop ?
431 5286 : is_fast_dirty = .TRUE.
432 5286 : is_crystal = .FALSE.
433 5286 : almo_scf_is_on = .FALSE.
434 :
435 5286 : NULLIFY (qs_env, mscfg_env, force_env_section, subsection)
436 5286 : CALL force_env_get(force_env, force_env_section=force_env_section)
437 5286 : CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
438 :
439 5286 : IF (method_name_id == do_qs) THEN
440 :
441 4604 : CALL force_env_get(force_env, qs_env=qs_env)
442 4604 : CPASSERT(ASSOCIATED(qs_env))
443 :
444 4604 : CALL get_qs_env(qs_env, mscfg_env=mscfg_env)
445 4604 : CPASSERT(ASSOCIATED(mscfg_env))
446 :
447 : !!!! RZK-warning: All decisions are based on the values of input keywords
448 : !!!! The real danger is that many of these keywords might not be even
449 : !!!! in control of the job. They might be simply present in the input
450 : !!!! This section must be re-written more accurately
451 :
452 : ! check ALMO SCF guess option
453 4604 : NULLIFY (subsection)
454 4604 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%ALMO_SCF")
455 4604 : CALL section_vals_val_get(subsection, "ALMO_SCF_GUESS", i_val=almo_guess_type)
456 : ! check whether ALMO SCF is on
457 4604 : NULLIFY (subsection)
458 4604 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%QS")
459 4604 : CALL section_vals_val_get(subsection, "ALMO_SCF", l_val=almo_scf_is_on)
460 :
461 : ! check SCF guess option
462 4604 : NULLIFY (subsection)
463 4604 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%SCF")
464 4604 : CALL section_vals_val_get(subsection, "SCF_GUESS", i_val=scf_guess_type)
465 :
466 : ! check ALMO EDA options
467 4604 : NULLIFY (subsection)
468 : !!!LATER subsection => section_vals_get_subs_vals(force_env_section,"DFT%ALMO_SCF%ALMO_DA")
469 : !!!LATER CALL section_vals_val_get(subsection,"FRZ_TERM",i_val=frz_term_type)
470 4604 : frz_term_type = almo_frz_none
471 :
472 : ! Are we doing the loop ?
473 : IF (scf_guess_type == molecular_guess .OR. & ! SCF guess is molecular
474 4604 : (almo_guess_type == molecular_guess .AND. almo_scf_is_on) .OR. & ! ALMO SCF guess is molecular
475 : frz_term_type /= almo_frz_none) THEN ! ALMO FRZ term is requested
476 :
477 10 : do_mol_loop = .TRUE.
478 :
479 : ! If we are calculating molecular guess it is OK to do fast and dirty loop
480 : ! It is NOT ok to be sloppy with ALMO EDA calculations of the FRZ term
481 : IF (frz_term_type /= almo_frz_none) THEN
482 : is_fast_dirty = .FALSE.
483 : IF (frz_term_type == almo_frz_crystal) THEN
484 : is_crystal = .TRUE.
485 : END IF
486 : END IF
487 :
488 : END IF
489 :
490 4604 : mscfg_env%is_fast_dirty = is_fast_dirty
491 4604 : mscfg_env%is_crystal = is_crystal
492 :
493 : END IF
494 :
495 : RETURN
496 :
497 : END FUNCTION do_mol_loop
498 :
499 : END MODULE mscfg_methods
500 :
|