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 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 16 : 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 60 : DO ifrag = 1, nfrags
240 : !
241 : ! Turn ALMO SCF flag off
242 : !
243 44 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=.FALSE.)
244 : !
245 : ! Setup the charge and multiplicity of the molecule
246 : !
247 :
248 44 : IF (almo_scf_env%activate(1) == 1) THEN
249 12 : multip_of_frag(ifrag) = almo_scf_env%multiplicity_of_domain(ifrag)
250 12 : charge_of_frag(ifrag) = almo_scf_env%charge_of_domain(ifrag)
251 : ELSE
252 32 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=charge_of_frag(ifrag))
253 32 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=multip_of_frag(ifrag))
254 : END IF
255 :
256 : !
257 : ! Create a list of atoms in the current molecule
258 : !
259 : ! Assume that atoms arranged consecutively (in ALMO SCF it is always the case)
260 : ! It is important to have a linear scaling procedure here
261 44 : first_atom = first_atom_of_frag(ifrag)
262 44 : last_atom = last_atom_of_frag(ifrag)
263 44 : isize = last_atom - first_atom + 1
264 132 : ALLOCATE (atom_index(isize))
265 432 : atom_index(1:isize) = [(i, i=first_atom, last_atom)]
266 : !
267 : ! Get atom type names
268 : !
269 132 : ALLOCATE (atom_type(isize))
270 216 : DO j = 1, isize
271 172 : my_targ = atom_index(j)
272 462 : DO k = 1, SIZE(particles%els)
273 462 : CALL get_atomic_kind(particles%els(k)%atomic_kind, atom_list=atom_list, name=name)
274 3768 : IF (ANY(atom_list == my_targ)) EXIT
275 : END DO
276 216 : atom_type(j) = name
277 : END DO
278 : !
279 : ! If smearing requested, setup ADDED_MOS correctly for each fragment (i.e. number of atoms in fragment)
280 : !
281 44 : IF (smear_almo_scf) THEN
282 8 : CALL section_vals_val_set(scf_section, "added_mos", i_val=isize)
283 : END IF
284 : !
285 : ! Create the environment of a subsystem
286 : !
287 : CALL create_small_subsys(subsys_loc, big_subsys=subsys, small_para_env=para_env, &
288 : small_cell=subsys%cell, sub_atom_index=atom_index, &
289 : sub_atom_kind_name=atom_type, para_env=para_env, &
290 44 : force_env_section=force_env_section, subsys_section=subsys_section)
291 44 : ALLOCATE (qs_env_loc)
292 44 : CALL qs_env_create(qs_env_loc, globenv)
293 : CALL qs_init(qs_env_loc, para_env, root_section, globenv=globenv, cp_subsys=subsys_loc, &
294 : force_env_section=force_env_section, subsys_section=subsys_section, &
295 44 : use_motion_section=.FALSE., multip=multip_of_frag(ifrag), charge=charge_of_frag(ifrag))
296 44 : CALL cp_subsys_release(subsys_loc)
297 :
298 : !
299 : ! Print-out fragment info
300 : !
301 : CALL print_frag_info(atom_index, atom_type, ifrag, nfrags, &
302 44 : charge_of_frag(ifrag), multip_of_frag(ifrag))
303 : !
304 : ! Run calculations on a subsystem
305 : !
306 44 : CALL qs_energies(qs_env_loc)
307 : !
308 : ! Get the desired results (energy and MOs) out
309 : !
310 44 : CALL get_qs_env(qs_env_loc, mos=mos_of_frag, energy=qs_energy)
311 : !
312 : ! Store all desired results of fragment calculations in the fragment_env
313 : ! of the qs_env to use them later as needed
314 : !
315 44 : mscfg_env%energy_of_frag(ifrag) = qs_energy%total
316 44 : nmosets_of_frag = SIZE(mos_of_frag)
317 44 : CPASSERT(nmosets_of_frag <= mscfg_max_moset_size)
318 44 : mscfg_env%nmosets_of_frag(ifrag) = nmosets_of_frag
319 100 : DO imo = 1, nmosets_of_frag
320 : !! Forcing compatibility for ALMO smearing
321 56 : IF (global_almo_scf_keyword) THEN
322 : !! Manually add compatibility between ALMO SCF and diag SCF (used for smearing compatibility)
323 : !! MOs are required to compute ALMO orbitals, but not stored with diag SCF algorithm...
324 : !! RS-WARNING: Should be properly fixed, this is just a raw fix.
325 : CALL copy_fm_to_dbcsr(mos_of_frag(imo)%mo_coeff, &
326 56 : mos_of_frag(imo)%mo_coeff_b)
327 56 : IF (smear_almo_scf) THEN
328 : !! Store MOs energies for ALMO smearing purpose
329 8 : nmo_of_frag = SIZE(mos_of_frag(imo)%eigenvalues)
330 : almo_scf_env%mo_energies(nb_eigenval_stored + 1:nb_eigenval_stored + nmo_of_frag, imo) &
331 272 : = mos_of_frag(imo)%eigenvalues(:)
332 : !! update stored energies offset. Assumes nmosets_of_frag == 1 (general smearing ALMO assumption)
333 8 : nb_eigenval_stored = nb_eigenval_stored + nmo_of_frag
334 : END IF
335 : END IF !! ALMO
336 :
337 : ! the matrices have been allocated already - copy the results there
338 : CALL dbcsr_create(mscfg_env%mos_of_frag(ifrag, imo), &
339 : template=mos_of_frag(imo)%mo_coeff_b, &
340 56 : matrix_type=dbcsr_type_no_symmetry)
341 : CALL dbcsr_copy(mscfg_env%mos_of_frag(ifrag, imo), &
342 100 : mos_of_frag(imo)%mo_coeff_b)
343 : END DO
344 : !
345 : ! Clean up
346 : !
347 44 : NULLIFY (qs_energy)
348 44 : CALL qs_env_release(qs_env_loc)
349 44 : DEALLOCATE (qs_env_loc)
350 44 : DEALLOCATE (atom_index)
351 104 : DEALLOCATE (atom_type)
352 :
353 : END DO
354 :
355 16 : CALL section_vals_val_set(dft_section, "CHARGE", i_val=global_charge)
356 16 : CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=global_multpl)
357 16 : CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
358 :
359 16 : CALL timestop(handle)
360 :
361 16 : END SUBROUTINE calcs_on_isolated_molecules
362 :
363 : ! **************************************************************************************************
364 : !> \brief Print info about fragment
365 : !> \param atom_index ...
366 : !> \param atom_type ...
367 : !> \param frag ...
368 : !> \param nfrags ...
369 : !> \param charge ...
370 : !> \param multpl ...
371 : !> \par History
372 : !> 07.2005 created as a part of BSSE calculations [tlaino]
373 : !> 10.2014 adapted to ALMO guess calculations [Rustam Z Khaliullin]
374 : !> \author Rustam Z Khaliullin
375 : ! **************************************************************************************************
376 44 : SUBROUTINE print_frag_info(atom_index, atom_type, frag, nfrags, charge, &
377 : multpl)
378 :
379 : INTEGER, DIMENSION(:), POINTER :: atom_index
380 : CHARACTER(len=default_string_length), &
381 : DIMENSION(:), POINTER :: atom_type
382 : INTEGER, INTENT(IN) :: frag, nfrags, charge, multpl
383 :
384 : CHARACTER(len=11) :: charI
385 : INTEGER :: i, iw
386 : TYPE(cp_logger_type), POINTER :: logger
387 :
388 44 : NULLIFY (logger)
389 44 : logger => cp_get_default_logger()
390 44 : IF (logger%para_env%is_source()) THEN
391 22 : iw = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
392 : ELSE
393 : iw = -1
394 : END IF
395 :
396 22 : IF (iw > 0) THEN
397 :
398 22 : WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
399 22 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
400 : WRITE (UNIT=iw, FMT="(T2,A,T5,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") &
401 22 : "-", "MOLECULAR GUESS:", "FRAGMENT", frag, "OUT OF", nfrags, "-"
402 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") "-", "CHARGE", charge, "MULTIPLICITY", &
403 44 : multpl, "-"
404 22 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
405 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "ATOM INDEX", "ATOM NAME", "-"
406 22 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "----------", "---------", "-"
407 108 : DO i = 1, SIZE(atom_index)
408 86 : WRITE (charI, '(I11)') atom_index(i)
409 108 : WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", ADJUSTL(charI), TRIM(atom_type(i)), "-"
410 : END DO
411 22 : WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
412 : END IF
413 :
414 44 : END SUBROUTINE print_frag_info
415 :
416 : ! **************************************************************************************************
417 : !> \brief Is the loop over molecules requested?
418 : !> \param force_env ...
419 : !> \return ...
420 : !> \par History
421 : !> 10.2014 created [Rustam Z. Khaliullin]
422 : !> \author Rustam Z. Khaliullin
423 : ! **************************************************************************************************
424 11692 : FUNCTION do_mol_loop(force_env)
425 :
426 : TYPE(force_env_type), POINTER :: force_env
427 : LOGICAL :: do_mol_loop
428 :
429 : INTEGER :: almo_guess_type, frz_term_type, &
430 : method_name_id, scf_guess_type
431 : LOGICAL :: almo_scf_is_on, is_crystal, is_fast_dirty
432 : TYPE(molecular_scf_guess_env_type), POINTER :: mscfg_env
433 : TYPE(qs_environment_type), POINTER :: qs_env
434 : TYPE(section_vals_type), POINTER :: force_env_section, subsection
435 :
436 5846 : do_mol_loop = .FALSE.
437 : ! What kind of options are we using in the loop ?
438 5846 : is_fast_dirty = .TRUE.
439 5846 : is_crystal = .FALSE.
440 : almo_scf_is_on = .FALSE.
441 :
442 5846 : NULLIFY (qs_env, mscfg_env, force_env_section, subsection)
443 5846 : CALL force_env_get(force_env, force_env_section=force_env_section)
444 5846 : CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
445 :
446 5846 : IF (method_name_id == do_qs) THEN
447 :
448 5156 : CALL force_env_get(force_env, qs_env=qs_env)
449 5156 : CPASSERT(ASSOCIATED(qs_env))
450 :
451 5156 : CALL get_qs_env(qs_env, mscfg_env=mscfg_env)
452 5156 : CPASSERT(ASSOCIATED(mscfg_env))
453 :
454 : !!!! RZK-warning: All decisions are based on the values of input keywords
455 : !!!! The real danger is that many of these keywords might not be even
456 : !!!! in control of the job. They might be simply present in the input
457 : !!!! This section must be re-written more accurately
458 :
459 : ! check ALMO SCF guess option
460 5156 : NULLIFY (subsection)
461 5156 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%ALMO_SCF")
462 5156 : CALL section_vals_val_get(subsection, "ALMO_SCF_GUESS", i_val=almo_guess_type)
463 : ! check whether ALMO SCF is on
464 5156 : NULLIFY (subsection)
465 5156 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%QS")
466 5156 : CALL section_vals_val_get(subsection, "ALMO_SCF", l_val=almo_scf_is_on)
467 :
468 : ! check SCF guess option
469 5156 : NULLIFY (subsection)
470 5156 : subsection => section_vals_get_subs_vals(force_env_section, "DFT%SCF")
471 5156 : CALL section_vals_val_get(subsection, "SCF_GUESS", i_val=scf_guess_type)
472 :
473 : ! check ALMO EDA options
474 5156 : NULLIFY (subsection)
475 : !!!LATER subsection => section_vals_get_subs_vals(force_env_section,"DFT%ALMO_SCF%ALMO_DA")
476 : !!!LATER CALL section_vals_val_get(subsection,"FRZ_TERM",i_val=frz_term_type)
477 5156 : frz_term_type = almo_frz_none
478 :
479 : ! Are we doing the loop ?
480 : IF (scf_guess_type == molecular_guess .OR. & ! SCF guess is molecular
481 5156 : (almo_guess_type == molecular_guess .AND. almo_scf_is_on) .OR. & ! ALMO SCF guess is molecular
482 : frz_term_type /= almo_frz_none) THEN ! ALMO FRZ term is requested
483 :
484 16 : do_mol_loop = .TRUE.
485 :
486 : ! If we are calculating molecular guess it is OK to do fast and dirty loop
487 : ! It is NOT ok to be sloppy with ALMO EDA calculations of the FRZ term
488 : IF (frz_term_type /= almo_frz_none) THEN
489 : is_fast_dirty = .FALSE.
490 : IF (frz_term_type == almo_frz_crystal) THEN
491 : is_crystal = .TRUE.
492 : END IF
493 : END IF
494 :
495 : END IF
496 :
497 5156 : mscfg_env%is_fast_dirty = is_fast_dirty
498 5156 : mscfg_env%is_crystal = is_crystal
499 :
500 : END IF
501 :
502 : RETURN
503 :
504 : END FUNCTION do_mol_loop
505 :
506 : END MODULE mscfg_methods
507 :
|