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 16 : 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 16 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
88 : TYPE(qs_environment_type), POINTER :: qs_env
89 :
90 16 : CALL force_env_get(force_env, qs_env=qs_env)
91 16 : CPASSERT(ASSOCIATED(qs_env))
92 : CALL get_qs_env(qs_env, &
93 16 : molecule_set=molecule_set)
94 :
95 16 : nmols = SIZE(molecule_set)
96 :
97 48 : ALLOCATE (first_atom_of_frag(nmols))
98 32 : ALLOCATE (last_atom_of_frag(nmols))
99 32 : ALLOCATE (charge_of_frag(nmols))
100 32 : 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 16 : mol_to_multiplicity=multip_of_frag)
107 :
108 : CALL calcs_on_isolated_molecules(force_env, globenv, nmols, &
109 16 : first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
110 :
111 16 : DEALLOCATE (first_atom_of_frag)
112 16 : DEALLOCATE (last_atom_of_frag)
113 16 : DEALLOCATE (charge_of_frag)
114 16 : DEALLOCATE (multip_of_frag)
115 :
116 16 : 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 96 : SUBROUTINE calcs_on_isolated_molecules(force_env, globenv, nfrags, &
134 16 : 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(INOUT) :: 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 16 : 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 16 : 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 16 : 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 16 : CALL timeset(routineN, handle)
165 :
166 16 : NULLIFY (subsys_loc, subsys, particles, para_env, atom_index, atom_type, &
167 16 : 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 16 : qs_env=qs_env)
170 16 : CALL section_vals_val_get(force_env_section, "METHOD", i_val=force_method)
171 16 : CPASSERT(force_method == do_qs)
172 16 : root_section => force_env%root_section
173 16 : subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
174 16 : 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 16 : CALL section_vals_val_get(dft_section, "CHARGE", i_val=global_charge)
180 16 : CALL section_vals_val_get(dft_section, "MULTIPLICITY", i_val=global_multpl)
181 16 : qs_section => section_vals_get_subs_vals(dft_section, "QS")
182 16 : 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 16 : CALL force_env_get(force_env=force_env, subsys=subsys, para_env=para_env)
187 16 : CALL cp_subsys_get(subsys, particles=particles)
188 16 : CALL get_qs_env(qs_env, mscfg_env=mscfg_env, almo_scf_env=almo_scf_env)
189 16 : CPASSERT(ASSOCIATED(mscfg_env))
190 16 : IF (global_almo_scf_keyword) THEN !! Check if smearing is on, and retrieve smearing parameters accordingly
191 16 : smear_almo_scf = qs_env%scf_control%smear%do_smear
192 16 : IF (smear_almo_scf) THEN
193 4 : scf_section => section_vals_get_subs_vals(dft_section, "SCF")
194 : !! Get total number of added MOs
195 4 : CALL section_vals_val_get(scf_section, "added_mos", i_val=tot_added_mos)
196 : !! Get total number of atoms (assume consecutive atoms)
197 4 : tot_isize = last_atom_of_frag(nfrags) - first_atom_of_frag(1) + 1
198 : !! Check that number of added MOs matches the number of atoms
199 : !! (to ensure compatibility, since each fragment will be computed with such parameters)
200 4 : IF (tot_isize /= tot_added_mos) THEN
201 0 : CPABORT("ALMO smearing currently requires ADDED_MOS == total number of atoms")
202 : END IF
203 : !! Get total number of MOs
204 4 : CALL get_qs_env(qs_env, mos=mos)
205 : !! Unrestricted ALMO is not implemented yet
206 4 : IF (SIZE(mos) > 1) CPABORT("Unrestricted ALMO methods are NYI")
207 4 : CALL get_mo_set(mo_set=mos(1), nmo=nmo)
208 : !! Initialize storage of MO energies for ALMO smearing
209 4 : CPASSERT(ASSOCIATED(almo_scf_env))
210 16 : ALLOCATE (almo_scf_env%mo_energies(nmo, SIZE(mos)))
211 12 : ALLOCATE (almo_scf_env%kTS(SIZE(mos)))
212 12 : nb_eigenval_stored = 0 !! Keep track of how many eigenvalues were stored in mo_energies
213 : END IF
214 : ELSE
215 : smear_almo_scf = .FALSE.
216 : END IF
217 : !
218 : ! These flags determine the options of molecular runs (e.g. cell size)
219 : !
220 : !!!LATER is_fast_dirty = mscfg_env%is_fast_dirty - shrink the cell
221 : !!!LATER is_crystal = mscfg_env%is_crystal - remove periodicity
222 : !
223 : ! Prepare storage for the results
224 : ! Until molecular_scf_guess_env is destroyed it will keep
225 : ! the results of fragment calculations
226 : !
227 16 : CALL molecular_scf_guess_env_init(mscfg_env, nfrags)
228 :
229 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
230 : !
231 : ! Start the loop over molecules
232 : !
233 : ! Here is the list of modifications necessary to run isolated molecules:
234 : ! * Atom list of a subsystem and their names
235 : ! * Charge and multiplicity of a subsystem
236 : ! * ALMO SCF flag off (unless several levels of recursion is desired)
237 : ! * Smaller cell can be provided if a fast-and-dirty approach is ok
238 : ! * Set ADDED_MOS to number of atoms in the fragment, if smearing requested (VASP default)
239 : ! * ... add your own and explain it here ...
240 : !
241 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
242 60 : DO ifrag = 1, nfrags
243 : !
244 : ! Turn ALMO SCF flag off
245 : !
246 44 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=.FALSE.)
247 : !
248 : ! Setup the charge and multiplicity of the molecule
249 : !
250 :
251 44 : IF (almo_scf_env%activate(1) == 1) THEN
252 12 : multip_of_frag(ifrag) = almo_scf_env%multiplicity_of_domain(ifrag)
253 12 : charge_of_frag(ifrag) = almo_scf_env%charge_of_domain(ifrag)
254 : ELSE
255 32 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=charge_of_frag(ifrag))
256 32 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=multip_of_frag(ifrag))
257 : END IF
258 :
259 : !
260 : ! Create a list of atoms in the current molecule
261 : !
262 : ! Assume that atoms arranged consecutively (in ALMO SCF it is always the case)
263 : ! It is important to have a linear scaling procedure here
264 44 : first_atom = first_atom_of_frag(ifrag)
265 44 : last_atom = last_atom_of_frag(ifrag)
266 44 : isize = last_atom - first_atom + 1
267 132 : ALLOCATE (atom_index(isize))
268 432 : atom_index(1:isize) = [(i, i=first_atom, last_atom)]
269 : !
270 : ! Get atom type names
271 : !
272 132 : ALLOCATE (atom_type(isize))
273 216 : DO j = 1, isize
274 172 : my_targ = atom_index(j)
275 462 : DO k = 1, SIZE(particles%els)
276 462 : CALL get_atomic_kind(particles%els(k)%atomic_kind, atom_list=atom_list, name=name)
277 3768 : IF (ANY(atom_list == my_targ)) EXIT
278 : END DO
279 216 : atom_type(j) = name
280 : END DO
281 : !
282 : ! If smearing requested, setup ADDED_MOS correctly for each fragment (i.e. number of atoms in fragment)
283 : !
284 44 : IF (smear_almo_scf) THEN
285 8 : CALL section_vals_val_set(scf_section, "added_mos", i_val=isize)
286 : END IF
287 : !
288 : ! Create the environment of a subsystem
289 : !
290 : CALL create_small_subsys(subsys_loc, big_subsys=subsys, small_para_env=para_env, &
291 : small_cell=subsys%cell, sub_atom_index=atom_index, &
292 : sub_atom_kind_name=atom_type, para_env=para_env, &
293 44 : force_env_section=force_env_section, subsys_section=subsys_section)
294 44 : ALLOCATE (qs_env_loc)
295 44 : CALL qs_env_create(qs_env_loc, globenv)
296 : CALL qs_init(qs_env_loc, para_env, root_section, globenv=globenv, cp_subsys=subsys_loc, &
297 : force_env_section=force_env_section, subsys_section=subsys_section, &
298 44 : use_motion_section=.FALSE., multip=multip_of_frag(ifrag), charge=charge_of_frag(ifrag))
299 44 : CALL cp_subsys_release(subsys_loc)
300 :
301 : !
302 : ! Print-out fragment info
303 : !
304 : CALL print_frag_info(atom_index, atom_type, ifrag, nfrags, &
305 44 : charge_of_frag(ifrag), multip_of_frag(ifrag))
306 : !
307 : ! Run calculations on a subsystem
308 : !
309 44 : CALL qs_energies(qs_env_loc)
310 : !
311 : ! Get the desired results (energy and MOs) out
312 : !
313 44 : CALL get_qs_env(qs_env_loc, mos=mos_of_frag, energy=qs_energy)
314 : !
315 : ! Store all desired results of fragment calculations in the fragment_env
316 : ! of the qs_env to use them later as needed
317 : !
318 44 : mscfg_env%energy_of_frag(ifrag) = qs_energy%total
319 44 : nmosets_of_frag = SIZE(mos_of_frag)
320 44 : CPASSERT(nmosets_of_frag <= mscfg_max_moset_size)
321 44 : mscfg_env%nmosets_of_frag(ifrag) = nmosets_of_frag
322 100 : DO imo = 1, nmosets_of_frag
323 : !! Forcing compatibility for ALMO smearing
324 56 : IF (global_almo_scf_keyword) THEN
325 : !! Manually add compatibility between ALMO SCF and diag SCF (used for smearing compatibility)
326 : !! MOs are required to compute ALMO orbitals, but not stored with diag SCF algorithm...
327 : !! RS-WARNING: Should be properly fixed, this is just a raw fix.
328 : CALL copy_fm_to_dbcsr(mos_of_frag(imo)%mo_coeff, &
329 56 : mos_of_frag(imo)%mo_coeff_b)
330 56 : IF (smear_almo_scf) THEN
331 : !! Store MOs energies for ALMO smearing purpose
332 8 : nmo_of_frag = SIZE(mos_of_frag(imo)%eigenvalues)
333 : almo_scf_env%mo_energies(nb_eigenval_stored + 1:nb_eigenval_stored + nmo_of_frag, imo) &
334 272 : = mos_of_frag(imo)%eigenvalues(:)
335 : !! update stored energies offset. Assumes nmosets_of_frag == 1 (general smearing ALMO assumption)
336 8 : nb_eigenval_stored = nb_eigenval_stored + nmo_of_frag
337 : END IF
338 : END IF !! ALMO
339 :
340 : ! the matrices have been allocated already - copy the results there
341 : CALL dbcsr_create(mscfg_env%mos_of_frag(ifrag, imo), &
342 : template=mos_of_frag(imo)%mo_coeff_b, &
343 56 : matrix_type=dbcsr_type_no_symmetry)
344 : CALL dbcsr_copy(mscfg_env%mos_of_frag(ifrag, imo), &
345 100 : mos_of_frag(imo)%mo_coeff_b)
346 : END DO
347 : !
348 : ! Clean up
349 : !
350 44 : NULLIFY (qs_energy)
351 44 : CALL qs_env_release(qs_env_loc)
352 44 : DEALLOCATE (qs_env_loc)
353 44 : DEALLOCATE (atom_index)
354 104 : DEALLOCATE (atom_type)
355 :
356 : END DO
357 :
358 16 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=global_charge)
359 16 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=global_multpl)
360 16 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
361 :
362 16 : CALL timestop(handle)
363 :
364 16 : END SUBROUTINE calcs_on_isolated_molecules
365 :
366 : ! **************************************************************************************************
367 : !> \brief Print info about fragment
368 : !> \param atom_index ...
369 : !> \param atom_type ...
370 : !> \param frag ...
371 : !> \param nfrags ...
372 : !> \param charge ...
373 : !> \param multpl ...
374 : !> \par History
375 : !> 07.2005 created as a part of BSSE calculations [tlaino]
376 : !> 10.2014 adapted to ALMO guess calculations [Rustam Z Khaliullin]
377 : !> \author Rustam Z Khaliullin
378 : ! **************************************************************************************************
379 44 : SUBROUTINE print_frag_info(atom_index, atom_type, frag, nfrags, charge, &
380 : multpl)
381 :
382 : INTEGER, DIMENSION(:), POINTER :: atom_index
383 : CHARACTER(len=default_string_length), &
384 : DIMENSION(:), POINTER :: atom_type
385 : INTEGER, INTENT(IN) :: frag, nfrags, charge, multpl
386 :
387 : CHARACTER(len=11) :: charI
388 : INTEGER :: i, iw
389 : TYPE(cp_logger_type), POINTER :: logger
390 :
391 44 : NULLIFY (logger)
392 44 : logger => cp_get_default_logger()
393 44 : IF (logger%para_env%is_source()) THEN
394 22 : iw = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
395 : ELSE
396 : iw = -1
397 : END IF
398 :
399 22 : IF (iw > 0) THEN
400 :
401 22 : WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
402 22 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
403 : WRITE (UNIT=iw, FMT="(T2,A,T5,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") &
404 22 : "-", "MOLECULAR GUESS:", "FRAGMENT", frag, "OUT OF", nfrags, "-"
405 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") "-", "CHARGE", charge, "MULTIPLICITY", &
406 44 : multpl, "-"
407 22 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
408 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "ATOM INDEX", "ATOM NAME", "-"
409 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "----------", "---------", "-"
410 108 : DO i = 1, SIZE(atom_index)
411 86 : WRITE (charI, '(I11)') atom_index(i)
412 108 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", ADJUSTL(charI), TRIM(atom_type(i)), "-"
413 : END DO
414 22 : WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
415 : END IF
416 :
417 44 : END SUBROUTINE print_frag_info
418 :
419 : ! **************************************************************************************************
420 : !> \brief Is the loop over molecules requested?
421 : !> \param force_env ...
422 : !> \return ...
423 : !> \par History
424 : !> 10.2014 created [Rustam Z. Khaliullin]
425 : !> \author Rustam Z. Khaliullin
426 : ! **************************************************************************************************
427 11872 : FUNCTION do_mol_loop(force_env)
428 :
429 : TYPE(force_env_type), POINTER :: force_env
430 : LOGICAL :: do_mol_loop
431 :
432 : INTEGER :: almo_guess_type, frz_term_type, &
433 : method_name_id, scf_guess_type
434 : LOGICAL :: almo_scf_is_on, is_crystal, is_fast_dirty
435 : TYPE(molecular_scf_guess_env_type), POINTER :: mscfg_env
436 : TYPE(qs_environment_type), POINTER :: qs_env
437 : TYPE(section_vals_type), POINTER :: force_env_section, subsection
438 :
439 5936 : do_mol_loop = .FALSE.
440 : ! What kind of options are we using in the loop ?
441 5936 : is_fast_dirty = .TRUE.
442 5936 : is_crystal = .FALSE.
443 : almo_scf_is_on = .FALSE.
444 :
445 5936 : NULLIFY (qs_env, mscfg_env, force_env_section, subsection)
446 5936 : CALL force_env_get(force_env, force_env_section=force_env_section)
447 5936 : CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
448 :
449 5936 : IF (method_name_id == do_qs) THEN
450 :
451 5244 : CALL force_env_get(force_env, qs_env=qs_env)
452 5244 : CPASSERT(ASSOCIATED(qs_env))
453 :
454 5244 : CALL get_qs_env(qs_env, mscfg_env=mscfg_env)
455 5244 : CPASSERT(ASSOCIATED(mscfg_env))
456 :
457 : !!!! RZK-warning: All decisions are based on the values of input keywords
458 : !!!! The real danger is that many of these keywords might not be even
459 : !!!! in control of the job. They might be simply present in the input
460 : !!!! This section must be re-written more accurately
461 :
462 : ! check ALMO SCF guess option
463 5244 : NULLIFY (subsection)
464 5244 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%ALMO_SCF")
465 5244 : CALL section_vals_val_get(subsection, "ALMO_SCF_GUESS", i_val=almo_guess_type)
466 : ! check whether ALMO SCF is on
467 5244 : NULLIFY (subsection)
468 5244 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%QS")
469 5244 : CALL section_vals_val_get(subsection, "ALMO_SCF", l_val=almo_scf_is_on)
470 :
471 : ! check SCF guess option
472 5244 : NULLIFY (subsection)
473 5244 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%SCF")
474 5244 : CALL section_vals_val_get(subsection, "SCF_GUESS", i_val=scf_guess_type)
475 :
476 : ! check ALMO EDA options
477 5244 : NULLIFY (subsection)
478 : !!!LATER subsection => section_vals_get_subs_vals(force_env_section,"DFT%ALMO_SCF%ALMO_DA")
479 : !!!LATER CALL section_vals_val_get(subsection,"FRZ_TERM",i_val=frz_term_type)
480 5244 : frz_term_type = almo_frz_none
481 :
482 : ! Are we doing the loop ?
483 : IF (scf_guess_type == molecular_guess .OR. & ! SCF guess is molecular
484 5244 : (almo_guess_type == molecular_guess .AND. almo_scf_is_on) .OR. & ! ALMO SCF guess is molecular
485 : frz_term_type /= almo_frz_none) THEN ! ALMO FRZ term is requested
486 :
487 16 : do_mol_loop = .TRUE.
488 :
489 : ! If we are calculating molecular guess it is OK to do fast and dirty loop
490 : ! It is NOT ok to be sloppy with ALMO EDA calculations of the FRZ term
491 : IF (frz_term_type /= almo_frz_none) THEN
492 : is_fast_dirty = .FALSE.
493 : IF (frz_term_type == almo_frz_crystal) THEN
494 : is_crystal = .TRUE.
495 : END IF
496 : END IF
497 :
498 : END IF
499 :
500 5244 : mscfg_env%is_fast_dirty = is_fast_dirty
501 5244 : mscfg_env%is_crystal = is_crystal
502 :
503 : END IF
504 :
505 : RETURN
506 :
507 : END FUNCTION do_mol_loop
508 :
509 : END MODULE mscfg_methods
510 :
|