Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : MODULE atom_energy
9 : USE atom_admm_methods, ONLY: atom_admm
10 : USE atom_electronic_structure, ONLY: calculate_atom
11 : USE atom_fit, ONLY: atom_fit_density,&
12 : atom_fit_kgpot
13 : USE atom_grb, ONLY: atom_grb_construction
14 : USE atom_operators, ONLY: atom_int_release,&
15 : atom_int_setup,&
16 : atom_ppint_release,&
17 : atom_ppint_setup,&
18 : atom_relint_release,&
19 : atom_relint_setup
20 : USE atom_output, ONLY: atom_print_basis,&
21 : atom_print_info,&
22 : atom_print_method,&
23 : atom_print_orbitals,&
24 : atom_print_potential,&
25 : atom_write_pseudo_param
26 : USE atom_sgp, ONLY: atom_sgp_construction
27 : USE atom_types, ONLY: &
28 : atom_basis_type, atom_gthpot_type, atom_integrals, atom_optimization_type, atom_orbitals, &
29 : atom_p_type, atom_potential_type, atom_state, atom_type, create_atom_orbs, &
30 : create_atom_type, gth_pseudo, init_atom_basis, init_atom_potential, lmat, &
31 : read_atom_opt_section, release_atom_basis, release_atom_potential, release_atom_type, &
32 : set_atom
33 : USE atom_utils, ONLY: &
34 : atom_completeness, atom_condnumber, atom_consistent_method, atom_core_density, &
35 : atom_density, atom_local_potential, atom_read_external_density, atom_read_external_vxc, &
36 : atom_set_occupation, atom_write_zmp_restart, get_maxl_occ, get_maxn_occ
37 : USE atom_xc, ONLY: calculate_atom_ext_vxc,&
38 : calculate_atom_zmp
39 : USE cp_log_handling, ONLY: cp_get_default_logger,&
40 : cp_logger_type
41 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
42 : cp_print_key_unit_nr
43 : USE input_constants, ONLY: do_analytic
44 : USE input_section_types, ONLY: section_vals_get,&
45 : section_vals_get_subs_vals,&
46 : section_vals_type,&
47 : section_vals_val_get
48 : USE kinds, ONLY: default_string_length,&
49 : dp
50 : USE mathconstants, ONLY: dfac,&
51 : gamma1,&
52 : pi,&
53 : rootpi
54 : USE periodic_table, ONLY: nelem,&
55 : ptable
56 : USE physcon, ONLY: bohr
57 : #include "./base/base_uses.f90"
58 :
59 : IMPLICIT NONE
60 : PRIVATE
61 : PUBLIC :: atom_energy_opt
62 :
63 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom_energy'
64 :
65 : CONTAINS
66 :
67 : ! **************************************************************************************************
68 : !> \brief Compute the atomic energy.
69 : !> \param atom_section ATOM input section
70 : !> \par History
71 : !> * 11.2016 geometrical response basis set [Juerg Hutter]
72 : !> * 07.2016 ADMM analysis [Juerg Hutter]
73 : !> * 02.2014 non-additive kinetic energy term [Juerg Hutter]
74 : !> * 11.2013 Zhao, Morrison, and Parr (ZMP) potential [Daniele Varsano]
75 : !> * 02.2010 unrestricted KS and HF methods [Juerg Hutter]
76 : !> * 05.2009 electronic density fit [Juerg Hutter]
77 : !> * 04.2009 refactored and renamed to atom_energy_opt() [Juerg Hutter]
78 : !> * 08.2008 created as atom_energy() [Juerg Hutter]
79 : ! **************************************************************************************************
80 324 : SUBROUTINE atom_energy_opt(atom_section)
81 : TYPE(section_vals_type), POINTER :: atom_section
82 :
83 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_energy_opt'
84 :
85 : CHARACTER(LEN=2) :: elem
86 : CHARACTER(LEN=default_string_length) :: filename
87 : CHARACTER(LEN=default_string_length), &
88 324 : DIMENSION(:), POINTER :: tmpstringlist
89 : INTEGER :: do_eric, do_erie, handle, i, im, in, iw, k, maxl, mb, method, mo, n_meth, n_rep, &
90 : nder, nr_gh, num_gau, num_gto, num_pol, reltyp, zcore, zval, zz
91 : INTEGER, DIMENSION(0:lmat) :: maxn
92 324 : INTEGER, DIMENSION(:), POINTER :: cn
93 : LOGICAL :: dm, do_gh, do_zmp, doread, eri_c, eri_e, &
94 : graph, had_ae, had_pp, lcomp, lcond, &
95 : pp_calc, read_vxc
96 : REAL(KIND=dp) :: crad, delta, lambda
97 324 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ext_density, ext_vxc
98 : REAL(KIND=dp), DIMENSION(0:lmat, 10) :: pocc
99 : TYPE(atom_basis_type), POINTER :: ae_basis, pp_basis
100 : TYPE(atom_integrals), POINTER :: ae_int, pp_int
101 : TYPE(atom_optimization_type) :: optimization
102 : TYPE(atom_orbitals), POINTER :: orbitals
103 324 : TYPE(atom_p_type), DIMENSION(:, :), POINTER :: atom_info
104 : TYPE(atom_potential_type), POINTER :: ae_pot, p_pot
105 : TYPE(atom_state), POINTER :: state
106 : TYPE(cp_logger_type), POINTER :: logger
107 : TYPE(section_vals_type), POINTER :: admm_section, basis_section, external_vxc_section, &
108 : method_section, opt_section, potential_section, powell_section, sgp_section, xc_section, &
109 : zmp_restart_section, zmp_section
110 :
111 324 : CALL timeset(routineN, handle)
112 :
113 : ! What atom do we calculate
114 324 : CALL section_vals_val_get(atom_section, "ATOMIC_NUMBER", i_val=zval)
115 324 : CALL section_vals_val_get(atom_section, "ELEMENT", c_val=elem)
116 324 : zz = 0
117 11574 : DO i = 1, nelem
118 11574 : IF (ptable(i)%symbol == elem) THEN
119 : zz = i
120 : EXIT
121 : END IF
122 : END DO
123 324 : IF (zz /= 1) zval = zz
124 :
125 : ! read and set up inofrmation on the basis sets
126 11988 : ALLOCATE (ae_basis, pp_basis)
127 324 : basis_section => section_vals_get_subs_vals(atom_section, "AE_BASIS")
128 324 : NULLIFY (ae_basis%grid)
129 324 : CALL init_atom_basis(ae_basis, basis_section, zval, "AE")
130 324 : NULLIFY (pp_basis%grid)
131 324 : basis_section => section_vals_get_subs_vals(atom_section, "PP_BASIS")
132 324 : CALL init_atom_basis(pp_basis, basis_section, zval, "PP")
133 :
134 : ! print general and basis set information
135 324 : logger => cp_get_default_logger()
136 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%PROGRAM_BANNER", extension=".log")
137 324 : IF (iw > 0) CALL atom_print_info(zval, "Atomic Energy Calculation", iw)
138 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%PROGRAM_BANNER")
139 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%BASIS_SET", extension=".log")
140 324 : IF (iw > 0) THEN
141 0 : CALL atom_print_basis(ae_basis, iw, " All Electron Basis")
142 0 : CALL atom_print_basis(pp_basis, iw, " Pseudopotential Basis")
143 : END IF
144 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%BASIS_SET")
145 :
146 : ! read and setup information on the pseudopotential
147 324 : NULLIFY (potential_section)
148 324 : potential_section => section_vals_get_subs_vals(atom_section, "POTENTIAL")
149 3403620 : ALLOCATE (ae_pot, p_pot)
150 324 : CALL init_atom_potential(p_pot, potential_section, zval)
151 324 : CALL init_atom_potential(ae_pot, potential_section, -1)
152 :
153 : ! if the ERI's are calculated analytically, we have to precalculate them
154 324 : eri_c = .FALSE.
155 324 : CALL section_vals_val_get(atom_section, "COULOMB_INTEGRALS", i_val=do_eric)
156 324 : IF (do_eric == do_analytic) eri_c = .TRUE.
157 324 : eri_e = .FALSE.
158 324 : CALL section_vals_val_get(atom_section, "EXCHANGE_INTEGRALS", i_val=do_erie)
159 324 : IF (do_erie == do_analytic) eri_e = .TRUE.
160 324 : CALL section_vals_val_get(atom_section, "USE_GAUSS_HERMITE", l_val=do_gh)
161 324 : CALL section_vals_val_get(atom_section, "GRID_POINTS_GH", i_val=nr_gh)
162 :
163 : ! information on the states to be calculated
164 324 : CALL section_vals_val_get(atom_section, "MAX_ANGULAR_MOMENTUM", i_val=maxl)
165 324 : maxn = 0
166 324 : CALL section_vals_val_get(atom_section, "CALCULATE_STATES", i_vals=cn)
167 684 : DO in = 1, MIN(SIZE(cn), 4)
168 684 : maxn(in - 1) = cn(in)
169 : END DO
170 2268 : DO in = 0, lmat
171 1944 : maxn(in) = MIN(maxn(in), ae_basis%nbas(in))
172 2268 : maxn(in) = MIN(maxn(in), pp_basis%nbas(in))
173 : END DO
174 :
175 : ! read optimization section
176 324 : opt_section => section_vals_get_subs_vals(atom_section, "OPTIMIZATION")
177 324 : CALL read_atom_opt_section(optimization, opt_section)
178 :
179 324 : had_ae = .FALSE.
180 324 : had_pp = .FALSE.
181 :
182 : ! Check for the total number of electron configurations to be calculated
183 324 : CALL section_vals_val_get(atom_section, "ELECTRON_CONFIGURATION", n_rep_val=n_rep)
184 : ! Check for the total number of method types to be calculated
185 324 : method_section => section_vals_get_subs_vals(atom_section, "METHOD")
186 324 : CALL section_vals_get(method_section, n_repetition=n_meth)
187 :
188 : ! integrals
189 137700 : ALLOCATE (ae_int, pp_int)
190 :
191 1950 : ALLOCATE (atom_info(n_rep, n_meth))
192 :
193 654 : DO in = 1, n_rep
194 984 : DO im = 1, n_meth
195 :
196 330 : NULLIFY (atom_info(in, im)%atom)
197 330 : CALL create_atom_type(atom_info(in, im)%atom)
198 :
199 330 : atom_info(in, im)%atom%optimization = optimization
200 :
201 330 : atom_info(in, im)%atom%z = zval
202 330 : xc_section => section_vals_get_subs_vals(method_section, "XC", i_rep_section=im)
203 330 : atom_info(in, im)%atom%xc_section => xc_section
204 :
205 : ! ZMP Reading input sections if they are found initialize everything
206 : do_zmp = .FALSE.
207 : doread = .FALSE.
208 : read_vxc = .FALSE.
209 :
210 330 : zmp_section => section_vals_get_subs_vals(method_section, "ZMP")
211 330 : CALL section_vals_get(zmp_section, explicit=do_zmp)
212 330 : atom_info(in, im)%atom%do_zmp = do_zmp
213 330 : CALL section_vals_val_get(zmp_section, "FILE_DENSITY", c_val=filename)
214 330 : atom_info(in, im)%atom%ext_file = filename
215 : CALL section_vals_val_get(zmp_section, "GRID_TOL", &
216 330 : r_val=atom_info(in, im)%atom%zmpgrid_tol)
217 330 : CALL section_vals_val_get(zmp_section, "LAMBDA", r_val=lambda)
218 330 : atom_info(in, im)%atom%lambda = lambda
219 330 : CALL section_vals_val_get(zmp_section, "DM", l_val=dm)
220 330 : atom_info(in, im)%atom%dm = dm
221 :
222 330 : zmp_restart_section => section_vals_get_subs_vals(zmp_section, "RESTART")
223 330 : CALL section_vals_get(zmp_restart_section, explicit=doread)
224 330 : atom_info(in, im)%atom%doread = doread
225 330 : CALL section_vals_val_get(zmp_restart_section, "FILE_RESTART", c_val=filename)
226 330 : atom_info(in, im)%atom%zmp_restart_file = filename
227 :
228 : ! ZMP Reading external vxc section, if found initialize
229 330 : external_vxc_section => section_vals_get_subs_vals(method_section, "EXTERNAL_VXC")
230 330 : CALL section_vals_get(external_vxc_section, explicit=read_vxc)
231 330 : atom_info(in, im)%atom%read_vxc = read_vxc
232 330 : CALL section_vals_val_get(external_vxc_section, "FILE_VXC", c_val=filename)
233 330 : atom_info(in, im)%atom%ext_vxc_file = filename
234 : CALL section_vals_val_get(external_vxc_section, "GRID_TOL", &
235 330 : r_val=atom_info(in, im)%atom%zmpvxcgrid_tol)
236 :
237 119790 : ALLOCATE (state)
238 :
239 : ! get the electronic configuration
240 : CALL section_vals_val_get(atom_section, "ELECTRON_CONFIGURATION", i_rep_val=in, &
241 330 : c_vals=tmpstringlist)
242 :
243 : ! set occupations
244 330 : CALL atom_set_occupation(tmpstringlist, state%occ, state%occupation, state%multiplicity)
245 330 : state%maxl_occ = get_maxl_occ(state%occ)
246 2310 : state%maxn_occ = get_maxn_occ(state%occ)
247 :
248 : ! set number of states to be calculated
249 330 : state%maxl_calc = MAX(maxl, state%maxl_occ)
250 330 : state%maxl_calc = MIN(lmat, state%maxl_calc)
251 2310 : state%maxn_calc = 0
252 1524 : DO k = 0, state%maxl_calc
253 1524 : state%maxn_calc(k) = MAX(maxn(k), state%maxn_occ(k))
254 : END DO
255 :
256 : ! is there a pseudo potential
257 1104 : pp_calc = ANY(INDEX(tmpstringlist(1:), "CORE") /= 0)
258 330 : IF (pp_calc) THEN
259 : ! get and set the core occupations
260 72 : CALL section_vals_val_get(atom_section, "CORE", c_vals=tmpstringlist)
261 72 : CALL atom_set_occupation(tmpstringlist, state%core, pocc)
262 5112 : zcore = zval - NINT(SUM(state%core))
263 72 : CALL set_atom(atom_info(in, im)%atom, zcore=zcore, pp_calc=.TRUE.)
264 : ELSE
265 18318 : state%core = 0._dp
266 258 : CALL set_atom(atom_info(in, im)%atom, zcore=zval, pp_calc=.FALSE.)
267 : END IF
268 :
269 330 : CALL section_vals_val_get(method_section, "METHOD_TYPE", i_val=method, i_rep_section=im)
270 330 : CALL section_vals_val_get(method_section, "RELATIVISTIC", i_val=reltyp, i_rep_section=im)
271 330 : CALL set_atom(atom_info(in, im)%atom, method_type=method, relativistic=reltyp)
272 :
273 330 : IF (atom_consistent_method(method, state%multiplicity)) THEN
274 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%METHOD_INFO", extension=".log")
275 330 : CALL atom_print_method(atom_info(in, im)%atom, iw)
276 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%METHOD_INFO")
277 :
278 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%POTENTIAL", extension=".log")
279 330 : IF (pp_calc) THEN
280 72 : IF (iw > 0) CALL atom_print_potential(p_pot, iw)
281 : ELSE
282 258 : IF (iw > 0) CALL atom_print_potential(ae_pot, iw)
283 : END IF
284 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%POTENTIAL")
285 : END IF
286 :
287 : ! calculate integrals
288 330 : IF (pp_calc) THEN
289 : ! general integrals
290 : CALL atom_int_setup(pp_int, pp_basis, &
291 72 : potential=p_pot, eri_coulomb=eri_c, eri_exchange=eri_e)
292 : ! potential
293 72 : CALL atom_ppint_setup(pp_int, pp_basis, potential=p_pot)
294 : !
295 72 : NULLIFY (pp_int%tzora, pp_int%hdkh)
296 : !
297 72 : CALL set_atom(atom_info(in, im)%atom, basis=pp_basis, integrals=pp_int, potential=p_pot)
298 936 : state%maxn_calc(:) = MIN(state%maxn_calc(:), pp_basis%nbas(:))
299 504 : CPASSERT(ALL(state%maxn_calc(:) >= state%maxn_occ))
300 : had_pp = .TRUE.
301 : ELSE
302 : ! general integrals
303 : CALL atom_int_setup(ae_int, ae_basis, potential=ae_pot, &
304 258 : eri_coulomb=eri_c, eri_exchange=eri_e)
305 : ! potential
306 258 : CALL atom_ppint_setup(ae_int, ae_basis, potential=ae_pot)
307 : ! relativistic correction terms
308 258 : CALL atom_relint_setup(ae_int, ae_basis, reltyp, zcore=REAL(zval, dp))
309 : !
310 258 : CALL set_atom(atom_info(in, im)%atom, basis=ae_basis, integrals=ae_int, potential=ae_pot)
311 3354 : state%maxn_calc(:) = MIN(state%maxn_calc(:), ae_basis%nbas(:))
312 1806 : CPASSERT(ALL(state%maxn_calc(:) >= state%maxn_occ))
313 : had_ae = .TRUE.
314 : END IF
315 :
316 330 : CALL set_atom(atom_info(in, im)%atom, state=state)
317 :
318 : CALL set_atom(atom_info(in, im)%atom, coulomb_integral_type=do_eric, &
319 330 : exchange_integral_type=do_erie)
320 330 : atom_info(in, im)%atom%hfx_pot%do_gh = do_gh
321 330 : atom_info(in, im)%atom%hfx_pot%nr_gh = nr_gh
322 :
323 330 : NULLIFY (orbitals)
324 2310 : mo = MAXVAL(state%maxn_calc)
325 2310 : mb = MAXVAL(atom_info(in, im)%atom%basis%nbas)
326 330 : CALL create_atom_orbs(orbitals, mb, mo)
327 330 : CALL set_atom(atom_info(in, im)%atom, orbitals=orbitals)
328 :
329 2310 : IF (atom_consistent_method(method, state%multiplicity)) THEN
330 : !Calculate the electronic structure
331 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%SCF_INFO", extension=".log")
332 330 : CALL calculate_atom(atom_info(in, im)%atom, iw)
333 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%SCF_INFO")
334 :
335 : ! ZMP If we have the external density do zmp
336 330 : IF (atom_info(in, im)%atom%do_zmp) THEN
337 0 : CALL atom_write_zmp_restart(atom_info(in, im)%atom)
338 :
339 0 : ALLOCATE (ext_density(atom_info(in, im)%atom%basis%grid%nr))
340 0 : ext_density = 0._dp
341 0 : CALL atom_read_external_density(ext_density, atom_info(in, im)%atom, iw)
342 : CALL calculate_atom_zmp(ext_density=ext_density, &
343 : atom=atom_info(in, im)%atom, &
344 0 : lprint=.TRUE.)
345 0 : DEALLOCATE (ext_density)
346 : END IF
347 : ! ZMP If we have the external v_xc calculate KS quantities
348 330 : IF (atom_info(in, im)%atom%read_vxc) THEN
349 0 : ALLOCATE (ext_vxc(atom_info(in, im)%atom%basis%grid%nr))
350 0 : ext_vxc = 0._dp
351 0 : CALL atom_read_external_vxc(ext_vxc, atom_info(in, im)%atom, iw)
352 : CALL calculate_atom_ext_vxc(vxc=ext_vxc, &
353 : atom=atom_info(in, im)%atom, &
354 0 : lprint=.TRUE.)
355 0 : DEALLOCATE (ext_vxc)
356 : END IF
357 :
358 : ! Print out the orbitals if requested
359 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ORBITALS", extension=".log")
360 330 : CALL section_vals_val_get(atom_section, "PRINT%ORBITALS%XMGRACE", l_val=graph)
361 330 : IF (iw > 0) THEN
362 0 : CALL atom_print_orbitals(atom_info(in, im)%atom, iw, xmgrace=graph)
363 : END IF
364 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ORBITALS")
365 :
366 : ! perform a fit of the total electronic density
367 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%FIT_DENSITY", extension=".log")
368 330 : IF (iw > 0) THEN
369 0 : CALL section_vals_val_get(atom_section, "PRINT%FIT_DENSITY%NUM_GTO", i_val=num_gto)
370 0 : powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
371 0 : CALL atom_fit_density(atom_info(in, im)%atom, num_gto, 0, iw, powell_section=powell_section)
372 : END IF
373 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%FIT_DENSITY")
374 :
375 : ! Optimize a local potential for the non-additive kinetic energy term in KG
376 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%FIT_KGPOT", extension=".log")
377 330 : IF (iw > 0) THEN
378 1 : CALL section_vals_val_get(atom_section, "PRINT%FIT_KGPOT%NUM_GAUSSIAN", i_val=num_gau)
379 1 : CALL section_vals_val_get(atom_section, "PRINT%FIT_KGPOT%NUM_POLYNOM", i_val=num_pol)
380 1 : powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
381 1 : CALL atom_fit_kgpot(atom_info(in, im)%atom, num_gau, num_pol, iw, powell_section=powell_section)
382 : END IF
383 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%FIT_KGPOT")
384 :
385 : ! generate a response basis
386 330 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%RESPONSE_BASIS", extension=".log")
387 330 : IF (iw > 0) THEN
388 1 : CALL section_vals_val_get(atom_section, "PRINT%RESPONSE_BASIS%DELTA_CHARGE", r_val=delta)
389 1 : CALL section_vals_val_get(atom_section, "PRINT%RESPONSE_BASIS%DERIVATIVES", i_val=nder)
390 1 : CALL atom_response_basis(atom_info(in, im)%atom, delta, nder, iw)
391 : END IF
392 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%RESPONSE_BASIS")
393 :
394 : ! generate a UPF file
395 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%UPF_FILE", extension=".upf", &
396 330 : file_position="REWIND")
397 330 : IF (iw > 0) THEN
398 2 : CALL atom_write_upf(atom_info(in, im)%atom, iw)
399 : END IF
400 330 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%UPF_FILE")
401 : END IF
402 :
403 : END DO
404 : END DO
405 :
406 : ! generate a geometrical response basis (GRB)
407 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS", extension=".log")
408 324 : IF (iw > 0) THEN
409 2 : CALL atom_grb_construction(atom_info, atom_section, iw)
410 : END IF
411 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS")
412 :
413 : ! Analyze basis sets
414 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ANALYZE_BASIS", extension=".log")
415 324 : IF (iw > 0) THEN
416 3 : CALL section_vals_val_get(atom_section, "PRINT%ANALYZE_BASIS%OVERLAP_CONDITION_NUMBER", l_val=lcond)
417 3 : CALL section_vals_val_get(atom_section, "PRINT%ANALYZE_BASIS%COMPLETENESS", l_val=lcomp)
418 3 : crad = ptable(zval)%covalent_radius*bohr
419 3 : IF (had_ae) THEN
420 2 : IF (lcond) CALL atom_condnumber(ae_basis, crad, iw)
421 2 : IF (lcomp) CALL atom_completeness(ae_basis, zval, iw)
422 : END IF
423 3 : IF (had_pp) THEN
424 1 : IF (lcond) CALL atom_condnumber(pp_basis, crad, iw)
425 1 : IF (lcomp) CALL atom_completeness(pp_basis, zval, iw)
426 : END IF
427 : END IF
428 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ANALYZE_BASIS")
429 :
430 : ! Analyse ADMM approximation
431 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ADMM", extension=".log")
432 324 : admm_section => section_vals_get_subs_vals(atom_section, "PRINT%ADMM")
433 324 : IF (iw > 0) THEN
434 1 : CALL atom_admm(atom_info, admm_section, iw)
435 : END IF
436 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ADMM")
437 :
438 : ! Generate a separable form of the pseudopotential using Gaussian functions
439 324 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO", extension=".log")
440 324 : sgp_section => section_vals_get_subs_vals(atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO")
441 324 : IF (iw > 0) THEN
442 5 : CALL atom_sgp_construction(atom_info, sgp_section, iw)
443 : END IF
444 324 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO")
445 :
446 : ! clean up
447 324 : IF (had_ae) THEN
448 256 : CALL atom_int_release(ae_int)
449 256 : CALL atom_ppint_release(ae_int)
450 256 : CALL atom_relint_release(ae_int)
451 : END IF
452 324 : IF (had_pp) THEN
453 70 : CALL atom_int_release(pp_int)
454 70 : CALL atom_ppint_release(pp_int)
455 70 : CALL atom_relint_release(pp_int)
456 : END IF
457 324 : CALL release_atom_basis(ae_basis)
458 324 : CALL release_atom_basis(pp_basis)
459 :
460 324 : CALL release_atom_potential(p_pot)
461 324 : CALL release_atom_potential(ae_pot)
462 :
463 654 : DO in = 1, n_rep
464 984 : DO im = 1, n_meth
465 660 : CALL release_atom_type(atom_info(in, im)%atom)
466 : END DO
467 : END DO
468 324 : DEALLOCATE (atom_info)
469 :
470 324 : DEALLOCATE (ae_pot, p_pot, ae_basis, pp_basis, ae_int, pp_int)
471 :
472 324 : CALL timestop(handle)
473 :
474 2268 : END SUBROUTINE atom_energy_opt
475 :
476 : ! **************************************************************************************************
477 : !> \brief Calculate response basis contraction coefficients.
478 : !> \param atom information about the atomic kind
479 : !> \param delta variation of charge used in finite difference derivative calculation
480 : !> \param nder number of wavefunction derivatives to calculate
481 : !> \param iw output file unit
482 : !> \par History
483 : !> * 10.2011 Gram-Schmidt orthogonalization [Joost VandeVondele]
484 : !> * 05.2009 created [Juerg Hutter]
485 : ! **************************************************************************************************
486 1 : SUBROUTINE atom_response_basis(atom, delta, nder, iw)
487 :
488 : TYPE(atom_type), POINTER :: atom
489 : REAL(KIND=dp), INTENT(IN) :: delta
490 : INTEGER, INTENT(IN) :: nder, iw
491 :
492 : INTEGER :: i, ider, j, k, l, lhomo, m, n, nhomo, &
493 : s1, s2
494 : REAL(KIND=dp) :: dene, emax, expzet, fhomo, o, prefac, &
495 : zeta
496 1 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: amat
497 1 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: rbasis
498 1 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: wfn
499 1 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: ovlp
500 : TYPE(atom_state), POINTER :: state
501 :
502 1 : WRITE (iw, '(/," ",79("*"),/,T30,A,A/," ",79("*"))') "RESPONSE BASIS for ", ptable(atom%z)%symbol
503 :
504 1 : state => atom%state
505 1 : ovlp => atom%integrals%ovlp
506 :
507 : ! find HOMO
508 1 : lhomo = -1
509 1 : nhomo = -1
510 1 : emax = -HUGE(1._dp)
511 4 : DO l = 0, state%maxl_occ
512 6 : DO i = 1, state%maxn_occ(l)
513 5 : IF (atom%orbitals%ener(i, l) > emax) THEN
514 1 : lhomo = l
515 1 : nhomo = i
516 1 : emax = atom%orbitals%ener(i, l)
517 1 : fhomo = state%occupation(l, i)
518 : END IF
519 : END DO
520 : END DO
521 :
522 1 : s1 = SIZE(atom%orbitals%wfn, 1)
523 1 : s2 = SIZE(atom%orbitals%wfn, 2)
524 6 : ALLOCATE (wfn(s1, s2, 0:lmat, -nder:nder))
525 7 : s2 = MAXVAL(state%maxn_occ) + nder
526 5 : ALLOCATE (rbasis(s1, s2, 0:lmat))
527 91 : rbasis = 0._dp
528 :
529 4 : DO ider = -nder, nder
530 3 : dene = REAL(ider, KIND=dp)*delta
531 3 : CPASSERT(fhomo > ABS(dene))
532 3 : state%occupation(lhomo, nhomo) = fhomo + dene
533 3 : CALL calculate_atom(atom, iw=0, noguess=.TRUE.)
534 147 : wfn(:, :, :, ider) = atom%orbitals%wfn
535 4 : state%occupation(lhomo, nhomo) = fhomo
536 : END DO
537 :
538 4 : DO l = 0, state%maxl_occ
539 : ! occupied states
540 6 : DO i = 1, MAX(state%maxn_occ(l), 1)
541 24 : rbasis(:, i, l) = wfn(:, i, l, 0)
542 : END DO
543 : ! differentiation
544 6 : DO ider = 1, nder
545 3 : i = MAX(state%maxn_occ(l), 1)
546 3 : SELECT CASE (ider)
547 : CASE (1)
548 21 : rbasis(:, i + 1, l) = 0.5_dp*(wfn(:, i, l, 1) - wfn(:, i, l, -1))/delta
549 : CASE (2)
550 0 : rbasis(:, i + 2, l) = 0.25_dp*(wfn(:, i, l, 2) - 2._dp*wfn(:, i, l, 0) + wfn(:, i, l, -2))/delta**2
551 : CASE (3)
552 : rbasis(:, i + 3, l) = 0.125_dp*(wfn(:, i, l, 3) - 3._dp*wfn(:, i, l, 1) &
553 0 : + 3._dp*wfn(:, i, l, -1) - wfn(:, i, l, -3))/delta**3
554 : CASE DEFAULT
555 3 : CPABORT("")
556 : END SELECT
557 : END DO
558 :
559 : ! orthogonalization, use gram-schmidt in order to keep the natural order (semi-core, valence, response) of the wfn.
560 3 : n = state%maxn_occ(l) + nder
561 3 : m = atom%basis%nbas(l)
562 8 : DO i = 1, n
563 7 : DO j = 1, i - 1
564 192 : o = DOT_PRODUCT(rbasis(1:m, j, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
565 19 : rbasis(1:m, i, l) = rbasis(1:m, i, l) - o*rbasis(1:m, j, l)
566 : END DO
567 480 : o = DOT_PRODUCT(rbasis(1:m, i, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), (/m/)))
568 38 : rbasis(1:m, i, l) = rbasis(1:m, i, l)/SQRT(o)
569 : END DO
570 :
571 : ! check
572 12 : ALLOCATE (amat(n, n))
573 578 : amat(1:n, 1:n) = MATMUL(TRANSPOSE(rbasis(1:m, 1:n, l)), MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, 1:n, l)))
574 8 : DO i = 1, n
575 8 : amat(i, i) = amat(i, i) - 1._dp
576 : END DO
577 17 : IF (MAXVAL(ABS(amat)) > 1.e-12) THEN
578 0 : WRITE (iw, '(/,A,G20.10)') " Orthogonality error ", MAXVAL(ABS(amat))
579 : END IF
580 3 : DEALLOCATE (amat)
581 :
582 : ! Quickstep normalization
583 3 : WRITE (iw, '(/,A,T30,I3)') " Angular momentum :", l
584 :
585 3 : WRITE (iw, '(/,A,I0,A,I0,A)') " Exponent Coef.(Quickstep Normalization), first ", &
586 6 : n - nder, " valence ", nder, " response"
587 3 : expzet = 0.25_dp*REAL(2*l + 3, dp)
588 3 : prefac = SQRT(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
589 22 : DO i = 1, m
590 18 : zeta = (2._dp*atom%basis%am(i, l))**expzet
591 51 : WRITE (iw, '(4X,F20.10,4X,15ES20.6)') atom%basis%am(i, l), ((prefac*rbasis(i, k, l)/zeta), k=1, n)
592 : END DO
593 :
594 : END DO
595 :
596 1 : DEALLOCATE (wfn, rbasis)
597 :
598 1 : WRITE (iw, '(" ",79("*"))')
599 :
600 2 : END SUBROUTINE atom_response_basis
601 :
602 : ! **************************************************************************************************
603 : !> \brief Write pseudo-potential in Quantum Espresso UPF format.
604 : !> \param atom information about the atomic kind
605 : !> \param iw output file unit
606 : !> \par History
607 : !> * 09.2012 created [Juerg Hutter]
608 : ! **************************************************************************************************
609 2 : SUBROUTINE atom_write_upf(atom, iw)
610 :
611 : TYPE(atom_type), POINTER :: atom
612 : INTEGER, INTENT(IN) :: iw
613 :
614 : CHARACTER(LEN=default_string_length) :: string
615 : INTEGER :: i, ibeta, j, k, l, lmax, nbeta, nr, &
616 : nwfc, nwfn
617 : LOGICAL :: up
618 : REAL(KIND=dp) :: pf, rl, rmax
619 2 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: beta, corden, dens, ef, locpot, rp
620 2 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: dij
621 : TYPE(atom_gthpot_type), POINTER :: pot
622 :
623 2 : IF (.NOT. atom%pp_calc) RETURN
624 2 : IF (atom%potential%ppot_type /= gth_pseudo) RETURN
625 2 : pot => atom%potential%gth_pot
626 2 : CPASSERT(.NOT. pot%lsdpot)
627 :
628 2 : WRITE (iw, '(A)') '<UPF version="2.0.1">'
629 :
630 2 : WRITE (iw, '(T4,A)') '<PP_INFO>'
631 2 : WRITE (iw, '(T8,A)') 'Converted from CP2K GTH format'
632 2 : WRITE (iw, '(T8,A)') '<PP_INPUTFILE>'
633 2 : CALL atom_write_pseudo_param(pot, iw)
634 2 : WRITE (iw, '(T8,A)') '</PP_INPUTFILE>'
635 2 : WRITE (iw, '(T4,A)') '</PP_INFO>'
636 2 : WRITE (iw, '(T4,A)') '<PP_HEADER'
637 2 : WRITE (iw, '(T8,A)') 'generated="Generated in analytical, separable form"'
638 2 : WRITE (iw, '(T8,A)') 'author="Goedecker/Hartwigsen/Hutter/Teter"'
639 2 : WRITE (iw, '(T8,A)') 'date="Phys.Rev.B58, 3641 (1998); B54, 1703 (1996)"'
640 2 : WRITE (iw, '(T8,A)') 'comment="This file generated by CP2K ATOM code"'
641 2 : CALL compose(string, "element", cval=pot%symbol)
642 2 : WRITE (iw, '(T8,A)') TRIM(string)
643 2 : WRITE (iw, '(T8,A)') 'pseudo_type="NC"'
644 2 : WRITE (iw, '(T8,A)') 'relativistic="no"'
645 2 : WRITE (iw, '(T8,A)') 'is_ultrasoft="F"'
646 2 : WRITE (iw, '(T8,A)') 'is_paw="F"'
647 2 : WRITE (iw, '(T8,A)') 'is_coulomb="F"'
648 2 : WRITE (iw, '(T8,A)') 'has_so="F"'
649 2 : WRITE (iw, '(T8,A)') 'has_wfc="F"'
650 2 : WRITE (iw, '(T8,A)') 'has_gipaw="F"'
651 2 : WRITE (iw, '(T8,A)') 'paw_as_gipaw="F"'
652 2 : IF (pot%nlcc) THEN
653 1 : WRITE (iw, '(T8,A)') 'core_correction="T"'
654 : ELSE
655 1 : WRITE (iw, '(T8,A)') 'core_correction="F"'
656 : END IF
657 2 : WRITE (iw, '(T8,A)') 'functional="DFT"'
658 2 : CALL compose(string, "z_valence", rval=pot%zion)
659 2 : WRITE (iw, '(T8,A)') TRIM(string)
660 2 : CALL compose(string, "total_psenergy", rval=2._dp*atom%energy%etot)
661 2 : WRITE (iw, '(T8,A)') TRIM(string)
662 2 : WRITE (iw, '(T8,A)') 'wfc_cutoff="0.0E+00"'
663 2 : WRITE (iw, '(T8,A)') 'rho_cutoff="0.0E+00"'
664 2 : lmax = -1
665 14 : DO l = 0, lmat
666 14 : IF (pot%nl(l) > 0) lmax = l
667 : END DO
668 2 : CALL compose(string, "l_max", ival=lmax)
669 2 : WRITE (iw, '(T8,A)') TRIM(string)
670 2 : WRITE (iw, '(T8,A)') 'l_max_rho="0"'
671 2 : WRITE (iw, '(T8,A)') 'l_local="-3"'
672 2 : nr = atom%basis%grid%nr
673 2 : CALL compose(string, "mesh_size", ival=nr)
674 2 : WRITE (iw, '(T8,A)') TRIM(string)
675 14 : nwfc = SUM(atom%state%maxn_occ)
676 2 : CALL compose(string, "number_of_wfc", ival=nwfc)
677 2 : WRITE (iw, '(T8,A)') TRIM(string)
678 14 : nbeta = SUM(pot%nl)
679 2 : CALL compose(string, "number_of_proj", ival=nbeta)
680 2 : WRITE (iw, '(T8,A)') TRIM(string)//'/>'
681 :
682 : ! Mesh
683 2 : up = atom%basis%grid%rad(1) < atom%basis%grid%rad(nr)
684 2 : WRITE (iw, '(T4,A)') '<PP_MESH'
685 2 : WRITE (iw, '(T8,A)') 'dx="1.E+00"'
686 2 : CALL compose(string, "mesh", ival=nr)
687 2 : WRITE (iw, '(T8,A)') TRIM(string)
688 2 : WRITE (iw, '(T8,A)') 'xmin="1.E+00"'
689 804 : rmax = MAXVAL(atom%basis%grid%rad)
690 2 : CALL compose(string, "rmax", rval=rmax)
691 2 : WRITE (iw, '(T8,A)') TRIM(string)
692 2 : WRITE (iw, '(T8,A)') 'zmesh="1.E+00">'
693 2 : WRITE (iw, '(T8,A)') '<PP_R type="real"'
694 2 : CALL compose(string, "size", ival=nr)
695 2 : WRITE (iw, '(T12,A)') TRIM(string)
696 2 : WRITE (iw, '(T12,A)') 'columns="4">'
697 2 : IF (up) THEN
698 0 : WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%rad(i), i=1, nr)
699 : ELSE
700 802 : WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%rad(i), i=nr, 1, -1)
701 : END IF
702 2 : WRITE (iw, '(T8,A)') '</PP_R>'
703 2 : WRITE (iw, '(T8,A)') '<PP_RAB type="real"'
704 2 : CALL compose(string, "size", ival=nr)
705 2 : WRITE (iw, '(T12,A)') TRIM(string)
706 2 : WRITE (iw, '(T12,A)') 'columns="4">'
707 2 : IF (up) THEN
708 0 : WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%wr(i)/atom%basis%grid%rad2(i), i=1, nr)
709 : ELSE
710 802 : WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%wr(i)/atom%basis%grid%rad2(i), i=nr, 1, -1)
711 : END IF
712 2 : WRITE (iw, '(T8,A)') '</PP_RAB>'
713 2 : WRITE (iw, '(T4,A)') '</PP_MESH>'
714 :
715 : ! NLCC
716 2 : IF (pot%nlcc) THEN
717 1 : WRITE (iw, '(T4,A)') '<PP_NLCC type="real"'
718 1 : CALL compose(string, "size", ival=nr)
719 1 : WRITE (iw, '(T8,A)') TRIM(string)
720 1 : WRITE (iw, '(T8,A)') 'columns="4">'
721 3 : ALLOCATE (corden(nr))
722 401 : corden(:) = 0.0_dp
723 1 : CALL atom_core_density(corden, atom%potential, "RHO", atom%basis%grid%rad)
724 1 : IF (up) THEN
725 0 : WRITE (iw, '(T8,4ES25.12E3)') (corden(i), i=1, nr)
726 : ELSE
727 1 : WRITE (iw, '(T8,4ES25.12E3)') (corden(i), i=nr, 1, -1)
728 : END IF
729 1 : DEALLOCATE (corden)
730 1 : WRITE (iw, '(T4,A)') '</PP_NLCC>'
731 : END IF
732 :
733 : ! local PP
734 2 : WRITE (iw, '(T4,A)') '<PP_LOCAL type="real"'
735 2 : CALL compose(string, "size", ival=nr)
736 2 : WRITE (iw, '(T8,A)') TRIM(string)
737 2 : WRITE (iw, '(T8,A)') 'columns="4">'
738 6 : ALLOCATE (locpot(nr))
739 802 : locpot(:) = 0.0_dp
740 2 : CALL atom_local_potential(locpot, pot, atom%basis%grid%rad)
741 2 : IF (up) THEN
742 0 : WRITE (iw, '(T8,4ES25.12E3)') (2.0_dp*locpot(i), i=1, nr)
743 : ELSE
744 802 : WRITE (iw, '(T8,4ES25.12E3)') (2.0_dp*locpot(i), i=nr, 1, -1)
745 : END IF
746 2 : DEALLOCATE (locpot)
747 2 : WRITE (iw, '(T4,A)') '</PP_LOCAL>'
748 :
749 : ! nonlocal PP
750 2 : WRITE (iw, '(T4,A)') '<PP_NONLOCAL>'
751 8 : ALLOCATE (rp(nr), ef(nr), beta(nr))
752 2 : ibeta = 0
753 14 : DO l = 0, lmat
754 12 : IF (pot%nl(l) == 0) CYCLE
755 3 : rl = pot%rcnl(l)
756 1203 : rp(:) = atom%basis%grid%rad
757 1203 : ef(:) = EXP(-0.5_dp*rp*rp/(rl*rl))
758 8 : DO i = 1, pot%nl(l)
759 3 : pf = rl**(l + 0.5_dp*(4._dp*i - 1._dp))
760 3 : j = l + 2*i - 1
761 3 : pf = SQRT(2._dp)/(pf*SQRT(gamma1(j)))
762 1203 : beta(:) = pf*rp**(l + 2*i - 2)*ef
763 3 : ibeta = ibeta + 1
764 3 : CALL compose(string, "<PP_BETA", counter=ibeta)
765 3 : WRITE (iw, '(T8,A)') TRIM(string)
766 3 : CALL compose(string, "angular_momentum", ival=l)
767 3 : WRITE (iw, '(T12,A)') TRIM(string)
768 3 : WRITE (iw, '(T12,A)') 'type="real"'
769 3 : CALL compose(string, "size", ival=nr)
770 3 : WRITE (iw, '(T12,A)') TRIM(string)
771 3 : WRITE (iw, '(T12,A)') 'columns="4">'
772 1203 : beta(:) = beta*rp
773 3 : IF (up) THEN
774 0 : WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=1, nr)
775 : ELSE
776 1203 : WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=nr, 1, -1)
777 : END IF
778 3 : CALL compose(string, "</PP_BETA", counter=ibeta, isfinal=.TRUE.)
779 15 : WRITE (iw, '(T8,A)') TRIM(string)
780 : END DO
781 : END DO
782 2 : DEALLOCATE (rp, ef, beta)
783 : ! nonlocal PP matrix elements
784 8 : ALLOCATE (dij(nbeta, nbeta))
785 10 : dij = 0._dp
786 14 : DO l = 0, lmat
787 12 : IF (pot%nl(l) == 0) CYCLE
788 4 : ibeta = SUM(pot%nl(0:l - 1)) + 1
789 3 : i = ibeta + pot%nl(l) - 1
790 11 : dij(ibeta:i, ibeta:i) = pot%hnl(1:pot%nl(l), 1:pot%nl(l), l)
791 : END DO
792 2 : WRITE (iw, '(T8,A)') '<PP_DIJ type="real"'
793 2 : WRITE (iw, '(T12,A)') 'columns="4">'
794 10 : WRITE (iw, '(T12,4ES25.12E3)') ((0.5_dp*dij(i, j), j=1, nbeta), i=1, nbeta)
795 2 : WRITE (iw, '(T8,A)') '</PP_DIJ>'
796 2 : DEALLOCATE (dij)
797 2 : WRITE (iw, '(T4,A)') '</PP_NONLOCAL>'
798 :
799 : ! atomic wavefunctions
800 4 : ALLOCATE (beta(nr))
801 2 : WRITE (iw, '(T4,A)') '<PP_PSWFC>'
802 2 : nwfn = 0
803 14 : DO l = 0, lmat
804 134 : DO i = 1, 10
805 120 : IF (ABS(atom%state%occupation(l, i)) == 0._dp) CYCLE
806 4 : nwfn = nwfn + 1
807 4 : CALL compose(string, "<PP_CHI", counter=nwfn)
808 4 : WRITE (iw, '(T8,A)') TRIM(string)
809 4 : CALL compose(string, "l", ival=l)
810 4 : WRITE (iw, '(T12,A)') TRIM(string)
811 4 : CALL compose(string, "occupation", rval=atom%state%occupation(l, i))
812 4 : WRITE (iw, '(T12,A)') TRIM(string)
813 4 : CALL compose(string, "pseudo_energy", rval=2._dp*atom%orbitals%ener(i, l))
814 4 : WRITE (iw, '(T12,A)') TRIM(string)
815 4 : WRITE (iw, '(T12,A)') 'columns="4">'
816 1604 : beta = 0._dp
817 75 : DO k = 1, atom%basis%nbas(l)
818 28475 : beta(:) = beta(:) + atom%orbitals%wfn(k, i, l)*atom%basis%bf(:, k, l)
819 : END DO
820 1604 : beta(:) = beta*atom%basis%grid%rad
821 4 : IF (up) THEN
822 0 : WRITE (iw, '(T12,4ES25.12E3)') (beta(j)*atom%basis%grid%rad(j), j=1, nr)
823 : ELSE
824 1604 : WRITE (iw, '(T12,4ES25.12E3)') (beta(j)*atom%basis%grid%rad(j), j=nr, 1, -1)
825 : END IF
826 4 : CALL compose(string, "</PP_CHI", counter=nwfn, isfinal=.TRUE.)
827 132 : WRITE (iw, '(T8,A)') TRIM(string)
828 : END DO
829 : END DO
830 2 : WRITE (iw, '(T4,A)') '</PP_PSWFC>'
831 2 : DEALLOCATE (beta)
832 :
833 : ! atomic charge
834 4 : ALLOCATE (dens(nr))
835 2 : WRITE (iw, '(T4,A)') '<PP_RHOATOM type="real"'
836 2 : CALL compose(string, "size", ival=nr)
837 2 : WRITE (iw, '(T8,A)') TRIM(string)
838 2 : WRITE (iw, '(T8,A)') 'columns="4">'
839 : CALL atom_density(dens, atom%orbitals%pmat, atom%basis, atom%state%maxl_occ, &
840 2 : "RHO", atom%basis%grid%rad)
841 2 : IF (up) THEN
842 0 : WRITE (iw, '(T8,4ES25.12E3)') (4._dp*pi*dens(j)*atom%basis%grid%rad2(j), j=1, nr)
843 : ELSE
844 802 : WRITE (iw, '(T8,4ES25.12E3)') (4._dp*pi*dens(j)*atom%basis%grid%rad2(j), j=nr, 1, -1)
845 : END IF
846 2 : WRITE (iw, '(T4,A)') '</PP_RHOATOM>'
847 2 : DEALLOCATE (dens)
848 :
849 2 : WRITE (iw, '(A)') '</UPF>'
850 :
851 2 : END SUBROUTINE atom_write_upf
852 :
853 : ! **************************************************************************************************
854 : !> \brief Produce an XML attribute string 'tag="counter/rval/ival/cval"'
855 : !> \param string composed string
856 : !> \param tag attribute tag
857 : !> \param counter counter
858 : !> \param rval real variable
859 : !> \param ival integer variable
860 : !> \param cval string variable
861 : !> \param isfinal close the current XML element if this is the last attribute
862 : !> \par History
863 : !> * 09.2012 created [Juerg Hutter]
864 : ! **************************************************************************************************
865 59 : SUBROUTINE compose(string, tag, counter, rval, ival, cval, isfinal)
866 : CHARACTER(len=*), INTENT(OUT) :: string
867 : CHARACTER(len=*), INTENT(IN) :: tag
868 : INTEGER, INTENT(IN), OPTIONAL :: counter
869 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: rval
870 : INTEGER, INTENT(IN), OPTIONAL :: ival
871 : CHARACTER(len=*), INTENT(IN), OPTIONAL :: cval
872 : LOGICAL, INTENT(IN), OPTIONAL :: isfinal
873 :
874 : CHARACTER(LEN=default_string_length) :: str
875 : LOGICAL :: fin
876 :
877 59 : IF (PRESENT(counter)) THEN
878 14 : WRITE (str, "(I12)") counter
879 45 : ELSEIF (PRESENT(rval)) THEN
880 14 : WRITE (str, "(G18.8)") rval
881 31 : ELSEIF (PRESENT(ival)) THEN
882 29 : WRITE (str, "(I12)") ival
883 2 : ELSEIF (PRESENT(cval)) THEN
884 2 : WRITE (str, "(A)") TRIM(ADJUSTL(cval))
885 : ELSE
886 0 : WRITE (str, "(A)") ""
887 : END IF
888 59 : fin = .FALSE.
889 59 : IF (PRESENT(isfinal)) fin = isfinal
890 59 : IF (PRESENT(counter)) THEN
891 14 : IF (fin) THEN
892 7 : WRITE (string, "(A,A1,A,A1)") TRIM(ADJUSTL(tag)), '.', TRIM(ADJUSTL(str)), '>'
893 : ELSE
894 7 : WRITE (string, "(A,A1,A)") TRIM(ADJUSTL(tag)), '.', TRIM(ADJUSTL(str))
895 : END IF
896 : ELSE
897 45 : IF (fin) THEN
898 0 : WRITE (string, "(A,A2,A,A2)") TRIM(ADJUSTL(tag)), '="', TRIM(ADJUSTL(str)), '>"'
899 : ELSE
900 45 : WRITE (string, "(A,A2,A,A1)") TRIM(ADJUSTL(tag)), '="', TRIM(ADJUSTL(str)), '"'
901 : END IF
902 : END IF
903 59 : END SUBROUTINE compose
904 :
905 10 : END MODULE atom_energy
|