Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Methods dealing with helium_solvent_type
10 : !> \author Lukasz Walewski
11 : !> \date 2009-06-10
12 : ! **************************************************************************************************
13 : MODULE helium_methods
14 :
15 : USE atomic_kind_types, ONLY: get_atomic_kind
16 : USE bibliography, ONLY: Walewski2014,&
17 : cite_reference
18 : USE cell_types, ONLY: cell_type,&
19 : get_cell
20 : USE cp_files, ONLY: close_file,&
21 : open_file
22 : USE cp_log_handling, ONLY: cp_add_default_logger,&
23 : cp_get_default_logger,&
24 : cp_logger_create,&
25 : cp_logger_release,&
26 : cp_logger_type,&
27 : cp_rm_default_logger
28 : USE cp_output_handling, ONLY: cp_printkey_is_on
29 : USE cp_subsys_types, ONLY: cp_subsys_get,&
30 : cp_subsys_type
31 : USE f77_interface, ONLY: f_env_add_defaults,&
32 : f_env_rm_defaults,&
33 : f_env_type
34 : USE force_env_types, ONLY: force_env_get
35 : USE helium_common, ONLY: helium_com,&
36 : helium_pbc
37 : USE helium_interactions, ONLY: helium_vij
38 : USE helium_io, ONLY: helium_write_line,&
39 : helium_write_setup
40 : USE helium_nnp, ONLY: helium_init_nnp
41 : USE helium_sampling, ONLY: helium_sample
42 : USE helium_types, ONLY: helium_solvent_p_type,&
43 : helium_solvent_type,&
44 : rho_atom_number,&
45 : rho_moment_of_inertia,&
46 : rho_num,&
47 : rho_projected_area,&
48 : rho_winding_cycle,&
49 : rho_winding_number
50 : USE input_constants, ONLY: helium_cell_shape_cube,&
51 : helium_cell_shape_octahedron,&
52 : helium_sampling_ceperley,&
53 : helium_sampling_worm,&
54 : helium_solute_intpot_nnp,&
55 : helium_solute_intpot_none
56 : USE input_section_types, ONLY: section_vals_get,&
57 : section_vals_get_subs_vals,&
58 : section_vals_type,&
59 : section_vals_val_get,&
60 : section_vals_val_set
61 : USE kinds, ONLY: default_path_length,&
62 : default_string_length,&
63 : dp,&
64 : max_line_length
65 : USE mathconstants, ONLY: pi,&
66 : twopi
67 : USE message_passing, ONLY: mp_para_env_type
68 : USE nnp_environment_types, ONLY: nnp_env_release
69 : USE parallel_rng_types, ONLY: GAUSSIAN,&
70 : UNIFORM,&
71 : rng_stream_p_type,&
72 : rng_stream_type
73 : USE particle_list_types, ONLY: particle_list_type
74 : USE physcon, ONLY: a_mass,&
75 : angstrom,&
76 : boltzmann,&
77 : h_bar,&
78 : kelvin,&
79 : massunit
80 : USE pint_public, ONLY: pint_com_pos
81 : USE pint_types, ONLY: pint_env_type
82 : USE splines_methods, ONLY: init_spline,&
83 : init_splinexy
84 : USE splines_types, ONLY: spline_data_create,&
85 : spline_data_release
86 : #include "../base/base_uses.f90"
87 :
88 : IMPLICIT NONE
89 :
90 : PRIVATE
91 :
92 : LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .TRUE.
93 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'helium_methods'
94 :
95 : PUBLIC :: helium_create
96 : PUBLIC :: helium_init
97 : PUBLIC :: helium_release
98 :
99 : CONTAINS
100 :
101 : ! ***************************************************************************
102 : !> \brief Data-structure that holds all needed information about
103 : !> (superfluid) helium solvent
104 : !> \param helium_env ...
105 : !> \param input ...
106 : !> \param solute ...
107 : !> \par History
108 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
109 : !> 2023-07-23 Modified to work with NNP solute-solvent interactions [lduran]
110 : !> \author hforbert
111 : ! **************************************************************************************************
112 26 : SUBROUTINE helium_create(helium_env, input, solute)
113 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
114 : TYPE(section_vals_type), POINTER :: input
115 : TYPE(pint_env_type), INTENT(IN), OPTIONAL :: solute
116 :
117 : CHARACTER(len=*), PARAMETER :: routineN = 'helium_create'
118 :
119 : CHARACTER(len=default_path_length) :: msg_str, potential_file_name
120 : INTEGER :: color_sub, handle, i, input_unit, isize, &
121 : itmp, j, k, mepos, nlines, ntab, &
122 : num_env, pdx
123 26 : INTEGER, DIMENSION(:), POINTER :: env_all
124 : LOGICAL :: expl_cell, expl_dens, expl_nats, &
125 : expl_pot, explicit, ltmp
126 : REAL(KIND=dp) :: cgeof, dx, he_mass, mHe, rtmp, T, tau, &
127 : tcheck, x1, x_spline
128 26 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: pot_transfer
129 : TYPE(cp_logger_type), POINTER :: logger, tmplogger
130 : TYPE(mp_para_env_type), POINTER :: new_comm
131 : TYPE(section_vals_type), POINTER :: helium_section, input_worm, nnp_section
132 :
133 26 : CALL timeset(routineN, handle)
134 :
135 26 : CALL cite_reference(Walewski2014)
136 26 : NULLIFY (logger)
137 26 : logger => cp_get_default_logger()
138 :
139 26 : NULLIFY (helium_section)
140 : helium_section => section_vals_get_subs_vals(input, &
141 26 : "MOTION%PINT%HELIUM")
142 26 : CALL section_vals_get(helium_section, explicit=explicit)
143 26 : CPASSERT(explicit)
144 :
145 : ! get number of environments
146 : CALL section_vals_val_get(helium_section, "NUM_ENV", &
147 26 : explicit=explicit)
148 26 : IF (explicit) THEN
149 : CALL section_vals_val_get(helium_section, "NUM_ENV", &
150 26 : i_val=num_env)
151 : ELSE
152 0 : num_env = logger%para_env%num_pe
153 : END IF
154 26 : CPASSERT(num_env >= 0)
155 26 : IF (num_env .NE. logger%para_env%num_pe) THEN
156 6 : msg_str = "NUM_ENV not equal to number of processors"
157 6 : CPWARN(msg_str)
158 : END IF
159 : ! calculate number of tasks for each processor
160 : mepos = num_env/logger%para_env%num_pe &
161 26 : + MIN(MOD(num_env, logger%para_env%num_pe)/(logger%para_env%mepos + 1), 1)
162 : ! gather result
163 26 : NULLIFY (env_all)
164 78 : ALLOCATE (env_all(logger%para_env%num_pe))
165 78 : env_all(:) = 0
166 78 : CALL logger%para_env%allgather(mepos, env_all)
167 :
168 : ! create new communicator for processors with helium_env
169 26 : IF (mepos == 0) THEN
170 1 : color_sub = 0
171 : ELSE
172 25 : color_sub = 1
173 : END IF
174 26 : ALLOCATE (new_comm)
175 26 : CALL new_comm%from_split(logger%para_env, color_sub)
176 : ! release new_comm for processors without helium_env
177 26 : IF (mepos == 0) THEN
178 1 : CALL new_comm%free()
179 1 : DEALLOCATE (new_comm)
180 1 : NULLIFY (new_comm)
181 : END IF
182 :
183 26 : NULLIFY (helium_env)
184 26 : IF (mepos .GT. 0) THEN
185 106 : ALLOCATE (helium_env(mepos))
186 56 : DO k = 1, mepos
187 31 : helium_env(k)%comm => new_comm
188 31 : NULLIFY (helium_env(k)%env_all)
189 31 : helium_env(k)%env_all => env_all
190 3627 : ALLOCATE (helium_env(k)%helium)
191 31 : NULLIFY (helium_env(k)%helium%input)
192 31 : helium_env(k)%helium%input => input
193 56 : helium_env(k)%helium%num_env = num_env
194 : END DO
195 : ! RNG state create & init
196 25 : CALL helium_rng_init(helium_env)
197 :
198 56 : DO k = 1, mepos
199 : NULLIFY (helium_env(k)%helium%ptable, &
200 31 : helium_env(k)%helium%permutation, &
201 31 : helium_env(k)%helium%savepermutation, &
202 31 : helium_env(k)%helium%iperm, &
203 31 : helium_env(k)%helium%saveiperm, &
204 31 : helium_env(k)%helium%itmp_atoms_1d, &
205 31 : helium_env(k)%helium%ltmp_atoms_1d, &
206 31 : helium_env(k)%helium%itmp_atoms_np_1d, &
207 31 : helium_env(k)%helium%pos, &
208 31 : helium_env(k)%helium%savepos, &
209 31 : helium_env(k)%helium%work, &
210 31 : helium_env(k)%helium%force_avrg, &
211 31 : helium_env(k)%helium%force_inst, &
212 31 : helium_env(k)%helium%rtmp_3_np_1d, &
213 31 : helium_env(k)%helium%rtmp_p_ndim_1d, &
214 31 : helium_env(k)%helium%rtmp_p_ndim_np_1d, &
215 31 : helium_env(k)%helium%rtmp_3_atoms_beads_1d, &
216 31 : helium_env(k)%helium%rtmp_3_atoms_beads_np_1d, &
217 31 : helium_env(k)%helium%rtmp_p_ndim_2d, &
218 31 : helium_env(k)%helium%ltmp_3_atoms_beads_3d, &
219 31 : helium_env(k)%helium%tmatrix, helium_env(k)%helium%pmatrix, &
220 31 : helium_env(k)%helium%nmatrix, helium_env(k)%helium%ipmatrix, &
221 31 : helium_env(k)%helium%u0, helium_env(k)%helium%e0, &
222 31 : helium_env(k)%helium%uoffdiag, helium_env(k)%helium%eoffdiag, &
223 31 : helium_env(k)%helium%vij, &
224 31 : helium_env(k)%helium%rdf_inst, &
225 31 : helium_env(k)%helium%plength_avrg, &
226 31 : helium_env(k)%helium%plength_inst, &
227 31 : helium_env(k)%helium%atom_plength, &
228 31 : helium_env(k)%helium%ename &
229 31 : )
230 :
231 31 : helium_env(k)%helium%accepts = 0
232 31 : helium_env(k)%helium%relrot = 0
233 :
234 : ! check if solute is present in our simulation
235 31 : helium_env(k)%helium%solute_present = .FALSE.
236 31 : helium_env(k)%helium%solute_atoms = 0
237 31 : helium_env(k)%helium%solute_beads = 0
238 : CALL section_vals_val_get( &
239 : helium_section, &
240 : "HELIUM_ONLY", &
241 31 : l_val=ltmp)
242 31 : IF (.NOT. ltmp) THEN
243 21 : IF (PRESENT(solute)) THEN
244 21 : helium_env(k)%helium%solute_present = .TRUE.
245 21 : helium_env(k)%helium%solute_atoms = solute%ndim/3
246 21 : helium_env(k)%helium%solute_beads = solute%p
247 : END IF
248 : END IF
249 :
250 : CALL section_vals_val_get(helium_section, "NBEADS", &
251 31 : i_val=helium_env(k)%helium%beads)
252 : CALL section_vals_val_get(helium_section, "INOROT", &
253 31 : i_val=helium_env(k)%helium%iter_norot)
254 : CALL section_vals_val_get(helium_section, "IROT", &
255 31 : i_val=helium_env(k)%helium%iter_rot)
256 :
257 : ! get number of steps and current step number from PINT
258 : CALL section_vals_val_get(input, "MOTION%PINT%ITERATION", &
259 31 : i_val=itmp)
260 31 : helium_env(k)%helium%first_step = itmp
261 : CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
262 31 : explicit=explicit)
263 31 : IF (explicit) THEN
264 : CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
265 0 : i_val=itmp)
266 0 : helium_env(k)%helium%last_step = itmp
267 : helium_env(k)%helium%num_steps = helium_env(k)%helium%last_step &
268 0 : - helium_env(k)%helium%first_step
269 : ELSE
270 : CALL section_vals_val_get(input, "MOTION%PINT%NUM_STEPS", &
271 31 : i_val=itmp)
272 31 : helium_env(k)%helium%num_steps = itmp
273 : helium_env(k)%helium%last_step = helium_env(k)%helium%first_step &
274 31 : + helium_env(k)%helium%num_steps
275 : END IF
276 :
277 : ! boundary conditions
278 : CALL section_vals_val_get(helium_section, "PERIODIC", &
279 31 : l_val=helium_env(k)%helium%periodic)
280 : CALL section_vals_val_get(helium_section, "CELL_SHAPE", &
281 31 : i_val=helium_env(k)%helium%cell_shape)
282 :
283 : CALL section_vals_val_get(helium_section, "DROPLET_RADIUS", &
284 31 : r_val=helium_env(k)%helium%droplet_radius)
285 :
286 : ! Set density Rho, number of atoms N and volume V ( Rho = N / V ).
287 : ! Allow only 2 out of 3 values to be defined at the same time, calculate
288 : ! the third.
289 : ! Note, that DENSITY and NATOMS keywords have default values, while
290 : ! CELL_SIZE does not. Thus if CELL_SIZE is given explicitly then one and
291 : ! only one of the two remaining options must be give explicitly as well.
292 : ! If CELL_SIZE is not given explicitly then all four combinations of the
293 : ! two other options are valid.
294 : CALL section_vals_val_get(helium_section, "DENSITY", &
295 31 : explicit=expl_dens, r_val=helium_env(k)%helium%density)
296 : CALL section_vals_val_get(helium_section, "NATOMS", &
297 31 : explicit=expl_nats, i_val=helium_env(k)%helium%atoms)
298 : CALL section_vals_val_get(helium_section, "CELL_SIZE", &
299 31 : explicit=expl_cell)
300 31 : cgeof = 1.0_dp
301 31 : IF (helium_env(k)%helium%periodic) THEN
302 16 : IF (helium_env(k)%helium%cell_shape .EQ. helium_cell_shape_octahedron) cgeof = 2.0_dp
303 : END IF
304 31 : rtmp = (cgeof*helium_env(k)%helium%atoms/helium_env(k)%helium%density)**(1.0_dp/3.0_dp)
305 31 : IF (.NOT. expl_cell) THEN
306 31 : helium_env(k)%helium%cell_size = rtmp
307 : ELSE
308 : CALL section_vals_val_get(helium_section, "CELL_SIZE", &
309 0 : r_val=helium_env(k)%helium%cell_size)
310 : ! only more work if not all three values are consistent:
311 0 : IF (ABS(helium_env(k)%helium%cell_size - rtmp) .GT. 100.0_dp*EPSILON(0.0_dp)* &
312 : (ABS(helium_env(k)%helium%cell_size) + rtmp)) THEN
313 0 : IF (expl_dens .AND. expl_nats) THEN
314 : msg_str = "DENSITY, NATOMS and CELL_SIZE options "// &
315 0 : "contradict each other"
316 0 : CPWARN(msg_str)
317 : END IF
318 : !ok we have enough freedom to resolve the conflict:
319 0 : IF (.NOT. expl_dens) THEN
320 0 : helium_env(k)%helium%density = cgeof*helium_env(k)%helium%atoms/helium_env(k)%helium%cell_size**3.0_dp
321 0 : IF (.NOT. expl_nats) THEN
322 : msg_str = "CELL_SIZE defined but neither "// &
323 0 : "NATOMS nor DENSITY given, using default NATOMS."
324 0 : CPWARN(msg_str)
325 : END IF
326 : ELSE ! ( expl_dens .AND. .NOT. expl_nats )
327 : ! calculate the nearest number of atoms for given conditions
328 : helium_env(k)%helium%atoms = NINT(helium_env(k)%helium%density* &
329 0 : helium_env(k)%helium%cell_size**3.0_dp/cgeof)
330 : ! adjust cell size to maintain correct density
331 : ! (should be a small correction)
332 : rtmp = (cgeof*helium_env(k)%helium%atoms/helium_env(k)%helium%density &
333 0 : )**(1.0_dp/3.0_dp)
334 0 : IF (ABS(helium_env(k)%helium%cell_size - rtmp) .GT. 100.0_dp*EPSILON(0.0_dp) &
335 : *(ABS(helium_env(k)%helium%cell_size) + rtmp)) THEN
336 : msg_str = "Adjusting actual cell size "// &
337 0 : "to maintain correct density."
338 0 : CPWARN(msg_str)
339 0 : helium_env(k)%helium%cell_size = rtmp
340 : END IF
341 : END IF
342 : END IF
343 : END IF
344 31 : helium_env(k)%helium%cell_size_inv = 1.0_dp/helium_env(k)%helium%cell_size
345 : ! From now on helium%density, helium%atoms and helium%cell_size are
346 : ! correctly defined.
347 :
348 : ! set the M matrix for winding number calculations
349 118 : SELECT CASE (helium_env(k)%helium%cell_shape)
350 :
351 : CASE (helium_cell_shape_octahedron)
352 21 : helium_env(k)%helium%cell_m(1, 1) = -0.5_dp*helium_env(k)%helium%cell_size
353 21 : helium_env(k)%helium%cell_m(2, 1) = 0.5_dp*helium_env(k)%helium%cell_size
354 21 : helium_env(k)%helium%cell_m(3, 1) = 0.5_dp*helium_env(k)%helium%cell_size
355 21 : helium_env(k)%helium%cell_m(1, 2) = 0.5_dp*helium_env(k)%helium%cell_size
356 21 : helium_env(k)%helium%cell_m(2, 2) = -0.5_dp*helium_env(k)%helium%cell_size
357 21 : helium_env(k)%helium%cell_m(3, 2) = 0.5_dp*helium_env(k)%helium%cell_size
358 21 : helium_env(k)%helium%cell_m(1, 3) = 0.5_dp*helium_env(k)%helium%cell_size
359 21 : helium_env(k)%helium%cell_m(2, 3) = 0.5_dp*helium_env(k)%helium%cell_size
360 21 : helium_env(k)%helium%cell_m(3, 3) = -0.5_dp*helium_env(k)%helium%cell_size
361 21 : helium_env(k)%helium%cell_m_inv(1, 1) = 0.0_dp
362 21 : helium_env(k)%helium%cell_m_inv(2, 1) = 1.0_dp/helium_env(k)%helium%cell_size
363 21 : helium_env(k)%helium%cell_m_inv(3, 1) = 1.0_dp/helium_env(k)%helium%cell_size
364 21 : helium_env(k)%helium%cell_m_inv(1, 2) = 1.0_dp/helium_env(k)%helium%cell_size
365 21 : helium_env(k)%helium%cell_m_inv(2, 2) = 0.0_dp
366 21 : helium_env(k)%helium%cell_m_inv(3, 2) = 1.0_dp/helium_env(k)%helium%cell_size
367 21 : helium_env(k)%helium%cell_m_inv(1, 3) = 1.0_dp/helium_env(k)%helium%cell_size
368 21 : helium_env(k)%helium%cell_m_inv(2, 3) = 1.0_dp/helium_env(k)%helium%cell_size
369 21 : helium_env(k)%helium%cell_m_inv(3, 3) = 0.0_dp
370 : CASE (helium_cell_shape_cube)
371 :
372 10 : helium_env(k)%helium%cell_m(1, 1) = helium_env(k)%helium%cell_size
373 10 : helium_env(k)%helium%cell_m(2, 1) = 0.0_dp
374 10 : helium_env(k)%helium%cell_m(3, 1) = 0.0_dp
375 10 : helium_env(k)%helium%cell_m(1, 2) = 0.0_dp
376 10 : helium_env(k)%helium%cell_m(2, 2) = helium_env(k)%helium%cell_size
377 10 : helium_env(k)%helium%cell_m(3, 2) = 0.0_dp
378 10 : helium_env(k)%helium%cell_m(1, 3) = 0.0_dp
379 10 : helium_env(k)%helium%cell_m(2, 3) = 0.0_dp
380 10 : helium_env(k)%helium%cell_m(3, 3) = helium_env(k)%helium%cell_size
381 10 : helium_env(k)%helium%cell_m_inv(1, 1) = 1.0_dp/helium_env(k)%helium%cell_size
382 10 : helium_env(k)%helium%cell_m_inv(2, 1) = 0.0_dp
383 10 : helium_env(k)%helium%cell_m_inv(3, 1) = 0.0_dp
384 10 : helium_env(k)%helium%cell_m_inv(1, 2) = 0.0_dp
385 10 : helium_env(k)%helium%cell_m_inv(2, 2) = 1.0_dp/helium_env(k)%helium%cell_size
386 10 : helium_env(k)%helium%cell_m_inv(3, 2) = 0.0_dp
387 10 : helium_env(k)%helium%cell_m_inv(1, 3) = 0.0_dp
388 10 : helium_env(k)%helium%cell_m_inv(2, 3) = 0.0_dp
389 10 : helium_env(k)%helium%cell_m_inv(3, 3) = 1.0_dp/helium_env(k)%helium%cell_size
390 : CASE DEFAULT
391 0 : helium_env(k)%helium%cell_m(:, :) = 0.0_dp
392 31 : helium_env(k)%helium%cell_m_inv(:, :) = 0.0_dp
393 :
394 : END SELECT
395 :
396 : END DO ! k
397 :
398 25 : IF (logger%para_env%is_source()) THEN
399 : CALL section_vals_val_get(helium_section, "POTENTIAL_FILE_NAME", &
400 13 : c_val=potential_file_name)
401 : CALL open_file(file_name=TRIM(potential_file_name), &
402 13 : file_action="READ", file_status="OLD", unit_number=input_unit)
403 13 : READ (input_unit, "(A)") msg_str
404 13 : READ (msg_str, *, IOSTAT=i) nlines, pdx, tau, &
405 26 : x_spline, dx, he_mass
406 13 : IF (i /= 0) THEN
407 : ! old style potential file, use default mass and potential
408 13 : he_mass = 4.00263037059764_dp !< 4He mass in [u]
409 13 : expl_pot = .FALSE.
410 13 : READ (msg_str, *, IOSTAT=i) nlines, pdx, tau, &
411 26 : x_spline, dx
412 13 : IF (i /= 0) THEN
413 0 : msg_str = "Format/Read Error from Solvent POTENTIAL_FILE"
414 0 : CPABORT(msg_str)
415 : END IF
416 : ELSE
417 0 : expl_pot = .TRUE.
418 : ! in file really hb2m in kelvin angstrom**2
419 0 : he_mass = angstrom**2*kelvin/massunit/he_mass
420 : ! tau might be negative to get older versions of cp2k,
421 : ! that cannot handle the new potential file format to
422 : ! crash and not run a calculation with wrong mass/potential
423 0 : tau = ABS(tau)
424 : END IF
425 13 : tau = kelvin/tau
426 13 : x_spline = x_spline/angstrom
427 13 : dx = dx/angstrom
428 : END IF
429 :
430 25 : CALL helium_env(1)%comm%bcast(nlines, logger%para_env%source)
431 25 : CALL helium_env(1)%comm%bcast(pdx, logger%para_env%source)
432 25 : CALL helium_env(1)%comm%bcast(tau, logger%para_env%source)
433 25 : CALL helium_env(1)%comm%bcast(x_spline, logger%para_env%source)
434 25 : CALL helium_env(1)%comm%bcast(dx, logger%para_env%source)
435 25 : CALL helium_env(1)%comm%bcast(he_mass, logger%para_env%source)
436 25 : isize = (pdx + 1)*(pdx + 2) + 1
437 100 : ALLOCATE (pot_transfer(nlines, isize))
438 25 : IF (logger%para_env%is_source()) THEN
439 13 : IF (expl_pot) THEN
440 0 : DO i = 1, nlines
441 0 : READ (input_unit, *) pot_transfer(i, :)
442 : END DO
443 : ELSE
444 1313 : DO i = 1, nlines
445 1300 : READ (input_unit, *) pot_transfer(i, 1:isize - 1)
446 : ! potential implicit, calculate it here now:
447 1313 : pot_transfer(i, isize) = helium_vij(x_spline + (i - 1)*dx)*kelvin
448 : END DO
449 : END IF
450 13 : CALL close_file(unit_number=input_unit)
451 : END IF
452 25 : CALL helium_env(1)%comm%bcast(pot_transfer, logger%para_env%source)
453 :
454 25 : CALL spline_data_create(helium_env(1)%helium%vij)
455 25 : CALL init_splinexy(helium_env(1)%helium%vij, nlines)
456 25 : helium_env(1)%helium%vij%x1 = x_spline
457 :
458 25 : CALL spline_data_create(helium_env(1)%helium%u0)
459 25 : CALL init_splinexy(helium_env(1)%helium%u0, nlines)
460 25 : helium_env(1)%helium%u0%x1 = x_spline
461 :
462 25 : CALL spline_data_create(helium_env(1)%helium%e0)
463 25 : CALL init_splinexy(helium_env(1)%helium%e0, nlines)
464 25 : helium_env(1)%helium%e0%x1 = x_spline
465 :
466 25 : isize = pdx + 1
467 25 : ntab = ((isize + 1)*isize)/2 - 1 ! -1 because endpoint approx treated separately
468 100 : ALLOCATE (helium_env(1)%helium%uoffdiag(ntab, 2, nlines))
469 75 : ALLOCATE (helium_env(1)%helium%eoffdiag(ntab, 2, nlines))
470 100 : DO j = 1, isize
471 250 : DO i = j, isize
472 150 : IF (i + j == 2) CYCLE ! endpoint approx later separately
473 125 : k = ((i - 1)*i)/2 + j
474 12625 : helium_env(1)%helium%vij%y(:) = pot_transfer(:, k)*angstrom**(2*i - 2)
475 125 : CALL init_spline(helium_env(1)%helium%vij, dx=dx)
476 12625 : helium_env(1)%helium%uoffdiag(ntab, 1, :) = helium_env(1)%helium%vij%y(:)
477 12625 : helium_env(1)%helium%uoffdiag(ntab, 2, :) = helium_env(1)%helium%vij%y2(:)
478 125 : k = k + ((isize + 1)*isize)/2
479 12625 : helium_env(1)%helium%vij%y(:) = pot_transfer(:, k)*angstrom**(2*i - 2)/kelvin
480 125 : CALL init_spline(helium_env(1)%helium%vij, dx=dx)
481 12625 : helium_env(1)%helium%eoffdiag(ntab, 1, :) = helium_env(1)%helium%vij%y(:)
482 12625 : helium_env(1)%helium%eoffdiag(ntab, 2, :) = helium_env(1)%helium%vij%y2(:)
483 225 : ntab = ntab - 1
484 : END DO
485 : END DO
486 :
487 25 : ntab = SIZE(pot_transfer, 2)
488 2525 : helium_env(1)%helium%vij%y(:) = pot_transfer(:, ntab)/kelvin
489 25 : CALL init_spline(helium_env(1)%helium%vij, dx=dx)
490 :
491 2525 : helium_env(1)%helium%u0%y(:) = pot_transfer(:, 1)
492 25 : CALL init_spline(helium_env(1)%helium%u0, dx=dx)
493 25 : k = ((isize + 1)*isize)/2 + 1
494 2525 : helium_env(1)%helium%e0%y(:) = pot_transfer(:, k)/kelvin
495 25 : CALL init_spline(helium_env(1)%helium%e0, dx=dx)
496 :
497 31 : DO k = 2, mepos
498 6 : helium_env(k)%helium%vij => helium_env(1)%helium%vij
499 6 : helium_env(k)%helium%u0 => helium_env(1)%helium%u0
500 6 : helium_env(k)%helium%e0 => helium_env(1)%helium%e0
501 6 : helium_env(k)%helium%uoffdiag => helium_env(1)%helium%uoffdiag
502 31 : helium_env(k)%helium%eoffdiag => helium_env(1)%helium%eoffdiag
503 : END DO
504 :
505 56 : DO k = 1, mepos
506 :
507 31 : helium_env(k)%helium%pdx = pdx
508 31 : helium_env(k)%helium%tau = tau
509 :
510 : ! boltzmann : Boltzmann constant [J/K]
511 : ! h_bar : Planck constant [J*s]
512 : ! J = kg*m^2/s^2
513 : ! 4He mass in [kg]
514 31 : mHe = he_mass*a_mass
515 : ! physical temperature [K]
516 31 : T = kelvin/helium_env(k)%helium%tau/helium_env(k)%helium%beads
517 : ! prefactors for calculating superfluid fractions [Angstrom^-2]
518 31 : helium_env(k)%helium%wpref = (((1e-20/h_bar)*mHe)/h_bar)*boltzmann*T
519 31 : helium_env(k)%helium%apref = (((4e-20/h_bar)*mHe)/h_bar)*boltzmann*T
520 :
521 31 : helium_env(k)%helium%he_mass_au = he_mass*massunit
522 31 : helium_env(k)%helium%hb2m = 1.0_dp/helium_env(k)%helium%he_mass_au
523 31 : helium_env(k)%helium%pweight = 0.0_dp
524 :
525 : ! Default in case sampling_method is not helium_sampling_worm.
526 31 : helium_env(k)%helium%worm_max_open_cycles = 0
527 :
528 : ! Choose sampling method:
529 : CALL section_vals_val_get(helium_section, "SAMPLING_METHOD", &
530 31 : i_val=helium_env(k)%helium%sampling_method)
531 :
532 53 : SELECT CASE (helium_env(k)%helium%sampling_method)
533 : CASE (helium_sampling_ceperley)
534 : ! check value of maxcycle
535 : CALL section_vals_val_get(helium_section, "CEPERLEY%MAX_PERM_CYCLE", &
536 22 : i_val=helium_env(k)%helium%maxcycle)
537 22 : i = helium_env(k)%helium%maxcycle
538 22 : CPASSERT(i >= 0)
539 22 : i = helium_env(k)%helium%atoms - helium_env(k)%helium%maxcycle
540 22 : CPASSERT(i >= 0)
541 :
542 : ! set m-distribution parameters
543 : CALL section_vals_val_get(helium_section, "CEPERLEY%M-SAMPLING%DISTRIBUTION-TYPE", &
544 22 : i_val=i)
545 22 : CPASSERT(i >= 1)
546 22 : CPASSERT(i <= 6)
547 22 : helium_env(k)%helium%m_dist_type = i
548 : CALL section_vals_val_get(helium_section, "CEPERLEY%M-SAMPLING%M-VALUE", &
549 22 : i_val=i)
550 22 : CPASSERT(i >= 1)
551 22 : CPASSERT(i <= helium_env(k)%helium%maxcycle)
552 22 : helium_env(k)%helium%m_value = i
553 : CALL section_vals_val_get(helium_section, "CEPERLEY%M-SAMPLING%M-RATIO", &
554 22 : r_val=rtmp)
555 22 : CPASSERT(rtmp > 0.0_dp)
556 22 : CPASSERT(rtmp <= 1.0_dp)
557 22 : helium_env(k)%helium%m_ratio = rtmp
558 :
559 : CALL section_vals_val_get(helium_section, "CEPERLEY%BISECTION", &
560 22 : i_val=helium_env(k)%helium%bisection)
561 : ! precheck bisection value (not all invalids are filtered out here yet)
562 22 : i = helium_env(k)%helium%bisection
563 22 : CPASSERT(i > 1)
564 22 : i = helium_env(k)%helium%beads - helium_env(k)%helium%bisection
565 22 : CPASSERT(i > 0)
566 : !
567 22 : itmp = helium_env(k)%helium%bisection
568 22 : rtmp = 2.0_dp**(ANINT(LOG(REAL(itmp, dp))/LOG(2.0_dp)))
569 22 : tcheck = ABS(REAL(itmp, KIND=dp) - rtmp)
570 22 : IF (tcheck > 100.0_dp*EPSILON(0.0_dp)) THEN
571 0 : msg_str = "BISECTION should be integer power of 2."
572 0 : CPABORT(msg_str)
573 : END IF
574 22 : helium_env(k)%helium%bisctlog2 = NINT(LOG(REAL(itmp, dp))/LOG(2.0_dp))
575 :
576 : CASE (helium_sampling_worm)
577 9 : NULLIFY (input_worm)
578 : input_worm => section_vals_get_subs_vals(helium_env(k)%helium%input, &
579 9 : "MOTION%PINT%HELIUM%WORM")
580 : CALL section_vals_val_get(helium_section, "WORM%CENTROID_DRMAX", &
581 9 : r_val=helium_env(k)%helium%worm_centroid_drmax)
582 :
583 : CALL section_vals_val_get(helium_section, "WORM%STAGING_L", &
584 9 : i_val=helium_env(k)%helium%worm_staging_l)
585 :
586 : CALL section_vals_val_get(helium_section, "WORM%OPEN_CLOSE_SCALE", &
587 9 : r_val=helium_env(k)%helium%worm_open_close_scale)
588 :
589 : CALL section_vals_val_get(helium_section, "WORM%ALLOW_OPEN", &
590 9 : l_val=helium_env(k)%helium%worm_allow_open)
591 9 : IF (helium_env(k)%helium%atoms == 1) THEN
592 0 : IF (helium_env(k)%helium%worm_allow_open) THEN
593 : msg_str = "Default enabled open state sampling "// &
594 0 : "for only 1 He might be inefficient."
595 0 : CPWARN(msg_str)
596 : END IF
597 : END IF
598 :
599 : CALL section_vals_val_get(helium_section, "WORM%MAX_OPEN_CYCLES", &
600 9 : i_val=helium_env(k)%helium%worm_max_open_cycles)
601 :
602 9 : IF (helium_env(k)%helium%worm_staging_l + 1 >= helium_env(k)%helium%beads) THEN
603 0 : msg_str = "STAGING_L for worm sampling is too large"
604 0 : CPABORT(msg_str)
605 9 : ELSE IF (helium_env(k)%helium%worm_staging_l < 1) THEN
606 0 : msg_str = "STAGING_L must be positive integer"
607 0 : CPABORT(msg_str)
608 : END IF
609 :
610 : CALL section_vals_val_get(helium_section, "WORM%SHOW_STATISTICS", &
611 9 : l_val=helium_env(k)%helium%worm_show_statistics)
612 :
613 : ! precompute an expensive scaling for the open and close acceptance probability
614 : ! tau is not included here, as It will be first defined in a few lines
615 9 : rtmp = 2.0_dp*pi*helium_env(k)%helium%hb2m
616 9 : rtmp = SQRT(rtmp)
617 9 : rtmp = rtmp**3
618 9 : rtmp = rtmp*helium_env(k)%helium%worm_open_close_scale
619 9 : IF (helium_env(k)%helium%periodic) THEN
620 4 : rtmp = rtmp*helium_env(k)%helium%density
621 : ELSE
622 : rtmp = rtmp*helium_env(k)%helium%atoms/ &
623 5 : (4.0_dp/3.0_dp*pi*helium_env(k)%helium%droplet_radius**3)
624 : END IF
625 9 : helium_env(k)%helium%worm_ln_openclose_scale = LOG(rtmp)
626 :
627 : ! deal with acceptance statistics without changing the ceperley stuff
628 9 : helium_env(k)%helium%maxcycle = 1
629 9 : helium_env(k)%helium%bisctlog2 = 0
630 :
631 : ! get the absolute weights of the individual moves
632 9 : helium_env(k)%helium%worm_all_limit = 0
633 : CALL section_vals_val_get(helium_section, "WORM%CENTROID_WEIGHT", &
634 9 : i_val=itmp)
635 9 : helium_env(k)%helium%worm_centroid_min = 1
636 9 : helium_env(k)%helium%worm_centroid_max = itmp
637 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
638 : CALL section_vals_val_get(helium_section, "WORM%STAGING_WEIGHT", &
639 9 : i_val=itmp)
640 9 : helium_env(k)%helium%worm_staging_min = helium_env(k)%helium%worm_centroid_max + 1
641 9 : helium_env(k)%helium%worm_staging_max = helium_env(k)%helium%worm_centroid_max + itmp
642 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
643 9 : IF (helium_env(k)%helium%worm_allow_open) THEN
644 : CALL section_vals_val_get(helium_section, "WORM%CRAWL_WEIGHT", &
645 9 : i_val=itmp)
646 9 : helium_env(k)%helium%worm_fcrawl_min = helium_env(k)%helium%worm_staging_max + 1
647 9 : helium_env(k)%helium%worm_fcrawl_max = helium_env(k)%helium%worm_staging_max + itmp
648 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
649 9 : helium_env(k)%helium%worm_bcrawl_min = helium_env(k)%helium%worm_fcrawl_max + 1
650 9 : helium_env(k)%helium%worm_bcrawl_max = helium_env(k)%helium%worm_fcrawl_max + itmp
651 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
652 : CALL section_vals_val_get(helium_section, "WORM%HEAD_TAIL_WEIGHT", &
653 9 : i_val=itmp)
654 9 : helium_env(k)%helium%worm_head_min = helium_env(k)%helium%worm_bcrawl_max + 1
655 9 : helium_env(k)%helium%worm_head_max = helium_env(k)%helium%worm_bcrawl_max + itmp
656 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
657 9 : helium_env(k)%helium%worm_tail_min = helium_env(k)%helium%worm_head_max + 1
658 9 : helium_env(k)%helium%worm_tail_max = helium_env(k)%helium%worm_head_max + itmp
659 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
660 : CALL section_vals_val_get(helium_section, "WORM%SWAP_WEIGHT", &
661 9 : i_val=itmp)
662 9 : helium_env(k)%helium%worm_swap_min = helium_env(k)%helium%worm_tail_max + 1
663 9 : helium_env(k)%helium%worm_swap_max = helium_env(k)%helium%worm_tail_max + itmp
664 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
665 : CALL section_vals_val_get(helium_section, "WORM%OPEN_CLOSE_WEIGHT", &
666 9 : i_val=itmp)
667 9 : helium_env(k)%helium%worm_open_close_min = helium_env(k)%helium%worm_swap_max + 1
668 9 : helium_env(k)%helium%worm_open_close_max = helium_env(k)%helium%worm_swap_max + itmp
669 9 : helium_env(k)%helium%worm_all_limit = helium_env(k)%helium%worm_all_limit + itmp
670 : CALL section_vals_val_get(helium_section, "WORM%CRAWL_REPETITION", &
671 9 : i_val=helium_env(k)%helium%worm_repeat_crawl)
672 : END IF
673 :
674 : !CPPostcondition(i<helium_env(k)%helium%beads,cp_failure_level,routineP,failure)
675 : ! end of worm
676 : CASE DEFAULT
677 0 : msg_str = "Unknown helium sampling method!"
678 106 : CPABORT(msg_str)
679 : END SELECT
680 :
681 : ! ALLOCATE helium-related arrays
682 31 : i = helium_env(k)%helium%atoms
683 31 : j = helium_env(k)%helium%beads
684 124 : ALLOCATE (helium_env(k)%helium%pos(3, i, j))
685 57577 : helium_env(k)%helium%pos = 0.0_dp
686 93 : ALLOCATE (helium_env(k)%helium%work(3, i, j))
687 93 : ALLOCATE (helium_env(k)%helium%ptable(helium_env(k)%helium%maxcycle + 1))
688 93 : ALLOCATE (helium_env(k)%helium%permutation(i))
689 62 : ALLOCATE (helium_env(k)%helium%iperm(i))
690 124 : ALLOCATE (helium_env(k)%helium%tmatrix(i, i))
691 124 : ALLOCATE (helium_env(k)%helium%nmatrix(i, 2*i))
692 93 : ALLOCATE (helium_env(k)%helium%pmatrix(i, i))
693 93 : ALLOCATE (helium_env(k)%helium%ipmatrix(i, i))
694 31 : itmp = helium_env(k)%helium%bisctlog2 + 2
695 124 : ALLOCATE (helium_env(k)%helium%num_accepted(itmp, helium_env(k)%helium%maxcycle))
696 93 : ALLOCATE (helium_env(k)%helium%plength_avrg(helium_env(k)%helium%atoms))
697 93 : ALLOCATE (helium_env(k)%helium%plength_inst(helium_env(k)%helium%atoms))
698 93 : ALLOCATE (helium_env(k)%helium%atom_plength(helium_env(k)%helium%atoms))
699 31 : IF (helium_env(k)%helium%worm_max_open_cycles > 0) THEN
700 0 : ALLOCATE (helium_env(k)%helium%savepermutation(i))
701 0 : ALLOCATE (helium_env(k)%helium%saveiperm(i))
702 0 : ALLOCATE (helium_env(k)%helium%savepos(3, i, j))
703 : END IF
704 :
705 : ! check whether rdfs should be calculated and printed
706 31 : helium_env(k)%helium%rdf_present = helium_property_active(helium_env(k)%helium, "RDF")
707 31 : IF (helium_env(k)%helium%rdf_present) THEN
708 : ! allocate & initialize rdf related data structures
709 2 : CALL helium_rdf_init(helium_env(k)%helium)
710 : END IF
711 :
712 : ! check whether densities should be calculated and printed
713 31 : helium_env(k)%helium%rho_present = helium_property_active(helium_env(k)%helium, "RHO")
714 56 : IF (helium_env(k)%helium%rho_present) THEN
715 : ! allocate & initialize density related data structures
716 2 : NULLIFY (helium_env(k)%helium%rho_property)
717 2 : CALL helium_rho_init(helium_env(k)%helium)
718 : END IF
719 :
720 : END DO
721 :
722 : ! restore averages calculated in previous runs
723 25 : CALL helium_averages_restore(helium_env)
724 :
725 56 : DO k = 1, mepos
726 : ! fill in the solute-related data structures
727 31 : helium_env(k)%helium%e_corr = 0.0_dp
728 31 : IF (helium_env(k)%helium%solute_present) THEN
729 21 : IF (helium_env(k)%helium%solute_beads > helium_env(k)%helium%beads) THEN
730 : ! Imaginary time striding for solute:
731 : helium_env(k)%helium%bead_ratio = helium_env(k)%helium%solute_beads/ &
732 2 : helium_env(k)%helium%beads
733 : ! check if bead numbers are commensurate:
734 2 : i = helium_env(k)%helium%bead_ratio*helium_env(k)%helium%beads - helium_env(k)%helium%solute_beads
735 2 : IF (i /= 0) THEN
736 0 : msg_str = "Adjust number of solute beads to multiple of solvent beads."
737 0 : CPABORT(msg_str)
738 : END IF
739 : msg_str = "Using multiple-time stepping in imaginary time for solute to couple "// &
740 : "to fewer solvent beads, e.g. for factor 3: "// &
741 : "he_1 - 3*sol_1; he_2 - 3*sol_4... "// &
742 2 : "Avoid too large coupling factors."
743 2 : CPWARN(msg_str)
744 19 : ELSE IF (helium_env(k)%helium%solute_beads < helium_env(k)%helium%beads) THEN
745 : ! Imaginary time striding for solvent:
746 : helium_env(k)%helium%bead_ratio = helium_env(k)%helium%beads/ &
747 18 : helium_env(k)%helium%solute_beads
748 : ! check if bead numbers are commensurate:
749 18 : i = helium_env(k)%helium%bead_ratio*helium_env(k)%helium%solute_beads - helium_env(k)%helium%beads
750 18 : IF (i /= 0) THEN
751 0 : msg_str = "Adjust number of solvent beads to multiple of solute beads."
752 0 : CPABORT(msg_str)
753 : END IF
754 : msg_str = "Coupling solvent beads to fewer solute beads via "// &
755 : "direct coupling, e.g. for factor 3: "// &
756 18 : "sol_1 - he_1,2,3; sol_2 - he_4,5,6..."
757 18 : CPWARN(msg_str)
758 : END IF
759 : !TODO Adjust helium bead number if not comm. and if coords not given expl.
760 :
761 : ! check if tau, temperature and bead number are consistent:
762 21 : tcheck = ABS((helium_env(k)%helium%tau*helium_env(k)%helium%beads - solute%beta)/solute%beta)
763 21 : IF (tcheck > 1.0e-14_dp) THEN
764 0 : msg_str = "Tau, temperature and bead number are inconsistent."
765 0 : CPABORT(msg_str)
766 : END IF
767 :
768 21 : CALL helium_set_solute_indices(helium_env(k)%helium, solute)
769 21 : CALL helium_set_solute_cell(helium_env(k)%helium, solute)
770 :
771 : ! set the interaction potential type
772 : CALL section_vals_val_get(helium_section, "SOLUTE_INTERACTION", &
773 21 : i_val=helium_env(k)%helium%solute_interaction)
774 21 : IF (helium_env(k)%helium%solute_interaction .EQ. helium_solute_intpot_nnp) THEN
775 1 : IF (k == 1) THEN
776 1 : NULLIFY (nnp_section)
777 1 : nnp_section => section_vals_get_subs_vals(helium_section, "NNP")
778 1 : CALL section_vals_get(nnp_section, explicit=explicit)
779 1 : msg_str = "NNP section not explicitly stated. Using default file names."
780 1 : CPWARN_IF(.NOT. explicit, msg_str)
781 : END IF
782 1 : ALLOCATE (helium_env(k)%helium%nnp)
783 1 : CALL cp_logger_create(tmplogger, para_env=helium_env(k)%comm, template_logger=logger)
784 1 : CALL cp_add_default_logger(tmplogger)
785 1 : CALL helium_init_nnp(helium_env(k)%helium, helium_env(k)%helium%nnp, nnp_section)
786 1 : CALL cp_rm_default_logger()
787 1 : CALL cp_logger_release(tmplogger)
788 : END IF
789 21 : IF (helium_env(k)%helium%solute_interaction .EQ. helium_solute_intpot_none) THEN
790 : WRITE (msg_str, '(A,I0,A)') &
791 : "Solute found but no helium-solute interaction selected "// &
792 0 : "(see SOLUTE_INTERACTION keyword)"
793 0 : CPABORT(msg_str)
794 : END IF
795 :
796 : ! ALLOCATE solute-related arrays
797 : ALLOCATE (helium_env(k)%helium%force_avrg(helium_env(k)%helium%solute_beads, &
798 84 : helium_env(k)%helium%solute_atoms*3))
799 : ALLOCATE (helium_env(k)%helium%force_inst(helium_env(k)%helium%solute_beads, &
800 84 : helium_env(k)%helium%solute_atoms*3))
801 :
802 63 : ALLOCATE (helium_env(k)%helium%rtmp_p_ndim_1d(solute%p*solute%ndim))
803 63 : ALLOCATE (helium_env(k)%helium%rtmp_p_ndim_np_1d(solute%p*solute%ndim*helium_env(k)%helium%num_env))
804 84 : ALLOCATE (helium_env(k)%helium%rtmp_p_ndim_2d(solute%p, solute%ndim))
805 :
806 : ELSE
807 10 : helium_env(k)%helium%bead_ratio = 0
808 10 : IF (helium_env(k)%helium%periodic) THEN
809 : ! this assumes a specific potential (and its ugly):
810 10 : x1 = angstrom*0.5_dp*helium_env(k)%helium%cell_size
811 : ! 10.8 is in Kelvin, x1 needs to be in Angstrom,
812 : ! since 2.9673 is in Angstrom
813 : helium_env(k)%helium%e_corr = (twopi*helium_env(k)%helium%density/angstrom**3*10.8_dp* &
814 : (544850.4_dp*EXP(-13.353384_dp*x1/2.9673_dp)*(2.9673_dp/13.353384_dp)**3* &
815 : (2.0_dp + 2.0_dp*13.353384_dp*x1/2.9673_dp + (13.353384_dp*x1/2.9673_dp)**2) - &
816 : (((0.1781_dp/7.0_dp*(2.9673_dp/x1)**2 + 0.4253785_dp/5.0_dp)*(2.9673_dp/x1)**2 + &
817 10 : 1.3732412_dp/3.0_dp)*(2.9673_dp/x1)**3)*2.9673_dp**3))/kelvin
818 : END IF
819 : END IF
820 :
821 : ! ALLOCATE temporary arrays
822 93 : ALLOCATE (helium_env(k)%helium%itmp_atoms_1d(helium_env(k)%helium%atoms))
823 93 : ALLOCATE (helium_env(k)%helium%ltmp_atoms_1d(helium_env(k)%helium%atoms))
824 93 : ALLOCATE (helium_env(k)%helium%itmp_atoms_np_1d(helium_env(k)%helium%atoms*helium_env(k)%helium%num_env))
825 93 : ALLOCATE (helium_env(k)%helium%rtmp_3_np_1d(3*helium_env(k)%helium%num_env))
826 : ALLOCATE (helium_env(k)%helium%rtmp_3_atoms_beads_1d(3*helium_env(k)%helium%atoms* &
827 93 : helium_env(k)%helium%beads))
828 : ALLOCATE (helium_env(k)%helium%rtmp_3_atoms_beads_np_1d(3*helium_env(k)%helium%atoms* &
829 93 : helium_env(k)%helium%beads*helium_env(k)%helium%num_env))
830 : ALLOCATE (helium_env(k)%helium%ltmp_3_atoms_beads_3d(3, helium_env(k)%helium%atoms, &
831 124 : helium_env(k)%helium%beads))
832 56 : IF (k .EQ. 1) THEN
833 25 : CALL helium_write_setup(helium_env(k)%helium)
834 : END IF
835 : END DO
836 25 : DEALLOCATE (pot_transfer)
837 : ELSE
838 : ! Deallocate env_all on processors without helium_env
839 1 : DEALLOCATE (env_all)
840 : END IF ! mepos .GT. 0
841 :
842 26 : NULLIFY (env_all)
843 26 : CALL timestop(handle)
844 :
845 26 : RETURN
846 104 : END SUBROUTINE helium_create
847 :
848 : ! ***************************************************************************
849 : !> \brief Releases helium_solvent_type
850 : !> \param helium_env ...
851 : !> \par History
852 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
853 : !> \author hforbert
854 : ! **************************************************************************************************
855 26 : SUBROUTINE helium_release(helium_env)
856 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
857 :
858 : INTEGER :: k
859 :
860 26 : IF (ASSOCIATED(helium_env)) THEN
861 56 : DO k = 1, SIZE(helium_env)
862 31 : IF (k .EQ. 1) THEN
863 25 : CALL helium_env(k)%comm%free()
864 25 : DEALLOCATE (helium_env(k)%comm)
865 25 : DEALLOCATE (helium_env(k)%env_all)
866 : END IF
867 31 : NULLIFY (helium_env(k)%env_all)
868 :
869 : ! DEALLOCATE temporary arrays
870 0 : DEALLOCATE ( &
871 : helium_env(k)%helium%ltmp_3_atoms_beads_3d, &
872 0 : helium_env(k)%helium%rtmp_3_atoms_beads_np_1d, &
873 0 : helium_env(k)%helium%rtmp_3_atoms_beads_1d, &
874 0 : helium_env(k)%helium%rtmp_3_np_1d, &
875 0 : helium_env(k)%helium%itmp_atoms_np_1d, &
876 0 : helium_env(k)%helium%ltmp_atoms_1d, &
877 31 : helium_env(k)%helium%itmp_atoms_1d)
878 :
879 : NULLIFY ( &
880 : helium_env(k)%helium%ltmp_3_atoms_beads_3d, &
881 31 : helium_env(k)%helium%rtmp_3_atoms_beads_np_1d, &
882 31 : helium_env(k)%helium%rtmp_3_atoms_beads_1d, &
883 31 : helium_env(k)%helium%rtmp_3_np_1d, &
884 31 : helium_env(k)%helium%itmp_atoms_np_1d, &
885 31 : helium_env(k)%helium%ltmp_atoms_1d, &
886 31 : helium_env(k)%helium%itmp_atoms_1d &
887 31 : )
888 :
889 31 : IF (helium_env(k)%helium%solute_present) THEN
890 : ! DEALLOCATE solute-related arrays
891 0 : DEALLOCATE ( &
892 : helium_env(k)%helium%rtmp_p_ndim_2d, &
893 0 : helium_env(k)%helium%rtmp_p_ndim_np_1d, &
894 0 : helium_env(k)%helium%rtmp_p_ndim_1d, &
895 0 : helium_env(k)%helium%force_inst, &
896 21 : helium_env(k)%helium%force_avrg)
897 : NULLIFY ( &
898 : helium_env(k)%helium%rtmp_p_ndim_2d, &
899 21 : helium_env(k)%helium%rtmp_p_ndim_np_1d, &
900 21 : helium_env(k)%helium%rtmp_p_ndim_1d, &
901 21 : helium_env(k)%helium%force_inst, &
902 21 : helium_env(k)%helium%force_avrg)
903 : END IF
904 :
905 31 : IF (helium_env(k)%helium%rho_present) THEN
906 0 : DEALLOCATE ( &
907 : helium_env(k)%helium%rho_rstr, &
908 0 : helium_env(k)%helium%rho_accu, &
909 0 : helium_env(k)%helium%rho_inst, &
910 2 : helium_env(k)%helium%rho_incr)
911 : NULLIFY ( &
912 : helium_env(k)%helium%rho_rstr, &
913 2 : helium_env(k)%helium%rho_accu, &
914 2 : helium_env(k)%helium%rho_inst, &
915 2 : helium_env(k)%helium%rho_incr)
916 : ! DEALLOCATE everything
917 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_atom_number)%filename_suffix)
918 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_atom_number)%component_name)
919 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_atom_number)%component_index)
920 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_atom_number)%filename_suffix)
921 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_atom_number)%component_name)
922 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_atom_number)%component_index)
923 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_number)%filename_suffix)
924 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_number)%component_name)
925 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_number)%component_index)
926 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_number)%filename_suffix)
927 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_number)%component_name)
928 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_number)%component_index)
929 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_cycle)%filename_suffix)
930 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_cycle)%component_name)
931 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_winding_cycle)%component_index)
932 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_cycle)%filename_suffix)
933 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_cycle)%component_name)
934 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_winding_cycle)%component_index)
935 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_projected_area)%filename_suffix)
936 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_projected_area)%component_name)
937 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_projected_area)%component_index)
938 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_projected_area)%filename_suffix)
939 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_projected_area)%component_name)
940 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_projected_area)%component_index)
941 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%filename_suffix)
942 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%component_name)
943 2 : DEALLOCATE (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%component_index)
944 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%filename_suffix)
945 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%component_name)
946 2 : NULLIFY (helium_env(k)%helium%rho_property(rho_moment_of_inertia)%component_index)
947 2 : DEALLOCATE (helium_env(k)%helium%rho_property)
948 2 : NULLIFY (helium_env(k)%helium%rho_property)
949 : END IF
950 :
951 31 : CALL helium_rdf_release(helium_env(k)%helium)
952 :
953 : ! DEALLOCATE helium-related arrays
954 0 : DEALLOCATE ( &
955 : helium_env(k)%helium%atom_plength, &
956 0 : helium_env(k)%helium%plength_inst, &
957 0 : helium_env(k)%helium%plength_avrg, &
958 0 : helium_env(k)%helium%num_accepted, &
959 0 : helium_env(k)%helium%ipmatrix, &
960 0 : helium_env(k)%helium%pmatrix, &
961 0 : helium_env(k)%helium%nmatrix, &
962 0 : helium_env(k)%helium%tmatrix, &
963 0 : helium_env(k)%helium%iperm, &
964 0 : helium_env(k)%helium%permutation, &
965 0 : helium_env(k)%helium%ptable, &
966 0 : helium_env(k)%helium%work, &
967 31 : helium_env(k)%helium%pos)
968 31 : IF (helium_env(k)%helium%worm_max_open_cycles > 0) THEN
969 0 : DEALLOCATE (helium_env(k)%helium%saveiperm, &
970 0 : helium_env(k)%helium%savepermutation, &
971 0 : helium_env(k)%helium%savepos)
972 : END IF
973 : NULLIFY ( &
974 : helium_env(k)%helium%atom_plength, &
975 31 : helium_env(k)%helium%plength_inst, &
976 31 : helium_env(k)%helium%plength_avrg, &
977 31 : helium_env(k)%helium%num_accepted, &
978 31 : helium_env(k)%helium%ipmatrix, &
979 31 : helium_env(k)%helium%pmatrix, &
980 31 : helium_env(k)%helium%nmatrix, &
981 31 : helium_env(k)%helium%tmatrix, &
982 31 : helium_env(k)%helium%iperm, &
983 31 : helium_env(k)%helium%saveiperm, &
984 31 : helium_env(k)%helium%permutation, &
985 31 : helium_env(k)%helium%savepermutation, &
986 31 : helium_env(k)%helium%ptable, &
987 31 : helium_env(k)%helium%work, &
988 31 : helium_env(k)%helium%pos, &
989 31 : helium_env(k)%helium%savepos &
990 31 : )
991 :
992 31 : IF (k == 1) THEN
993 25 : CALL spline_data_release(helium_env(k)%helium%vij)
994 25 : CALL spline_data_release(helium_env(k)%helium%u0)
995 25 : CALL spline_data_release(helium_env(k)%helium%e0)
996 25 : DEALLOCATE (helium_env(k)%helium%uoffdiag)
997 25 : DEALLOCATE (helium_env(k)%helium%eoffdiag)
998 : END IF
999 : NULLIFY (helium_env(k)%helium%uoffdiag, &
1000 31 : helium_env(k)%helium%eoffdiag, &
1001 31 : helium_env(k)%helium%vij, &
1002 31 : helium_env(k)%helium%u0, &
1003 31 : helium_env(k)%helium%e0)
1004 :
1005 31 : DEALLOCATE (helium_env(k)%helium%rng_stream_uniform)
1006 31 : DEALLOCATE (helium_env(k)%helium%rng_stream_gaussian)
1007 :
1008 : ! deallocate solute-related arrays
1009 31 : IF (helium_env(k)%helium%solute_present) THEN
1010 21 : DEALLOCATE (helium_env(k)%helium%solute_element)
1011 21 : NULLIFY (helium_env(k)%helium%solute_element)
1012 : END IF
1013 :
1014 : ! Deallocate everything from the helium_set_solute_indices
1015 31 : IF (ASSOCIATED(helium_env(k)%helium%ename)) THEN
1016 0 : DEALLOCATE (helium_env(k)%helium%ename)
1017 0 : NULLIFY (helium_env(k)%helium%ename)
1018 : END IF
1019 :
1020 : ! NNP interaction
1021 31 : IF (ASSOCIATED(helium_env(k)%helium%nnp)) THEN
1022 1 : CALL nnp_env_release(helium_env(k)%helium%nnp)
1023 1 : DEALLOCATE (helium_env(k)%helium%nnp)
1024 1 : NULLIFY (helium_env(k)%helium%nnp)
1025 : END IF
1026 31 : IF (ASSOCIATED(helium_env(k)%helium%nnp_sr_cut)) THEN
1027 1 : DEALLOCATE (helium_env(k)%helium%nnp_sr_cut)
1028 1 : NULLIFY (helium_env(k)%helium%nnp_sr_cut)
1029 : END IF
1030 :
1031 56 : DEALLOCATE (helium_env(k)%helium)
1032 :
1033 : END DO
1034 :
1035 25 : DEALLOCATE (helium_env)
1036 : NULLIFY (helium_env)
1037 : END IF
1038 26 : RETURN
1039 : END SUBROUTINE helium_release
1040 :
1041 : ! ***************************************************************************
1042 : !> \brief Initialize helium data structures.
1043 : !> \param helium_env ...
1044 : !> \param pint_env ...
1045 : !> \par History
1046 : !> removed references to pint_env_type data structure [lwalewski]
1047 : !> 2009-11-10 init/restore coords, perm, RNG and forces [lwalewski]
1048 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1049 : !> \author hforbert
1050 : !> \note Initializes helium coordinates either as random positions or from
1051 : !> HELIUM%COORD section if it's present in the input file.
1052 : !> Initializes helium permutation state as identity permutation or
1053 : !> from HELIUM%PERM section if it's present in the input file.
1054 : ! **************************************************************************************************
1055 26 : SUBROUTINE helium_init(helium_env, pint_env)
1056 :
1057 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1058 : TYPE(pint_env_type), INTENT(IN) :: pint_env
1059 :
1060 : CHARACTER(len=*), PARAMETER :: routineN = 'helium_init'
1061 :
1062 : INTEGER :: handle, k
1063 : LOGICAL :: coords_presampled, explicit, presample
1064 : REAL(KIND=dp) :: initkT, solute_radius
1065 : TYPE(cp_logger_type), POINTER :: logger
1066 : TYPE(section_vals_type), POINTER :: helium_section, sec
1067 :
1068 26 : CALL timeset(routineN, handle)
1069 :
1070 26 : NULLIFY (logger)
1071 26 : logger => cp_get_default_logger()
1072 :
1073 26 : IF (ASSOCIATED(helium_env)) THEN
1074 :
1075 25 : NULLIFY (helium_section)
1076 : helium_section => section_vals_get_subs_vals(helium_env(1)%helium%input, &
1077 25 : "MOTION%PINT%HELIUM")
1078 :
1079 : ! restore RNG state
1080 25 : NULLIFY (sec)
1081 25 : sec => section_vals_get_subs_vals(helium_section, "RNG_STATE")
1082 25 : CALL section_vals_get(sec, explicit=explicit)
1083 25 : IF (explicit) THEN
1084 6 : CALL helium_rng_restore(helium_env)
1085 : ELSE
1086 19 : CALL helium_write_line("RNG state initialized as new.")
1087 : END IF
1088 :
1089 : ! init/restore permutation state
1090 25 : NULLIFY (sec)
1091 25 : sec => section_vals_get_subs_vals(helium_section, "PERM")
1092 25 : CALL section_vals_get(sec, explicit=explicit)
1093 25 : IF (explicit) THEN
1094 6 : CALL helium_perm_restore(helium_env)
1095 : ELSE
1096 19 : CALL helium_perm_init(helium_env)
1097 19 : CALL helium_write_line("Permutation state initialized as identity.")
1098 : END IF
1099 :
1100 : ! Specify if forces should be obtained as AVG or LAST
1101 56 : DO k = 1, SIZE(helium_env)
1102 : CALL section_vals_val_get(helium_section, "GET_FORCES", &
1103 56 : i_val=helium_env(k)%helium%get_helium_forces)
1104 : END DO
1105 :
1106 56 : DO k = 1, SIZE(helium_env)
1107 : ! init center of mass
1108 56 : IF (helium_env(k)%helium%solute_present) THEN
1109 84 : helium_env(k)%helium%center(:) = pint_com_pos(pint_env)
1110 : ELSE
1111 40 : helium_env(k)%helium%center(:) = (/0.0_dp, 0.0_dp, 0.0_dp/)
1112 : END IF
1113 : END DO
1114 :
1115 : ! init/restore coordinates
1116 25 : NULLIFY (sec)
1117 25 : sec => section_vals_get_subs_vals(helium_section, "COORD")
1118 25 : CALL section_vals_get(sec, explicit=explicit)
1119 25 : IF (explicit) THEN
1120 6 : CALL helium_coord_restore(helium_env)
1121 6 : CALL helium_write_line("Coordinates restarted.")
1122 : ELSE
1123 19 : CALL section_vals_val_get(helium_section, "COORD_INIT_TEMP", r_val=initkT)
1124 19 : CALL section_vals_val_get(helium_section, "SOLUTE_RADIUS", r_val=solute_radius)
1125 19 : CALL helium_coord_init(helium_env, initkT, solute_radius)
1126 19 : IF (initkT > 0.0_dp) THEN
1127 12 : CALL helium_write_line("Coordinates initialized with thermal gaussian.")
1128 : ELSE
1129 7 : CALL helium_write_line("Coordinates initialized as point particles.")
1130 : END IF
1131 : END IF
1132 :
1133 56 : DO k = 1, SIZE(helium_env)
1134 :
1135 31 : helium_env(k)%helium%worm_is_closed = .TRUE.
1136 31 : helium_env(k)%helium%worm_atom_idx = 0
1137 31 : helium_env(k)%helium%worm_bead_idx = 0
1138 :
1139 57577 : helium_env(k)%helium%work(:, :, :) = helium_env(k)%helium%pos(:, :, :)
1140 :
1141 : ! init center of mass
1142 56 : IF (helium_env(k)%helium%solute_present) THEN
1143 84 : helium_env(k)%helium%center(:) = pint_com_pos(pint_env)
1144 : ELSE
1145 10 : IF (helium_env(k)%helium%periodic) THEN
1146 40 : helium_env(k)%helium%center(:) = (/0.0_dp, 0.0_dp, 0.0_dp/)
1147 : ELSE
1148 0 : helium_env(k)%helium%center(:) = helium_com(helium_env(k)%helium)
1149 : END IF
1150 : END IF
1151 : END DO
1152 :
1153 : ! Optional helium coordinate presampling:
1154 : ! Assume IONODE to have always at least one helium_env
1155 : CALL section_vals_val_get(helium_section, "PRESAMPLE", &
1156 25 : l_val=presample)
1157 25 : coords_presampled = .FALSE.
1158 25 : IF (presample) THEN
1159 30 : DO k = 1, SIZE(helium_env)
1160 30 : helium_env(k)%helium%current_step = 0
1161 : END DO
1162 12 : CALL helium_sample(helium_env, pint_env)
1163 30 : DO k = 1, SIZE(helium_env)
1164 558 : IF (helium_env(k)%helium%solute_present) helium_env(k)%helium%force_avrg(:, :) = 0.0_dp
1165 198 : helium_env(k)%helium%energy_avrg(:) = 0.0_dp
1166 324 : helium_env(k)%helium%plength_avrg(:) = 0.0_dp
1167 228 : helium_env(k)%helium%num_accepted(:, :) = 0.0_dp
1168 : ! Reset properties accumulated over presample:
1169 72 : helium_env(k)%helium%proarea%accu(:) = 0.0_dp
1170 72 : helium_env(k)%helium%prarea2%accu(:) = 0.0_dp
1171 72 : helium_env(k)%helium%wnmber2%accu(:) = 0.0_dp
1172 72 : helium_env(k)%helium%mominer%accu(:) = 0.0_dp
1173 18 : IF (helium_env(k)%helium%rho_present) THEN
1174 4222 : helium_env(k)%helium%rho_accu(:, :, :, :) = 0.0_dp
1175 : END IF
1176 30 : IF (helium_env(k)%helium%rdf_present) THEN
1177 1002 : helium_env(k)%helium%rdf_accu(:, :) = 0.0_dp
1178 : END IF
1179 : END DO
1180 12 : coords_presampled = .TRUE.
1181 12 : CALL helium_write_line("Bead coordinates pre-sampled.")
1182 : END IF
1183 :
1184 25 : IF (helium_env(1)%helium%solute_present) THEN
1185 : ! restore helium forces
1186 15 : NULLIFY (sec)
1187 15 : sec => section_vals_get_subs_vals(helium_section, "FORCE")
1188 15 : CALL section_vals_get(sec, explicit=explicit)
1189 15 : IF (explicit) THEN
1190 2 : IF (.NOT. coords_presampled) THEN
1191 2 : CALL helium_force_restore(helium_env)
1192 : END IF
1193 : ELSE
1194 13 : IF (.NOT. coords_presampled) THEN
1195 7 : CALL helium_force_init(helium_env)
1196 7 : CALL helium_write_line("Forces on the solute initialized as zero.")
1197 : END IF
1198 : END IF
1199 : !! Update pint_env force, assume always one helium_env at IONODE
1200 : !IF (pint_env%logger%para_env%is_source()) THEN
1201 : ! pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
1202 : !END IF
1203 : !CALL pint_env%logger%para_env%bcast(pint_env%f,&
1204 : ! pint_env%logger%para_env%source)
1205 :
1206 : END IF
1207 : END IF
1208 :
1209 26 : CALL timestop(handle)
1210 :
1211 26 : RETURN
1212 : END SUBROUTINE helium_init
1213 :
1214 : ! ***************************************************************************
1215 : ! Data transfer functions.
1216 : !
1217 : ! These functions manipulate and transfer data between the runtime
1218 : ! environment and the input structure.
1219 : ! ***************************************************************************
1220 :
1221 : ! ***************************************************************************
1222 : !> \brief Initialize helium coordinates with random positions.
1223 : !> \param helium_env ...
1224 : !> \param initkT ...
1225 : !> \param solute_radius ...
1226 : !> \date 2009-11-09
1227 : !> \par History
1228 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1229 : !> 2018-04-30 Useful initialization for droplets [fuhl]
1230 : !> \author Lukasz Walewski
1231 : ! **************************************************************************************************
1232 19 : SUBROUTINE helium_coord_init(helium_env, initkT, solute_radius)
1233 : TYPE(helium_solvent_p_type), DIMENSION(:), &
1234 : INTENT(INOUT), POINTER :: helium_env
1235 : REAL(KIND=dp), INTENT(IN) :: initkT, solute_radius
1236 :
1237 : REAL(KIND=dp), PARAMETER :: minHeHedst = 5.669177966_dp
1238 :
1239 : INTEGER :: ia, ib, ic, id, iter, k
1240 : LOGICAL :: invalidpos
1241 : REAL(KIND=dp) :: minHeHedsttmp, r1, r2
1242 19 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: centroids
1243 : REAL(KIND=dp), DIMENSION(3) :: cvek, rvek, tvek
1244 :
1245 : !corresponds to three angstrom (roughly first maximum of He-He-rdf)
1246 19 : minHeHedsttmp = minHeHedst
1247 :
1248 44 : DO k = 1, SIZE(helium_env)
1249 25 : IF (helium_env(k)%helium%solute_present) THEN
1250 76 : cvek(:) = helium_env(k)%helium%center(:)
1251 19 : CALL helium_pbc(helium_env(k)%helium, cvek)
1252 : END IF
1253 :
1254 75 : ALLOCATE (centroids(3, helium_env(k)%helium%atoms))
1255 25 : IF (helium_env(k)%helium%periodic) THEN
1256 330 : DO ia = 1, helium_env(k)%helium%atoms
1257 : invalidpos = .TRUE.
1258 : iter = 0
1259 343843 : DO WHILE (invalidpos)
1260 343513 : iter = iter + 1
1261 343513 : invalidpos = .FALSE.
1262 : ! if sampling fails to often, reduce he he criterion
1263 : !CS TODO:
1264 : !minHeHedsttmp = 0.90_dp**(iter/100)*minHeHedst
1265 343513 : minHeHedsttmp = 0.90_dp**MIN(0, iter - 2)*minHeHedst
1266 1374052 : DO ic = 1, 3
1267 1030539 : r1 = helium_env(k)%helium%rng_stream_uniform%next()
1268 1030539 : r1 = 2.0_dp*r1 - 1.0_dp
1269 1030539 : r1 = r1*helium_env(k)%helium%cell_size
1270 1374052 : centroids(ic, ia) = r1
1271 : END DO
1272 : ! check if helium is outside of cell
1273 1374052 : tvek(:) = centroids(:, ia)
1274 343513 : CALL helium_pbc(helium_env(k)%helium, tvek(:))
1275 1374052 : rvek(:) = tvek(:) - centroids(:, ia)
1276 1374052 : r2 = DOT_PRODUCT(rvek, rvek)
1277 343513 : IF (r2 > 1.0_dp*10.0_dp**(-6)) THEN
1278 : invalidpos = .TRUE.
1279 : ELSE
1280 : ! check for helium-helium collision
1281 201908 : DO id = 1, ia - 1
1282 806348 : rvek = centroids(:, ia) - centroids(:, id)
1283 201587 : CALL helium_pbc(helium_env(k)%helium, rvek)
1284 806348 : r2 = DOT_PRODUCT(rvek, rvek)
1285 201908 : IF (r2 < minHeHedsttmp**2) THEN
1286 : invalidpos = .TRUE.
1287 : EXIT
1288 : END IF
1289 : END DO
1290 : END IF
1291 343833 : IF (.NOT. invalidpos) THEN
1292 : ! check if centroid collides with molecule
1293 321 : IF (helium_env(k)%helium%solute_present) THEN
1294 516 : rvek(:) = (cvek(:) - centroids(:, ia))
1295 516 : r2 = DOT_PRODUCT(rvek, rvek)
1296 129 : IF (r2 <= solute_radius**2) invalidpos = .TRUE.
1297 : END IF
1298 : END IF
1299 : END DO
1300 : END DO
1301 : ! do thermal gaussian delocalization of hot start
1302 10 : IF (initkT > 0.0_dp) THEN
1303 10 : CALL helium_thermal_gaussian_beads_init(helium_env(k)%helium, centroids, initkT)
1304 : ELSE
1305 0 : DO ia = 1, helium_env(k)%helium%atoms
1306 0 : DO ib = 1, helium_env(k)%helium%beads
1307 0 : helium_env(k)%helium%pos(:, ia, ib) = centroids(:, ia)
1308 : END DO
1309 : END DO
1310 : END IF
1311 : ! apply PBC to bead coords
1312 330 : DO ia = 1, helium_env(k)%helium%atoms
1313 7178 : DO ib = 1, helium_env(k)%helium%beads
1314 6848 : CALL helium_pbc(helium_env(k)%helium, helium_env(k)%helium%pos(:, ia, ib))
1315 : ! check if bead collides with molecule
1316 7168 : IF (helium_env(k)%helium%solute_present) THEN
1317 8192 : rvek(:) = (cvek(:) - helium_env(k)%helium%pos(:, ia, ib))
1318 8192 : r2 = DOT_PRODUCT(rvek, rvek)
1319 2048 : IF (r2 <= solute_radius**2) THEN
1320 2 : r1 = SQRT(r2)
1321 : helium_env(k)%helium%pos(:, ia, ib) = &
1322 8 : cvek(:) + solute_radius/r1*rvek(:)
1323 : END IF
1324 : END IF
1325 : END DO
1326 : END DO
1327 : ELSE
1328 213 : DO ia = 1, helium_env(k)%helium%atoms
1329 : iter = 0
1330 : invalidpos = .TRUE.
1331 601 : DO WHILE (invalidpos)
1332 388 : invalidpos = .FALSE.
1333 388 : iter = iter + 1
1334 : ! if sampling fails to often, reduce he he criterion
1335 388 : minHeHedsttmp = 0.90_dp**MIN(0, iter - 2)*minHeHedst
1336 1552 : DO ic = 1, 3
1337 1164 : rvek(ic) = helium_env(k)%helium%rng_stream_uniform%next()
1338 1164 : rvek(ic) = 2.0_dp*rvek(ic) - 1.0_dp
1339 1552 : rvek(ic) = rvek(ic)*helium_env(k)%helium%droplet_radius
1340 : END DO
1341 1552 : centroids(:, ia) = rvek(:)
1342 : ! check if helium is outside of the droplet
1343 1552 : r2 = DOT_PRODUCT(rvek, rvek)
1344 388 : IF (r2 > helium_env(k)%helium%droplet_radius**2) THEN
1345 : invalidpos = .TRUE.
1346 : ELSE
1347 : ! check for helium-helium collision
1348 2550 : DO id = 1, ia - 1
1349 9408 : rvek = centroids(:, ia) - centroids(:, id)
1350 9408 : r2 = DOT_PRODUCT(rvek, rvek)
1351 2550 : IF (r2 < minHeHedsttmp**2) THEN
1352 : invalidpos = .TRUE.
1353 : EXIT
1354 : END IF
1355 : END DO
1356 : END IF
1357 586 : IF (.NOT. invalidpos) THEN
1358 : ! make sure the helium does not collide with the solute
1359 198 : IF (helium_env(k)%helium%solute_present) THEN
1360 792 : rvek(:) = (cvek(:) - centroids(:, ia))
1361 792 : r2 = DOT_PRODUCT(rvek, rvek)
1362 198 : IF (r2 <= solute_radius**2) invalidpos = .TRUE.
1363 : END IF
1364 : END IF
1365 : END DO
1366 : END DO
1367 : ! do thermal gaussian delocalization of hot start
1368 15 : IF (initkT > 0.0_dp) THEN
1369 5 : CALL helium_thermal_gaussian_beads_init(helium_env(k)%helium, centroids, initkT)
1370 : ELSE
1371 183 : DO ia = 1, helium_env(k)%helium%atoms
1372 2951 : DO ib = 1, helium_env(k)%helium%beads
1373 11245 : helium_env(k)%helium%pos(:, ia, ib) = centroids(:, ia)
1374 : END DO
1375 : END DO
1376 : END IF
1377 213 : DO ia = 1, helium_env(k)%helium%atoms
1378 3381 : DO ib = 1, helium_env(k)%helium%beads
1379 : ! Make sure, that nothing lies outside the droplet radius
1380 : r1 = DOT_PRODUCT(helium_env(k)%helium%pos(:, ia, ib), &
1381 12672 : helium_env(k)%helium%pos(:, ia, ib))
1382 3168 : IF (r1 > helium_env(k)%helium%droplet_radius**2) THEN
1383 16 : r1 = SQRT(r1)
1384 : helium_env(k)%helium%pos(:, ia, ib) = &
1385 : helium_env(k)%helium%droplet_radius/r1* &
1386 64 : helium_env(k)%helium%pos(:, ia, ib)
1387 3152 : ELSE IF (helium_env(k)%helium%solute_present) THEN
1388 3152 : IF (r1 < solute_radius**2) THEN
1389 : !make sure that nothing lies within the molecule
1390 16 : r1 = SQRT(r1)
1391 : helium_env(k)%helium%pos(:, ia, ib) = &
1392 : solute_radius/r1* &
1393 64 : helium_env(k)%helium%pos(:, ia, ib)
1394 : END IF
1395 : END IF
1396 : ! transfer to position around actual center of droplet
1397 : helium_env(k)%helium%pos(:, ia, ib) = &
1398 : helium_env(k)%helium%pos(:, ia, ib) + &
1399 12870 : helium_env(k)%helium%center(:)
1400 : END DO
1401 : END DO
1402 : END IF
1403 40543 : helium_env(k)%helium%work = helium_env(k)%helium%pos
1404 44 : DEALLOCATE (centroids)
1405 : END DO
1406 :
1407 19 : RETURN
1408 19 : END SUBROUTINE helium_coord_init
1409 :
1410 : ! **************************************************************************************************
1411 : !> \brief ...
1412 : !> \param helium_env ...
1413 : !> \param centroids ...
1414 : !> \param kbT ...
1415 : ! **************************************************************************************************
1416 15 : SUBROUTINE helium_thermal_gaussian_beads_init(helium_env, centroids, kbT)
1417 :
1418 : TYPE(helium_solvent_type), POINTER :: helium_env
1419 : REAL(KIND=dp), DIMENSION(3, helium_env%atoms), &
1420 : INTENT(IN) :: centroids
1421 : REAL(KIND=dp), INTENT(IN) :: kbT
1422 :
1423 : INTEGER :: i, iatom, idim, imode, j, p
1424 : REAL(KIND=dp) :: invsqrtp, omega, pip, rand, sqrt2p, &
1425 : sqrtp, twopip, variance
1426 : REAL(KIND=dp), &
1427 30 : DIMENSION(helium_env%beads, helium_env%beads) :: u2x
1428 30 : REAL(KIND=dp), DIMENSION(helium_env%beads) :: nmhecoords
1429 :
1430 15 : p = helium_env%beads
1431 :
1432 15 : sqrt2p = SQRT(2.0_dp/REAL(p, dp))
1433 15 : twopip = twopi/REAL(p, dp)
1434 15 : pip = pi/REAL(p, dp)
1435 15 : sqrtp = SQRT(REAL(p, dp))
1436 15 : invsqrtp = 1.0_dp/SQRT(REAL(p, dp))
1437 :
1438 : ! set up normal mode backtransform matrix
1439 6363 : u2x(:, :) = 0.0_dp
1440 309 : u2x(:, 1) = invsqrtp
1441 159 : DO i = 2, p/2 + 1
1442 3111 : DO j = 1, p
1443 3096 : u2x(j, i) = sqrt2p*COS(twopip*(i - 1)*(j - 1))
1444 : END DO
1445 : END DO
1446 150 : DO i = p/2 + 2, p
1447 2958 : DO j = 1, p
1448 2943 : u2x(j, i) = sqrt2p*SIN(twopip*(i - 1)*(j - 1))
1449 : END DO
1450 : END DO
1451 15 : IF (MOD(p, 2) == 0) THEN
1452 9 : DO i = 1, p - 1, 2
1453 72 : u2x(i, p/2 + 1) = invsqrtp
1454 72 : u2x(i + 1, p/2 + 1) = -1.0_dp*invsqrtp
1455 : END DO
1456 : END IF
1457 :
1458 360 : DO iatom = 1, helium_env%atoms
1459 1395 : DO idim = 1, 3
1460 1035 : nmhecoords(1) = sqrtp*centroids(idim, iatom)
1461 21744 : DO imode = 2, p
1462 20709 : omega = 2.0_dp*p*kbT*SIN((imode - 1)*pip)
1463 20709 : variance = kbT*p/(helium_env%he_mass_au*omega**2)
1464 20709 : rand = helium_env%rng_stream_gaussian%next()
1465 21744 : nmhecoords(imode) = rand*SQRT(variance)
1466 : END DO
1467 522372 : helium_env%pos(idim, iatom, 1:p) = MATMUL(u2x, nmhecoords)
1468 : END DO
1469 : END DO
1470 :
1471 15 : END SUBROUTINE helium_thermal_gaussian_beads_init
1472 :
1473 : ! ***************************************************************************
1474 : !> \brief Restore coordinates from the input structure.
1475 : !> \param helium_env ...
1476 : !> \date 2009-11-09
1477 : !> \par History
1478 : !> 2010-07-22 accommodate additional cpus in the runtime wrt the
1479 : !> restart [lwalewski]
1480 : !> 2016-07-14 Modified to work with independent helium_env
1481 : !> [cschran]
1482 : !> \author Lukasz Walewski
1483 : ! **************************************************************************************************
1484 6 : SUBROUTINE helium_coord_restore(helium_env)
1485 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1486 :
1487 : CHARACTER(len=default_string_length) :: err_str, stmp
1488 : INTEGER :: actlen, i, k, msglen, num_env_restart, &
1489 : off, offset
1490 6 : LOGICAL, DIMENSION(:, :, :), POINTER :: m
1491 6 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
1492 6 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: f
1493 : TYPE(cp_logger_type), POINTER :: logger
1494 :
1495 6 : NULLIFY (logger)
1496 12 : logger => cp_get_default_logger()
1497 :
1498 : ! assign the pointer to the memory location of the input structure, where
1499 : ! the coordinates are stored
1500 6 : NULLIFY (message)
1501 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1502 : "MOTION%PINT%HELIUM%COORD%_DEFAULT_KEYWORD_", &
1503 6 : r_vals=message)
1504 :
1505 : ! check that the number of values in the input match the current runtime
1506 6 : actlen = SIZE(message)
1507 6 : num_env_restart = actlen/helium_env(1)%helium%atoms/helium_env(1)%helium%beads/3
1508 :
1509 6 : IF (num_env_restart .NE. helium_env(1)%helium%num_env) THEN
1510 0 : err_str = "Reading bead coordinates from the input file."
1511 0 : CALL helium_write_line(err_str)
1512 0 : err_str = "Number of environments in the restart...: '"
1513 0 : stmp = ""
1514 0 : WRITE (stmp, *) num_env_restart
1515 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
1516 0 : CALL helium_write_line(err_str)
1517 0 : err_str = "Number of current run time environments.: '"
1518 0 : stmp = ""
1519 0 : WRITE (stmp, *) helium_env(1)%helium%num_env
1520 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
1521 0 : CALL helium_write_line(err_str)
1522 0 : err_str = "Missmatch between number of bead coord. in input file and helium environments."
1523 0 : CPABORT(err_str)
1524 : ELSE
1525 6 : CALL helium_write_line("Bead coordinates read from the input file.")
1526 :
1527 6 : offset = 0
1528 9 : DO i = 1, logger%para_env%mepos
1529 9 : offset = offset + helium_env(1)%env_all(i)
1530 : END DO
1531 :
1532 : ! distribute coordinates over processors (no message passing)
1533 12 : DO k = 1, SIZE(helium_env)
1534 6 : msglen = helium_env(k)%helium%atoms*helium_env(k)%helium%beads*3
1535 6 : off = msglen*MOD(offset + k - 1, num_env_restart)
1536 : NULLIFY (m, f)
1537 24 : ALLOCATE (m(3, helium_env(k)%helium%atoms, helium_env(k)%helium%beads))
1538 24 : ALLOCATE (f(3, helium_env(k)%helium%atoms, helium_env(k)%helium%beads))
1539 17034 : m(:, :, :) = .TRUE.
1540 17034 : f(:, :, :) = 0.0_dp
1541 17034 : helium_env(k)%helium%pos(:, :, 1:helium_env(k)%helium%beads) = UNPACK(message(off + 1:off + msglen), MASK=m, FIELD=f)
1542 12 : DEALLOCATE (f, m)
1543 : END DO
1544 :
1545 : END IF
1546 :
1547 : NULLIFY (message)
1548 :
1549 6 : RETURN
1550 6 : END SUBROUTINE helium_coord_restore
1551 :
1552 : ! ***************************************************************************
1553 : !> \brief Initialize forces exerted on the solute
1554 : !> \param helium_env ...
1555 : !> \date 2009-11-10
1556 : !> \par History
1557 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1558 : !> \author Lukasz Walewski
1559 : ! **************************************************************************************************
1560 7 : SUBROUTINE helium_force_init(helium_env)
1561 :
1562 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1563 :
1564 : INTEGER :: k
1565 :
1566 14 : DO k = 1, SIZE(helium_env)
1567 14 : IF (helium_env(k)%helium%solute_present) THEN
1568 934 : helium_env(k)%helium%force_avrg(:, :) = 0.0_dp
1569 934 : helium_env(k)%helium%force_inst(:, :) = 0.0_dp
1570 : END IF
1571 : END DO
1572 :
1573 7 : RETURN
1574 : END SUBROUTINE helium_force_init
1575 :
1576 : ! ***************************************************************************
1577 : !> \brief Restore forces from the input structure to the runtime environment.
1578 : !> \param helium_env ...
1579 : !> \date 2009-11-10
1580 : !> \par History
1581 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1582 : !> \author Lukasz Walewski
1583 : ! **************************************************************************************************
1584 2 : SUBROUTINE helium_force_restore(helium_env)
1585 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1586 :
1587 : CHARACTER(len=default_string_length) :: err_str, stmp
1588 : INTEGER :: actlen, k, msglen
1589 2 : LOGICAL, DIMENSION(:, :), POINTER :: m
1590 2 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
1591 2 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: f
1592 :
1593 : ! assign the pointer to the memory location of the input structure, where
1594 : ! the forces are stored
1595 :
1596 2 : NULLIFY (message)
1597 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1598 : "MOTION%PINT%HELIUM%FORCE%_DEFAULT_KEYWORD_", &
1599 2 : r_vals=message)
1600 :
1601 : ! check if the destination array has correct size
1602 2 : msglen = helium_env(1)%helium%solute_atoms*helium_env(1)%helium%solute_beads*3
1603 6 : actlen = SIZE(helium_env(1)%helium%force_avrg)
1604 2 : err_str = "Invalid size of helium%force_avrg array: actual '"
1605 2 : stmp = ""
1606 2 : WRITE (stmp, *) actlen
1607 : err_str = TRIM(ADJUSTL(err_str))// &
1608 2 : TRIM(ADJUSTL(stmp))//"' but expected '"
1609 2 : stmp = ""
1610 2 : WRITE (stmp, *) msglen
1611 2 : IF (actlen /= msglen) THEN
1612 : err_str = TRIM(ADJUSTL(err_str))// &
1613 0 : TRIM(ADJUSTL(stmp))//"'."
1614 0 : CPABORT(err_str)
1615 : END IF
1616 :
1617 : ! restore forces on all processors (no message passing)
1618 : NULLIFY (m, f)
1619 8 : ALLOCATE (m(helium_env(1)%helium%solute_beads, helium_env(1)%helium%solute_atoms*3))
1620 8 : ALLOCATE (f(helium_env(1)%helium%solute_beads, helium_env(1)%helium%solute_atoms*3))
1621 92 : m(:, :) = .TRUE.
1622 92 : f(:, :) = 0.0_dp
1623 4 : DO k = 1, SIZE(helium_env)
1624 92 : helium_env(k)%helium%force_avrg(:, :) = UNPACK(message(1:msglen), MASK=m, FIELD=f)
1625 94 : helium_env(k)%helium%force_inst(:, :) = 0.0_dp
1626 : END DO
1627 2 : DEALLOCATE (f, m)
1628 :
1629 2 : CALL helium_write_line("Forces on the solute read from the input file.")
1630 :
1631 : NULLIFY (message)
1632 :
1633 2 : RETURN
1634 2 : END SUBROUTINE helium_force_restore
1635 :
1636 : ! ***************************************************************************
1637 : !> \brief Initialize the permutation state.
1638 : !> \param helium_env ...
1639 : !> \date 2009-11-05
1640 : !> \par History
1641 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1642 : !> \author Lukasz Walewski
1643 : !> \note Assign the identity permutation at each processor. Inverse
1644 : !> permutation array gets assigned as well.
1645 : ! **************************************************************************************************
1646 19 : SUBROUTINE helium_perm_init(helium_env)
1647 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1648 :
1649 : INTEGER :: ia, k
1650 :
1651 44 : DO k = 1, SIZE(helium_env)
1652 562 : DO ia = 1, helium_env(k)%helium%atoms
1653 518 : helium_env(k)%helium%permutation(ia) = ia
1654 543 : helium_env(k)%helium%iperm(ia) = ia
1655 : END DO
1656 : END DO
1657 :
1658 19 : RETURN
1659 : END SUBROUTINE helium_perm_init
1660 :
1661 : ! ***************************************************************************
1662 : !> \brief Restore permutation state from the input structure.
1663 : !> \param helium_env ...
1664 : !> \date 2009-11-05
1665 : !> \par History
1666 : !> 2010-07-22 accommodate additional cpus in the runtime wrt the
1667 : !> restart [lwalewski]
1668 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1669 : !> \author Lukasz Walewski
1670 : !> \note Transfer permutation state from the input tree to the runtime
1671 : !> data structures on each processor. Inverse permutation array is
1672 : !> recalculated according to the restored permutation state.
1673 : ! **************************************************************************************************
1674 6 : SUBROUTINE helium_perm_restore(helium_env)
1675 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1676 :
1677 : CHARACTER(len=default_string_length) :: err_str, stmp
1678 : INTEGER :: actlen, i, ia, ic, k, msglen, &
1679 : num_env_restart, off, offset
1680 6 : INTEGER, DIMENSION(:), POINTER :: message
1681 : TYPE(cp_logger_type), POINTER :: logger
1682 :
1683 6 : NULLIFY (logger)
1684 12 : logger => cp_get_default_logger()
1685 :
1686 : ! assign the pointer to the memory location of the input structure, where
1687 : ! the permutation state is stored
1688 6 : NULLIFY (message)
1689 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1690 : "MOTION%PINT%HELIUM%PERM%_DEFAULT_KEYWORD_", &
1691 6 : i_vals=message)
1692 :
1693 : ! check the number of environments presumably stored in the restart
1694 6 : actlen = SIZE(message)
1695 6 : num_env_restart = actlen/helium_env(1)%helium%atoms
1696 :
1697 : !TODO maybe add some sanity checks here:
1698 : ! is num_env_restart integer ?
1699 :
1700 6 : IF (num_env_restart .NE. helium_env(1)%helium%num_env) THEN
1701 0 : err_str = "Reading permutation state from the input file."
1702 0 : CALL helium_write_line(err_str)
1703 0 : err_str = "Number of environments in the restart...: '"
1704 0 : stmp = ""
1705 0 : WRITE (stmp, *) num_env_restart
1706 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
1707 0 : CALL helium_write_line(err_str)
1708 0 : err_str = "Number of current run time environments.: '"
1709 0 : stmp = ""
1710 0 : WRITE (stmp, *) helium_env(1)%helium%num_env
1711 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
1712 0 : CALL helium_write_line(err_str)
1713 0 : err_str = "Missmatch between number of perm. states in input file and helium environments."
1714 0 : CPABORT(err_str)
1715 : ELSE
1716 6 : CALL helium_write_line("Permutation state read from the input file.")
1717 :
1718 : ! distribute permutation state over processors
1719 6 : offset = 0
1720 9 : DO i = 1, logger%para_env%mepos
1721 9 : offset = offset + helium_env(1)%env_all(i)
1722 : END DO
1723 :
1724 12 : DO k = 1, SIZE(helium_env)
1725 6 : msglen = helium_env(k)%helium%atoms
1726 6 : off = msglen*MOD(k - 1 + offset, num_env_restart)
1727 402 : helium_env(k)%helium%permutation(:) = message(off + 1:off + msglen)
1728 : END DO
1729 : END IF
1730 :
1731 : ! recalculate the inverse permutation array
1732 12 : DO k = 1, SIZE(helium_env)
1733 198 : helium_env(k)%helium%iperm(:) = 0
1734 6 : ic = 0
1735 198 : DO ia = 1, msglen
1736 198 : IF ((helium_env(k)%helium%permutation(ia) > 0) .AND. (helium_env(k)%helium%permutation(ia) <= msglen)) THEN
1737 192 : helium_env(k)%helium%iperm(helium_env(k)%helium%permutation(ia)) = ia
1738 192 : ic = ic + 1
1739 : END IF
1740 : END DO
1741 6 : err_str = "Invalid HELIUM%PERM state: some numbers not within (1,"
1742 6 : stmp = ""
1743 6 : WRITE (stmp, *) msglen
1744 12 : IF (ic /= msglen) THEN
1745 : err_str = TRIM(ADJUSTL(err_str))// &
1746 0 : TRIM(ADJUSTL(stmp))//")."
1747 0 : CPABORT(err_str)
1748 : END IF
1749 : END DO
1750 : NULLIFY (message)
1751 :
1752 6 : RETURN
1753 6 : END SUBROUTINE helium_perm_restore
1754 :
1755 : ! ***************************************************************************
1756 : !> \brief Restore averages from the input structure
1757 : !> \param helium_env ...
1758 : !> \date 2014-06-25
1759 : !> \par History
1760 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1761 : !> \author Lukasz Walewski
1762 : ! **************************************************************************************************
1763 125 : SUBROUTINE helium_averages_restore(helium_env)
1764 :
1765 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1766 :
1767 : INTEGER :: i, k, msglen, num_env_restart, off, &
1768 : offset
1769 : LOGICAL :: explicit
1770 25 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
1771 : TYPE(cp_logger_type), POINTER :: logger
1772 :
1773 25 : NULLIFY (logger)
1774 50 : logger => cp_get_default_logger()
1775 :
1776 25 : offset = 0
1777 37 : DO i = 1, logger%para_env%mepos
1778 37 : offset = offset + helium_env(1)%env_all(i)
1779 : END DO
1780 :
1781 : ! restore projected area
1782 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1783 : "MOTION%PINT%HELIUM%AVERAGES%PROJECTED_AREA", &
1784 25 : explicit=explicit)
1785 25 : IF (explicit) THEN
1786 0 : NULLIFY (message)
1787 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1788 : "MOTION%PINT%HELIUM%AVERAGES%PROJECTED_AREA", &
1789 0 : r_vals=message)
1790 0 : num_env_restart = SIZE(message)/3 ! apparent number of environments
1791 0 : msglen = 3
1792 0 : DO k = 1, SIZE(helium_env)
1793 0 : off = msglen*MOD(offset + k - 1, num_env_restart)
1794 0 : helium_env(k)%helium%proarea%rstr(:) = message(off + 1:off + msglen)
1795 : END DO
1796 : ELSE
1797 56 : DO k = 1, SIZE(helium_env)
1798 149 : helium_env(k)%helium%proarea%rstr(:) = 0.0_dp
1799 : END DO
1800 : END IF
1801 :
1802 : ! restore projected area squared
1803 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1804 : "MOTION%PINT%HELIUM%AVERAGES%PROJECTED_AREA_2", &
1805 25 : explicit=explicit)
1806 25 : IF (explicit) THEN
1807 0 : NULLIFY (message)
1808 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1809 : "MOTION%PINT%HELIUM%AVERAGES%PROJECTED_AREA_2", &
1810 0 : r_vals=message)
1811 0 : num_env_restart = SIZE(message)/3 ! apparent number of environments
1812 0 : msglen = 3
1813 0 : DO k = 1, SIZE(helium_env)
1814 0 : off = msglen*MOD(offset + k - 1, num_env_restart)
1815 0 : helium_env(k)%helium%prarea2%rstr(:) = message(off + 1:off + msglen)
1816 : END DO
1817 : ELSE
1818 56 : DO k = 1, SIZE(helium_env)
1819 149 : helium_env(k)%helium%prarea2%rstr(:) = 0.0_dp
1820 : END DO
1821 : END IF
1822 :
1823 : ! restore winding number squared
1824 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1825 : "MOTION%PINT%HELIUM%AVERAGES%WINDING_NUMBER_2", &
1826 25 : explicit=explicit)
1827 25 : IF (explicit) THEN
1828 0 : NULLIFY (message)
1829 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1830 : "MOTION%PINT%HELIUM%AVERAGES%WINDING_NUMBER_2", &
1831 0 : r_vals=message)
1832 0 : num_env_restart = SIZE(message)/3 ! apparent number of environments
1833 0 : msglen = 3
1834 0 : DO k = 1, SIZE(helium_env)
1835 0 : off = msglen*MOD(offset + k - 1, num_env_restart)
1836 0 : helium_env(k)%helium%wnmber2%rstr(:) = message(off + 1:off + msglen)
1837 : END DO
1838 : ELSE
1839 56 : DO k = 1, SIZE(helium_env)
1840 149 : helium_env(k)%helium%wnmber2%rstr(:) = 0.0_dp
1841 : END DO
1842 : END IF
1843 :
1844 : ! restore moment of inertia
1845 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1846 : "MOTION%PINT%HELIUM%AVERAGES%MOMENT_OF_INERTIA", &
1847 25 : explicit=explicit)
1848 25 : IF (explicit) THEN
1849 0 : NULLIFY (message)
1850 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1851 : "MOTION%PINT%HELIUM%AVERAGES%MOMENT_OF_INERTIA", &
1852 0 : r_vals=message)
1853 0 : num_env_restart = SIZE(message)/3 ! apparent number of environments
1854 0 : msglen = 3
1855 0 : DO k = 1, SIZE(helium_env)
1856 0 : off = msglen*MOD(offset + k - 1, num_env_restart)
1857 0 : helium_env(k)%helium%mominer%rstr(:) = message(off + 1:off + msglen)
1858 : END DO
1859 : ELSE
1860 56 : DO k = 1, SIZE(helium_env)
1861 149 : helium_env(k)%helium%mominer%rstr(:) = 0.0_dp
1862 : END DO
1863 : END IF
1864 :
1865 25 : IF (helium_env(1)%helium%rdf_present) THEN
1866 2 : CALL helium_rdf_restore(helium_env)
1867 : END IF
1868 :
1869 25 : IF (helium_env(1)%helium%rho_present) THEN
1870 : ! restore densities
1871 2 : CALL helium_rho_restore(helium_env)
1872 : END IF
1873 :
1874 : ! get the weighting factor
1875 56 : DO k = 1, SIZE(helium_env)
1876 : CALL section_vals_val_get( &
1877 : helium_env(k)%helium%input, &
1878 : "MOTION%PINT%HELIUM%AVERAGES%IWEIGHT", &
1879 31 : i_val=helium_env(k)%helium%averages_iweight)
1880 :
1881 : ! set the flag indicating whether the averages have been restarted
1882 : CALL section_vals_val_get( &
1883 : helium_env(k)%helium%input, &
1884 : "EXT_RESTART%RESTART_HELIUM_AVERAGES", &
1885 56 : l_val=helium_env(k)%helium%averages_restarted)
1886 : END DO
1887 :
1888 25 : RETURN
1889 25 : END SUBROUTINE helium_averages_restore
1890 :
1891 : ! ***************************************************************************
1892 : !> \brief Create RNG streams and initialize their state.
1893 : !> \param helium_env ...
1894 : !> \date 2009-11-04
1895 : !> \par History
1896 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1897 : !> \author Lukasz Walewski
1898 : !> \note TODO: This function shouldn't create (allocate) objects! Only
1899 : !> initialization, i.e. setting the seed values etc, should be done
1900 : !> here, allocation should be moved to helium_create
1901 : ! **************************************************************************************************
1902 25 : SUBROUTINE helium_rng_init(helium_env)
1903 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1904 :
1905 : INTEGER :: helium_seed, i, offset
1906 : REAL(KIND=dp), DIMENSION(3, 2) :: initial_seed
1907 : TYPE(cp_logger_type), POINTER :: logger
1908 25 : TYPE(rng_stream_p_type), DIMENSION(:), POINTER :: gaussian_array, uniform_array
1909 :
1910 25 : NULLIFY (logger)
1911 50 : logger => cp_get_default_logger()
1912 25 : IF (logger%para_env%is_source()) THEN
1913 : CALL section_vals_val_get(helium_env(1)%helium%input, &
1914 : "MOTION%PINT%HELIUM%RNG_SEED", &
1915 13 : i_val=helium_seed)
1916 : END IF
1917 : CALL helium_env(1)%comm%bcast(helium_seed, &
1918 25 : logger%para_env%source)
1919 225 : initial_seed(:, :) = REAL(helium_seed, dp)
1920 :
1921 : ALLOCATE (uniform_array(helium_env(1)%helium%num_env), &
1922 222 : gaussian_array(helium_env(1)%helium%num_env))
1923 86 : DO i = 1, helium_env(1)%helium%num_env
1924 3014 : ALLOCATE (uniform_array(i)%stream, gaussian_array(i)%stream)
1925 : END DO
1926 :
1927 : ! Create num_env RNG streams on processor all processors
1928 : ! and distribute them so, that each processor gets unique
1929 : ! RN sequences for his helium environments
1930 : ! COMMENT: rng_stream can not be used with mp_bcast
1931 :
1932 : uniform_array(1)%stream = rng_stream_type(name="helium_rns_uniform", &
1933 : distribution_type=UNIFORM, &
1934 : extended_precision=.TRUE., &
1935 25 : seed=initial_seed)
1936 :
1937 : gaussian_array(1)%stream = rng_stream_type(name="helium_rns_gaussian", &
1938 : distribution_type=GAUSSIAN, &
1939 : extended_precision=.TRUE., &
1940 25 : last_rng_stream=uniform_array(1)%stream)
1941 61 : DO i = 2, helium_env(1)%helium%num_env
1942 : uniform_array(i)%stream = rng_stream_type(name="helium_rns_uniform", &
1943 : distribution_type=UNIFORM, &
1944 : extended_precision=.TRUE., &
1945 36 : last_rng_stream=gaussian_array(i - 1)%stream)
1946 :
1947 : gaussian_array(i)%stream = rng_stream_type(name="helium_rns_uniform", &
1948 : distribution_type=GAUSSIAN, &
1949 : extended_precision=.TRUE., &
1950 61 : last_rng_stream=uniform_array(i)%stream)
1951 : END DO
1952 :
1953 25 : offset = 0
1954 37 : DO i = 1, logger%para_env%mepos
1955 37 : offset = offset + helium_env(1)%env_all(i)
1956 : END DO
1957 :
1958 56 : DO i = 1, SIZE(helium_env)
1959 : NULLIFY (helium_env(i)%helium%rng_stream_uniform, &
1960 31 : helium_env(i)%helium%rng_stream_gaussian)
1961 31 : helium_env(i)%helium%rng_stream_uniform => uniform_array(offset + i)%stream
1962 56 : helium_env(i)%helium%rng_stream_gaussian => gaussian_array(offset + i)%stream
1963 : END DO
1964 :
1965 86 : DO i = 1, helium_env(1)%helium%num_env
1966 61 : IF (i .LE. offset .OR. i .GT. offset + SIZE(helium_env)) THEN
1967 : ! only deallocate pointers here which were not passed on to helium_env(*)%helium
1968 30 : DEALLOCATE (uniform_array(i)%stream)
1969 30 : DEALLOCATE (gaussian_array(i)%stream)
1970 : END IF
1971 61 : NULLIFY (uniform_array(i)%stream)
1972 86 : NULLIFY (gaussian_array(i)%stream)
1973 : END DO
1974 :
1975 25 : DEALLOCATE (uniform_array)
1976 25 : DEALLOCATE (gaussian_array)
1977 25 : END SUBROUTINE helium_rng_init
1978 :
1979 : ! ***************************************************************************
1980 : !> \brief Restore RNG state from the input structure.
1981 : !> \param helium_env ...
1982 : !> \date 2009-11-04
1983 : !> \par History
1984 : !> 2010-07-22 Create new rng streams if more cpus available in the
1985 : !> runtime than in the restart [lwalewski]
1986 : !> 2016-04-18 Modified for independet number of helium_env [cschran]
1987 : !> \author Lukasz Walewski
1988 : ! **************************************************************************************************
1989 6 : SUBROUTINE helium_rng_restore(helium_env)
1990 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1991 :
1992 : CHARACTER(len=default_string_length) :: err_str, stmp
1993 : INTEGER :: actlen, i, k, msglen, num_env_restart, &
1994 : off, offset
1995 : LOGICAL :: lbf
1996 : LOGICAL, DIMENSION(3, 2) :: m
1997 : REAL(KIND=dp) :: bf, bu
1998 : REAL(KIND=dp), DIMENSION(3, 2) :: bg, cg, f, ig
1999 6 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
2000 : TYPE(cp_logger_type), POINTER :: logger
2001 :
2002 6 : NULLIFY (logger)
2003 12 : logger => cp_get_default_logger()
2004 :
2005 : ! assign the pointer to the memory location of the input structure
2006 : ! where the RNG state is stored
2007 6 : NULLIFY (message)
2008 : CALL section_vals_val_get(helium_env(1)%helium%input, &
2009 : "MOTION%PINT%HELIUM%RNG_STATE%_DEFAULT_KEYWORD_", &
2010 6 : r_vals=message)
2011 :
2012 : ! check the number of environments presumably stored in the restart
2013 6 : actlen = SIZE(message)
2014 6 : num_env_restart = actlen/40
2015 :
2016 : ! check, if RNG restart has the same dimension as helium%num_env
2017 6 : IF (num_env_restart .NE. helium_env(1)%helium%num_env) THEN
2018 0 : err_str = "Reading RNG state from the input file."
2019 0 : CALL helium_write_line(err_str)
2020 0 : err_str = "Number of environments in the restart...: '"
2021 0 : stmp = ""
2022 0 : WRITE (stmp, *) num_env_restart
2023 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
2024 0 : CALL helium_write_line(err_str)
2025 0 : err_str = "Number of current run time environments.: '"
2026 0 : stmp = ""
2027 0 : WRITE (stmp, *) helium_env(1)%helium%num_env
2028 0 : err_str = TRIM(ADJUSTL(err_str))//TRIM(ADJUSTL(stmp))//"'."
2029 0 : CALL helium_write_line(err_str)
2030 0 : err_str = "Missmatch between number of RNG states in input file and helium environments."
2031 0 : CPABORT(err_str)
2032 : ELSE
2033 6 : CALL helium_write_line("RNG state read from the input file.")
2034 :
2035 : ! unpack the buffer at each processor, set RNG state
2036 6 : offset = 0
2037 9 : DO i = 1, logger%para_env%mepos
2038 9 : offset = offset + helium_env(1)%env_all(i)
2039 : END DO
2040 :
2041 12 : DO k = 1, SIZE(helium_env)
2042 6 : msglen = 40
2043 6 : off = msglen*(offset + k - 1)
2044 54 : m(:, :) = .TRUE.
2045 6 : f(:, :) = 0.0_dp
2046 6 : bg(:, :) = UNPACK(message(off + 1:off + 6), MASK=m, FIELD=f)
2047 6 : cg(:, :) = UNPACK(message(off + 7:off + 12), MASK=m, FIELD=f)
2048 6 : ig(:, :) = UNPACK(message(off + 13:off + 18), MASK=m, FIELD=f)
2049 6 : bf = message(off + 19)
2050 6 : bu = message(off + 20)
2051 6 : IF (bf .GT. 0) THEN
2052 0 : lbf = .TRUE.
2053 : ELSE
2054 6 : lbf = .FALSE.
2055 : END IF
2056 : CALL helium_env(k)%helium%rng_stream_uniform%set(bg=bg, cg=cg, ig=ig, &
2057 6 : buffer=bu, buffer_filled=lbf)
2058 6 : bg(:, :) = UNPACK(message(off + 21:off + 26), MASK=m, FIELD=f)
2059 6 : cg(:, :) = UNPACK(message(off + 27:off + 32), MASK=m, FIELD=f)
2060 6 : ig(:, :) = UNPACK(message(off + 33:off + 38), MASK=m, FIELD=f)
2061 6 : bf = message(off + 39)
2062 6 : bu = message(off + 40)
2063 6 : IF (bf .GT. 0) THEN
2064 4 : lbf = .TRUE.
2065 : ELSE
2066 2 : lbf = .FALSE.
2067 : END IF
2068 : CALL helium_env(k)%helium%rng_stream_gaussian%set(bg=bg, cg=cg, ig=ig, &
2069 12 : buffer=bu, buffer_filled=lbf)
2070 : END DO
2071 : END IF
2072 :
2073 : NULLIFY (message)
2074 :
2075 6 : RETURN
2076 6 : END SUBROUTINE helium_rng_restore
2077 :
2078 : ! ***************************************************************************
2079 : !> \brief Create the RDF related data structures and initialize
2080 : !> \param helium ...
2081 : !> \date 2014-02-25
2082 : !> \par History
2083 : !> 2018-10-19 Changed to bead-wise RDFs of solute-He and He-He [cschran]
2084 : !> \author Lukasz Walewski
2085 : ! **************************************************************************************************
2086 2 : SUBROUTINE helium_rdf_init(helium)
2087 :
2088 : TYPE(helium_solvent_type), POINTER :: helium
2089 :
2090 : CHARACTER(len=2*default_string_length) :: err_str, stmp
2091 : INTEGER :: ii, ij
2092 : LOGICAL :: explicit
2093 : TYPE(cp_logger_type), POINTER :: logger
2094 :
2095 : ! read parameters
2096 2 : NULLIFY (logger)
2097 2 : logger => cp_get_default_logger()
2098 : CALL section_vals_val_get( &
2099 : helium%input, &
2100 : "MOTION%PINT%HELIUM%RDF%SOLUTE_HE", &
2101 2 : l_val=helium%rdf_sol_he)
2102 : CALL section_vals_val_get( &
2103 : helium%input, &
2104 : "MOTION%PINT%HELIUM%RDF%HE_HE", &
2105 2 : l_val=helium%rdf_he_he)
2106 :
2107 : ! Prevent He_He Rdfs for a single he atom:
2108 2 : IF (helium%atoms <= 1) THEN
2109 0 : helium%rdf_he_he = .FALSE.
2110 : END IF
2111 :
2112 2 : helium%rdf_num = 0
2113 2 : IF (helium%rdf_sol_he) THEN
2114 2 : IF (helium%solute_present) THEN
2115 : ! get number of centers from solute to store solute positions
2116 0 : ALLOCATE (helium%rdf_centers(helium%beads, helium%solute_atoms*3))
2117 0 : helium%rdf_centers(:, :) = 0.0_dp
2118 0 : helium%rdf_num = helium%solute_atoms
2119 : ELSE
2120 2 : helium%rdf_sol_he = .FALSE.
2121 : END IF
2122 : END IF
2123 :
2124 2 : IF (helium%rdf_he_he) THEN
2125 2 : helium%rdf_num = helium%rdf_num + 1
2126 : END IF
2127 :
2128 : ! set the flag for RDF and either proceed or return
2129 2 : IF (helium%rdf_num > 0) THEN
2130 2 : helium%rdf_present = .TRUE.
2131 : ELSE
2132 0 : helium%rdf_present = .FALSE.
2133 : err_str = "HELIUM RDFs requested, but no valid choice of "// &
2134 0 : "parameters specified. No RDF will be computed."
2135 0 : CPWARN(err_str)
2136 0 : RETURN
2137 : END IF
2138 :
2139 : ! set the maximum RDF range
2140 : CALL section_vals_val_get( &
2141 : helium%input, &
2142 : "MOTION%PINT%HELIUM%RDF%MAXR", &
2143 2 : explicit=explicit)
2144 2 : IF (explicit) THEN
2145 : ! use the value explicitly set in the input
2146 : CALL section_vals_val_get( &
2147 : helium%input, &
2148 : "MOTION%PINT%HELIUM%RDF%MAXR", &
2149 0 : r_val=helium%rdf_maxr)
2150 : ELSE
2151 : ! use the default value
2152 : CALL section_vals_val_get( &
2153 : helium%input, &
2154 : "MOTION%PINT%HELIUM%DROPLET_RADIUS", &
2155 2 : explicit=explicit)
2156 2 : IF (explicit) THEN
2157 : ! use the droplet radius
2158 0 : IF (helium%solute_present .AND. .NOT. helium%periodic) THEN
2159 : ! COM of solute is used as center of the box.
2160 : ! Therefore distances became larger then droplet_radius
2161 : ! when parts of the solute are on opposite site of
2162 : ! COM and helium.
2163 : ! Use two times droplet_radius for security:
2164 0 : helium%rdf_maxr = helium%droplet_radius*2.0_dp
2165 : ELSE
2166 0 : helium%rdf_maxr = helium%droplet_radius
2167 : END IF
2168 : ELSE
2169 : ! use cell_size and cell_shape
2170 : ! (they are set regardless of us being periodic or not)
2171 2 : SELECT CASE (helium%cell_shape)
2172 : CASE (helium_cell_shape_cube)
2173 0 : helium%rdf_maxr = helium%cell_size/2.0_dp
2174 : CASE (helium_cell_shape_octahedron)
2175 2 : helium%rdf_maxr = helium%cell_size*SQRT(3.0_dp)/4.0_dp
2176 : CASE DEFAULT
2177 0 : helium%rdf_maxr = 0.0_dp
2178 0 : WRITE (stmp, *) helium%cell_shape
2179 0 : err_str = "cell shape unknown ("//TRIM(ADJUSTL(stmp))//")"
2180 2 : CPABORT(err_str)
2181 : END SELECT
2182 : END IF
2183 : END IF
2184 :
2185 : ! get number of bins and set bin spacing
2186 : CALL section_vals_val_get( &
2187 : helium%input, &
2188 : "MOTION%PINT%HELIUM%RDF%NBIN", &
2189 2 : i_val=helium%rdf_nbin)
2190 2 : helium%rdf_delr = helium%rdf_maxr/REAL(helium%rdf_nbin, dp)
2191 :
2192 : ! get the weighting factor
2193 : CALL section_vals_val_get( &
2194 : helium%input, &
2195 : "MOTION%PINT%HELIUM%AVERAGES%IWEIGHT", &
2196 2 : i_val=helium%rdf_iweight)
2197 :
2198 : ! allocate and initialize memory for RDF storage
2199 2 : ii = helium%rdf_num
2200 2 : ij = helium%rdf_nbin
2201 8 : ALLOCATE (helium%rdf_inst(ii, ij))
2202 6 : ALLOCATE (helium%rdf_accu(ii, ij))
2203 6 : ALLOCATE (helium%rdf_rstr(ii, ij))
2204 1002 : helium%rdf_inst(:, :) = 0.0_dp
2205 1002 : helium%rdf_accu(:, :) = 0.0_dp
2206 1002 : helium%rdf_rstr(:, :) = 0.0_dp
2207 :
2208 : RETURN
2209 2 : END SUBROUTINE helium_rdf_init
2210 :
2211 : ! ***************************************************************************
2212 : !> \brief Restore the RDFs from the input structure
2213 : !> \param helium_env ...
2214 : !> \date 2011-06-22
2215 : !> \par History
2216 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
2217 : !> 2018-10-19 Changed to bead-wise RDFs of solute-He and He-He [cschran]
2218 : !> \author Lukasz Walewski
2219 : ! **************************************************************************************************
2220 2 : SUBROUTINE helium_rdf_restore(helium_env)
2221 :
2222 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
2223 :
2224 : CHARACTER(len=default_string_length) :: stmp1, stmp2
2225 : CHARACTER(len=max_line_length) :: err_str
2226 : INTEGER :: ii, ij, itmp, k, msglen
2227 : LOGICAL :: explicit, ltmp
2228 2 : LOGICAL, DIMENSION(:, :), POINTER :: m
2229 2 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
2230 2 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: f
2231 :
2232 : CALL section_vals_val_get(helium_env(1)%helium%input, &
2233 : "MOTION%PINT%HELIUM%AVERAGES%RDF", &
2234 2 : explicit=explicit)
2235 2 : IF (explicit) THEN
2236 0 : NULLIFY (message)
2237 : CALL section_vals_val_get(helium_env(1)%helium%input, &
2238 : "MOTION%PINT%HELIUM%AVERAGES%RDF", &
2239 0 : r_vals=message)
2240 0 : msglen = SIZE(message)
2241 0 : itmp = SIZE(helium_env(1)%helium%rdf_rstr)
2242 0 : ltmp = (msglen .EQ. itmp)
2243 0 : IF (.NOT. ltmp) THEN
2244 0 : stmp1 = ""
2245 0 : WRITE (stmp1, *) msglen
2246 0 : stmp2 = ""
2247 0 : WRITE (stmp2, *) itmp
2248 : err_str = "Size of the RDF array in the input ("// &
2249 : TRIM(ADJUSTL(stmp1))// &
2250 : ") .NE. that in the runtime ("// &
2251 0 : TRIM(ADJUSTL(stmp2))//")."
2252 0 : CPABORT(err_str)
2253 : END IF
2254 : ELSE
2255 : RETURN
2256 : END IF
2257 :
2258 0 : ii = helium_env(1)%helium%rdf_num
2259 0 : ij = helium_env(1)%helium%rdf_nbin
2260 : NULLIFY (m, f)
2261 0 : ALLOCATE (m(ii, ij))
2262 0 : ALLOCATE (f(ii, ij))
2263 0 : m(:, :) = .TRUE.
2264 0 : f(:, :) = 0.0_dp
2265 :
2266 0 : DO k = 1, SIZE(helium_env)
2267 0 : helium_env(k)%helium%rdf_rstr(:, :) = UNPACK(message(1:msglen), MASK=m, FIELD=f)
2268 : CALL section_vals_val_get(helium_env(k)%helium%input, &
2269 : "MOTION%PINT%HELIUM%AVERAGES%IWEIGHT", &
2270 0 : i_val=helium_env(k)%helium%rdf_iweight)
2271 : END DO
2272 :
2273 0 : DEALLOCATE (f, m)
2274 : NULLIFY (message)
2275 :
2276 0 : RETURN
2277 2 : END SUBROUTINE helium_rdf_restore
2278 :
2279 : ! ***************************************************************************
2280 : !> \brief Release/deallocate RDF related data structures
2281 : !> \param helium ...
2282 : !> \date 2014-02-25
2283 : !> \author Lukasz Walewski
2284 : ! **************************************************************************************************
2285 31 : SUBROUTINE helium_rdf_release(helium)
2286 :
2287 : TYPE(helium_solvent_type), POINTER :: helium
2288 :
2289 31 : IF (helium%rdf_present) THEN
2290 :
2291 0 : DEALLOCATE ( &
2292 : helium%rdf_rstr, &
2293 0 : helium%rdf_accu, &
2294 2 : helium%rdf_inst)
2295 :
2296 : NULLIFY ( &
2297 : helium%rdf_rstr, &
2298 2 : helium%rdf_accu, &
2299 2 : helium%rdf_inst)
2300 :
2301 2 : IF (helium%rdf_sol_he) THEN
2302 0 : DEALLOCATE (helium%rdf_centers)
2303 0 : NULLIFY (helium%rdf_centers)
2304 : END IF
2305 :
2306 : END IF
2307 :
2308 31 : RETURN
2309 : END SUBROUTINE helium_rdf_release
2310 :
2311 : ! ***************************************************************************
2312 : !> \brief Check whether property <prop> is activated in the input structure
2313 : !> \param helium ...
2314 : !> \param prop ...
2315 : !> \return ...
2316 : !> \date 2014-06-26
2317 : !> \author Lukasz Walewski
2318 : !> \note The property is controlled by two items in the input structure,
2319 : !> the printkey and the control section. Two settings result in
2320 : !> the property being considered active:
2321 : !> 1. printkey is on at the given print level
2322 : !> 2. control section is explicit and on
2323 : !> If the property is considered active it should be calculated
2324 : !> and printed through out the run.
2325 : ! **************************************************************************************************
2326 124 : FUNCTION helium_property_active(helium, prop) RESULT(is_active)
2327 :
2328 : TYPE(helium_solvent_type), POINTER :: helium
2329 : CHARACTER(len=*) :: prop
2330 : LOGICAL :: is_active
2331 :
2332 : CHARACTER(len=default_string_length) :: input_path
2333 : INTEGER :: print_level
2334 : LOGICAL :: explicit, is_on
2335 : TYPE(cp_logger_type), POINTER :: logger
2336 : TYPE(section_vals_type), POINTER :: print_key, section
2337 :
2338 62 : is_active = .FALSE.
2339 62 : NULLIFY (logger)
2340 124 : logger => cp_get_default_logger()
2341 :
2342 : ! if the printkey is on at this runlevel consider prop to be active
2343 62 : NULLIFY (print_key)
2344 62 : input_path = "MOTION%PINT%HELIUM%PRINT%"//TRIM(ADJUSTL(prop))
2345 : print_key => section_vals_get_subs_vals( &
2346 : helium%input, &
2347 62 : input_path)
2348 : is_on = cp_printkey_is_on( &
2349 : iteration_info=logger%iter_info, &
2350 62 : print_key=print_key)
2351 62 : IF (is_on) THEN
2352 62 : is_active = .TRUE.
2353 : RETURN
2354 : END IF
2355 :
2356 : ! if the control section is explicit and on consider prop to be active
2357 : ! and activate the printkey
2358 62 : is_active = .FALSE.
2359 62 : NULLIFY (section)
2360 62 : input_path = "MOTION%PINT%HELIUM%"//TRIM(ADJUSTL(prop))
2361 : section => section_vals_get_subs_vals( &
2362 : helium%input, &
2363 62 : input_path)
2364 62 : CALL section_vals_get(section, explicit=explicit)
2365 62 : IF (explicit) THEN
2366 : ! control section explicitly present, continue checking
2367 : CALL section_vals_val_get( &
2368 : section, &
2369 : "_SECTION_PARAMETERS_", &
2370 4 : l_val=is_on)
2371 4 : IF (is_on) THEN
2372 : ! control section is explicit and on, activate the property
2373 4 : is_active = .TRUE.
2374 : ! activate the corresponding print_level as well
2375 4 : print_level = logger%iter_info%print_level
2376 : CALL section_vals_val_set( &
2377 : print_key, &
2378 : "_SECTION_PARAMETERS_", &
2379 4 : i_val=print_level)
2380 : END IF
2381 : END IF
2382 :
2383 : RETURN
2384 62 : END FUNCTION helium_property_active
2385 :
2386 : ! ***************************************************************************
2387 : !> \brief Create the density related data structures and initialize
2388 : !> \param helium ...
2389 : !> \date 2014-02-25
2390 : !> \author Lukasz Walewski
2391 : ! **************************************************************************************************
2392 2 : SUBROUTINE helium_rho_property_init(helium)
2393 :
2394 : TYPE(helium_solvent_type), POINTER :: helium
2395 :
2396 : INTEGER :: nc
2397 :
2398 12 : ALLOCATE (helium%rho_property(rho_num))
2399 :
2400 2 : helium%rho_property(rho_atom_number)%name = 'Atom number density'
2401 2 : nc = 1
2402 2 : helium%rho_property(rho_atom_number)%num_components = nc
2403 2 : ALLOCATE (helium%rho_property(rho_atom_number)%filename_suffix(nc))
2404 2 : ALLOCATE (helium%rho_property(rho_atom_number)%component_name(nc))
2405 2 : ALLOCATE (helium%rho_property(rho_atom_number)%component_index(nc))
2406 2 : helium%rho_property(rho_atom_number)%filename_suffix(1) = 'an'
2407 2 : helium%rho_property(rho_atom_number)%component_name(1) = ''
2408 4 : helium%rho_property(rho_atom_number)%component_index(:) = 0
2409 :
2410 2 : helium%rho_property(rho_projected_area)%name = 'Projected area squared density, A*A(r)'
2411 2 : nc = 3
2412 2 : helium%rho_property(rho_projected_area)%num_components = nc
2413 2 : ALLOCATE (helium%rho_property(rho_projected_area)%filename_suffix(nc))
2414 2 : ALLOCATE (helium%rho_property(rho_projected_area)%component_name(nc))
2415 2 : ALLOCATE (helium%rho_property(rho_projected_area)%component_index(nc))
2416 2 : helium%rho_property(rho_projected_area)%filename_suffix(1) = 'pa_x'
2417 2 : helium%rho_property(rho_projected_area)%filename_suffix(2) = 'pa_y'
2418 2 : helium%rho_property(rho_projected_area)%filename_suffix(3) = 'pa_z'
2419 2 : helium%rho_property(rho_projected_area)%component_name(1) = 'component x'
2420 2 : helium%rho_property(rho_projected_area)%component_name(2) = 'component y'
2421 2 : helium%rho_property(rho_projected_area)%component_name(3) = 'component z'
2422 8 : helium%rho_property(rho_projected_area)%component_index(:) = 0
2423 :
2424 2 : helium%rho_property(rho_winding_number)%name = 'Winding number squared density, W*W(r)'
2425 2 : nc = 3
2426 2 : helium%rho_property(rho_winding_number)%num_components = nc
2427 2 : ALLOCATE (helium%rho_property(rho_winding_number)%filename_suffix(nc))
2428 2 : ALLOCATE (helium%rho_property(rho_winding_number)%component_name(nc))
2429 2 : ALLOCATE (helium%rho_property(rho_winding_number)%component_index(nc))
2430 2 : helium%rho_property(rho_winding_number)%filename_suffix(1) = 'wn_x'
2431 2 : helium%rho_property(rho_winding_number)%filename_suffix(2) = 'wn_y'
2432 2 : helium%rho_property(rho_winding_number)%filename_suffix(3) = 'wn_z'
2433 2 : helium%rho_property(rho_winding_number)%component_name(1) = 'component x'
2434 2 : helium%rho_property(rho_winding_number)%component_name(2) = 'component y'
2435 2 : helium%rho_property(rho_winding_number)%component_name(3) = 'component z'
2436 8 : helium%rho_property(rho_winding_number)%component_index(:) = 0
2437 :
2438 2 : helium%rho_property(rho_winding_cycle)%name = 'Winding number squared density, W^2(r)'
2439 2 : nc = 3
2440 2 : helium%rho_property(rho_winding_cycle)%num_components = nc
2441 2 : ALLOCATE (helium%rho_property(rho_winding_cycle)%filename_suffix(nc))
2442 2 : ALLOCATE (helium%rho_property(rho_winding_cycle)%component_name(nc))
2443 2 : ALLOCATE (helium%rho_property(rho_winding_cycle)%component_index(nc))
2444 2 : helium%rho_property(rho_winding_cycle)%filename_suffix(1) = 'wc_x'
2445 2 : helium%rho_property(rho_winding_cycle)%filename_suffix(2) = 'wc_y'
2446 2 : helium%rho_property(rho_winding_cycle)%filename_suffix(3) = 'wc_z'
2447 2 : helium%rho_property(rho_winding_cycle)%component_name(1) = 'component x'
2448 2 : helium%rho_property(rho_winding_cycle)%component_name(2) = 'component y'
2449 2 : helium%rho_property(rho_winding_cycle)%component_name(3) = 'component z'
2450 8 : helium%rho_property(rho_winding_cycle)%component_index(:) = 0
2451 :
2452 2 : helium%rho_property(rho_moment_of_inertia)%name = 'Moment of inertia'
2453 2 : nc = 3
2454 2 : helium%rho_property(rho_moment_of_inertia)%num_components = nc
2455 2 : ALLOCATE (helium%rho_property(rho_moment_of_inertia)%filename_suffix(nc))
2456 2 : ALLOCATE (helium%rho_property(rho_moment_of_inertia)%component_name(nc))
2457 2 : ALLOCATE (helium%rho_property(rho_moment_of_inertia)%component_index(nc))
2458 2 : helium%rho_property(rho_moment_of_inertia)%filename_suffix(1) = 'mi_x'
2459 2 : helium%rho_property(rho_moment_of_inertia)%filename_suffix(2) = 'mi_y'
2460 2 : helium%rho_property(rho_moment_of_inertia)%filename_suffix(3) = 'mi_z'
2461 2 : helium%rho_property(rho_moment_of_inertia)%component_name(1) = 'component x'
2462 2 : helium%rho_property(rho_moment_of_inertia)%component_name(2) = 'component y'
2463 2 : helium%rho_property(rho_moment_of_inertia)%component_name(3) = 'component z'
2464 8 : helium%rho_property(rho_moment_of_inertia)%component_index(:) = 0
2465 :
2466 12 : helium%rho_property(:)%is_calculated = .FALSE.
2467 :
2468 2 : RETURN
2469 : END SUBROUTINE helium_rho_property_init
2470 :
2471 : ! ***************************************************************************
2472 : !> \brief Create the density related data structures and initialize
2473 : !> \param helium ...
2474 : !> \date 2014-02-25
2475 : !> \author Lukasz Walewski
2476 : ! **************************************************************************************************
2477 2 : SUBROUTINE helium_rho_init(helium)
2478 :
2479 : TYPE(helium_solvent_type), POINTER :: helium
2480 :
2481 : INTEGER :: ii, itmp, jtmp
2482 : LOGICAL :: explicit, ltmp
2483 :
2484 2 : CALL helium_rho_property_init(helium)
2485 :
2486 2 : helium%rho_num_act = 0
2487 :
2488 : ! check for atom number density
2489 : CALL section_vals_val_get( &
2490 : helium%input, &
2491 : "MOTION%PINT%HELIUM%RHO%ATOM_NUMBER", &
2492 2 : l_val=ltmp)
2493 2 : IF (ltmp) THEN
2494 2 : helium%rho_property(rho_atom_number)%is_calculated = .TRUE.
2495 2 : helium%rho_num_act = helium%rho_num_act + 1
2496 2 : helium%rho_property(rho_atom_number)%component_index(1) = helium%rho_num_act
2497 : END IF
2498 :
2499 : ! check for projected area density
2500 : CALL section_vals_val_get( &
2501 : helium%input, &
2502 : "MOTION%PINT%HELIUM%RHO%PROJECTED_AREA_2", &
2503 2 : l_val=ltmp)
2504 2 : IF (ltmp) THEN
2505 0 : helium%rho_property(rho_projected_area)%is_calculated = .TRUE.
2506 0 : DO ii = 1, helium%rho_property(rho_projected_area)%num_components
2507 0 : helium%rho_num_act = helium%rho_num_act + 1
2508 0 : helium%rho_property(rho_projected_area)%component_index(ii) = helium%rho_num_act
2509 : END DO
2510 : END IF
2511 :
2512 : ! check for winding number density
2513 : CALL section_vals_val_get( &
2514 : helium%input, &
2515 : "MOTION%PINT%HELIUM%RHO%WINDING_NUMBER_2", &
2516 2 : l_val=ltmp)
2517 2 : IF (ltmp) THEN
2518 0 : helium%rho_property(rho_winding_number)%is_calculated = .TRUE.
2519 0 : DO ii = 1, helium%rho_property(rho_winding_number)%num_components
2520 0 : helium%rho_num_act = helium%rho_num_act + 1
2521 0 : helium%rho_property(rho_winding_number)%component_index(ii) = helium%rho_num_act
2522 : END DO
2523 : END IF
2524 :
2525 : ! check for winding cycle density
2526 : CALL section_vals_val_get( &
2527 : helium%input, &
2528 : "MOTION%PINT%HELIUM%RHO%WINDING_CYCLE_2", &
2529 2 : l_val=ltmp)
2530 2 : IF (ltmp) THEN
2531 0 : helium%rho_property(rho_winding_cycle)%is_calculated = .TRUE.
2532 0 : DO ii = 1, helium%rho_property(rho_winding_cycle)%num_components
2533 0 : helium%rho_num_act = helium%rho_num_act + 1
2534 0 : helium%rho_property(rho_winding_cycle)%component_index(ii) = helium%rho_num_act
2535 : END DO
2536 : END IF
2537 :
2538 : ! check for moment of inertia density
2539 : CALL section_vals_val_get( &
2540 : helium%input, &
2541 : "MOTION%PINT%HELIUM%RHO%MOMENT_OF_INERTIA", &
2542 2 : l_val=ltmp)
2543 2 : IF (ltmp) THEN
2544 0 : helium%rho_property(rho_moment_of_inertia)%is_calculated = .TRUE.
2545 0 : DO ii = 1, helium%rho_property(rho_moment_of_inertia)%num_components
2546 0 : helium%rho_num_act = helium%rho_num_act + 1
2547 0 : helium%rho_property(rho_moment_of_inertia)%component_index(ii) = helium%rho_num_act
2548 : END DO
2549 : END IF
2550 :
2551 : ! set the cube dimensions, etc (common to all estimators)
2552 2 : helium%rho_maxr = helium%cell_size
2553 : CALL section_vals_val_get( &
2554 : helium%input, &
2555 : "MOTION%PINT%HELIUM%RHO%NBIN", &
2556 2 : i_val=helium%rho_nbin)
2557 2 : helium%rho_delr = helium%rho_maxr/REAL(helium%rho_nbin, dp)
2558 :
2559 : ! check for optional estimators based on winding paths
2560 2 : helium%rho_num_min_len_wdg = 0
2561 : CALL section_vals_val_get( &
2562 : helium%input, &
2563 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_WDG", &
2564 2 : explicit=explicit)
2565 2 : IF (explicit) THEN
2566 0 : NULLIFY (helium%rho_min_len_wdg_vals)
2567 : CALL section_vals_val_get( &
2568 : helium%input, &
2569 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_WDG", &
2570 0 : i_vals=helium%rho_min_len_wdg_vals)
2571 0 : itmp = SIZE(helium%rho_min_len_wdg_vals)
2572 0 : IF (itmp .GT. 0) THEN
2573 0 : helium%rho_num_min_len_wdg = itmp
2574 0 : helium%rho_num_act = helium%rho_num_act + itmp
2575 : END IF
2576 : END IF
2577 :
2578 : ! check for optional estimators based on non-winding paths
2579 2 : helium%rho_num_min_len_non = 0
2580 : CALL section_vals_val_get( &
2581 : helium%input, &
2582 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_NON", &
2583 2 : explicit=explicit)
2584 2 : IF (explicit) THEN
2585 0 : NULLIFY (helium%rho_min_len_non_vals)
2586 : CALL section_vals_val_get( &
2587 : helium%input, &
2588 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_NON", &
2589 0 : i_vals=helium%rho_min_len_non_vals)
2590 0 : itmp = SIZE(helium%rho_min_len_non_vals)
2591 0 : IF (itmp .GT. 0) THEN
2592 0 : helium%rho_num_min_len_non = itmp
2593 0 : helium%rho_num_act = helium%rho_num_act + itmp
2594 : END IF
2595 : END IF
2596 :
2597 : ! check for optional estimators based on all paths
2598 2 : helium%rho_num_min_len_all = 0
2599 : CALL section_vals_val_get( &
2600 : helium%input, &
2601 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_ALL", &
2602 2 : explicit=explicit)
2603 2 : IF (explicit) THEN
2604 0 : NULLIFY (helium%rho_min_len_all_vals)
2605 : CALL section_vals_val_get( &
2606 : helium%input, &
2607 : "MOTION%PINT%HELIUM%RHO%MIN_CYCLE_LENGTHS_ALL", &
2608 0 : i_vals=helium%rho_min_len_all_vals)
2609 0 : itmp = SIZE(helium%rho_min_len_all_vals)
2610 0 : IF (itmp .GT. 0) THEN
2611 0 : helium%rho_num_min_len_all = itmp
2612 0 : helium%rho_num_act = helium%rho_num_act + itmp
2613 : END IF
2614 : END IF
2615 :
2616 : ! get the weighting factor
2617 : CALL section_vals_val_get( &
2618 : helium%input, &
2619 : "MOTION%PINT%HELIUM%AVERAGES%IWEIGHT", &
2620 2 : i_val=helium%rho_iweight)
2621 :
2622 : ! allocate and initialize memory for density storage
2623 2 : itmp = helium%rho_nbin
2624 2 : jtmp = helium%rho_num_act
2625 12 : ALLOCATE (helium%rho_inst(jtmp, itmp, itmp, itmp))
2626 12 : ALLOCATE (helium%rho_accu(jtmp, itmp, itmp, itmp))
2627 12 : ALLOCATE (helium%rho_rstr(jtmp, itmp, itmp, itmp))
2628 10 : ALLOCATE (helium%rho_incr(jtmp, helium%atoms, helium%beads))
2629 :
2630 3252 : helium%rho_incr(:, :, :) = 0.0_dp
2631 4222 : helium%rho_inst(:, :, :, :) = 0.0_dp
2632 4222 : helium%rho_accu(:, :, :, :) = 0.0_dp
2633 4222 : helium%rho_rstr(:, :, :, :) = 0.0_dp
2634 :
2635 2 : RETURN
2636 16 : END SUBROUTINE helium_rho_init
2637 :
2638 : ! ***************************************************************************
2639 : !> \brief Restore the densities from the input structure.
2640 : !> \param helium_env ...
2641 : !> \date 2011-06-22
2642 : !> \par History
2643 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
2644 : !> \author Lukasz Walewski
2645 : ! **************************************************************************************************
2646 2 : SUBROUTINE helium_rho_restore(helium_env)
2647 :
2648 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
2649 :
2650 : CHARACTER(len=default_string_length) :: stmp1, stmp2
2651 : CHARACTER(len=max_line_length) :: err_str
2652 : INTEGER :: itmp, k, msglen
2653 : LOGICAL :: explicit, ltmp
2654 2 : LOGICAL, DIMENSION(:, :, :, :), POINTER :: m
2655 2 : REAL(KIND=dp), DIMENSION(:), POINTER :: message
2656 2 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: f
2657 :
2658 : CALL section_vals_val_get(helium_env(1)%helium%input, &
2659 : "MOTION%PINT%HELIUM%AVERAGES%RHO", &
2660 2 : explicit=explicit)
2661 2 : IF (explicit) THEN
2662 0 : NULLIFY (message)
2663 : CALL section_vals_val_get(helium_env(1)%helium%input, &
2664 : "MOTION%PINT%HELIUM%AVERAGES%RHO", &
2665 0 : r_vals=message)
2666 0 : msglen = SIZE(message)
2667 0 : itmp = SIZE(helium_env(1)%helium%rho_rstr)
2668 0 : ltmp = (msglen .EQ. itmp)
2669 0 : IF (.NOT. ltmp) THEN
2670 0 : stmp1 = ""
2671 0 : WRITE (stmp1, *) msglen
2672 0 : stmp2 = ""
2673 0 : WRITE (stmp2, *) itmp
2674 : err_str = "Size of the S density array in the input ("// &
2675 : TRIM(ADJUSTL(stmp1))// &
2676 : ") .NE. that in the runtime ("// &
2677 0 : TRIM(ADJUSTL(stmp2))//")."
2678 0 : CPABORT(err_str)
2679 : END IF
2680 : ELSE
2681 : RETURN
2682 : END IF
2683 :
2684 0 : itmp = helium_env(1)%helium%rho_nbin
2685 : NULLIFY (m, f)
2686 0 : ALLOCATE (m(helium_env(1)%helium%rho_num_act, itmp, itmp, itmp))
2687 0 : ALLOCATE (f(helium_env(1)%helium%rho_num_act, itmp, itmp, itmp))
2688 0 : m(:, :, :, :) = .TRUE.
2689 0 : f(:, :, :, :) = 0.0_dp
2690 :
2691 0 : DO k = 1, SIZE(helium_env)
2692 0 : helium_env(k)%helium%rho_rstr(:, :, :, :) = UNPACK(message(1:msglen), MASK=m, FIELD=f)
2693 : END DO
2694 :
2695 0 : DEALLOCATE (f, m)
2696 : NULLIFY (message)
2697 :
2698 0 : RETURN
2699 2 : END SUBROUTINE helium_rho_restore
2700 :
2701 : ! ***************************************************************************
2702 : !> \brief Count atoms of different types and store their global indices.
2703 : !> \param helium ...
2704 : !> \param pint_env ...
2705 : !> \author Lukasz Walewski
2706 : !> \note Arrays ALLOCATEd here are (should be) DEALLOCATEd in
2707 : !> helium_release.
2708 : ! **************************************************************************************************
2709 21 : SUBROUTINE helium_set_solute_indices(helium, pint_env)
2710 : TYPE(helium_solvent_type), POINTER :: helium
2711 : TYPE(pint_env_type), INTENT(IN) :: pint_env
2712 :
2713 : INTEGER :: iatom, natoms
2714 : REAL(KIND=dp) :: mass
2715 : TYPE(cp_subsys_type), POINTER :: my_subsys
2716 : TYPE(f_env_type), POINTER :: my_f_env
2717 : TYPE(particle_list_type), POINTER :: my_particles
2718 :
2719 : ! set up my_particles structure
2720 :
2721 21 : NULLIFY (my_f_env, my_subsys, my_particles)
2722 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
2723 21 : f_env=my_f_env)
2724 21 : CALL force_env_get(force_env=my_f_env%force_env, subsys=my_subsys)
2725 21 : CALL cp_subsys_get(my_subsys, particles=my_particles)
2726 21 : CALL f_env_rm_defaults(my_f_env)
2727 :
2728 21 : natoms = helium%solute_atoms
2729 21 : NULLIFY (helium%solute_element)
2730 42 : ALLOCATE (helium%solute_element(natoms))
2731 :
2732 : ! find out how many different atomic types are there
2733 21 : helium%enum = 0
2734 84 : DO iatom = 1, natoms
2735 : CALL get_atomic_kind(my_particles%els(iatom)%atomic_kind, &
2736 : mass=mass, &
2737 84 : element_symbol=helium%solute_element(iatom))
2738 : END DO
2739 :
2740 21 : RETURN
2741 : END SUBROUTINE helium_set_solute_indices
2742 :
2743 : ! ***************************************************************************
2744 : !> \brief Sets helium%solute_cell based on the solute's force_env.
2745 : !> \param helium ...
2746 : !> \param pint_env ...
2747 : !> \author Lukasz Walewski
2748 : !> \note The simulation cell for the solvated molecule is taken from force_env
2749 : !> which should assure that we get proper cell dimensions regardless of
2750 : !> the method used for the solute (QS, FIST). Helium solvent needs the
2751 : !> solute's cell dimensions to calculate the solute-solvent distances
2752 : !> correctly.
2753 : !> \note At the moment only orthorhombic cells are supported.
2754 : ! **************************************************************************************************
2755 42 : SUBROUTINE helium_set_solute_cell(helium, pint_env)
2756 : TYPE(helium_solvent_type), POINTER :: helium
2757 : TYPE(pint_env_type), INTENT(IN) :: pint_env
2758 :
2759 : LOGICAL :: my_orthorhombic
2760 : TYPE(cell_type), POINTER :: my_cell
2761 : TYPE(f_env_type), POINTER :: my_f_env
2762 :
2763 : ! get the cell structure from pint_env
2764 :
2765 21 : NULLIFY (my_f_env, my_cell)
2766 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
2767 21 : f_env=my_f_env)
2768 21 : CALL force_env_get(force_env=my_f_env%force_env, cell=my_cell)
2769 21 : CALL f_env_rm_defaults(my_f_env)
2770 :
2771 21 : CALL get_cell(my_cell, orthorhombic=my_orthorhombic)
2772 21 : IF (.NOT. my_orthorhombic) THEN
2773 0 : CPABORT("Helium solvent not implemented for non-orthorhombic cells.")
2774 : ELSE
2775 21 : helium%solute_cell => my_cell
2776 : END IF
2777 :
2778 21 : RETURN
2779 : END SUBROUTINE helium_set_solute_cell
2780 :
2781 : END MODULE helium_methods
|