39 #include "../base/base_uses.f90"
51 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pint_piglet'
92 TYPE(piglet_therm_type),
INTENT(OUT) :: piglet_therm
93 TYPE(pint_env_type),
INTENT(IN) :: pint_env
94 TYPE(section_vals_type),
POINTER :: section
100 piglet_therm%nsp1 = piglet_therm%nsp1 + 1
102 piglet_therm%p = pint_env%p
104 piglet_therm%ndim = pint_env%ndim
105 NULLIFY (piglet_therm%a_mat)
106 ALLOCATE (piglet_therm%a_mat(piglet_therm%nsp1, piglet_therm%nsp1, p))
107 piglet_therm%a_mat(:, :, :) = 0.0_dp
108 NULLIFY (piglet_therm%c_mat)
109 ALLOCATE (piglet_therm%c_mat(piglet_therm%nsp1, piglet_therm%nsp1, p))
110 piglet_therm%c_mat(:, :, :) = 0.0_dp
111 NULLIFY (piglet_therm%gle_t)
112 ALLOCATE (piglet_therm%gle_t(piglet_therm%nsp1, piglet_therm%nsp1, p))
113 piglet_therm%gle_t(:, :, :) = 0.0_dp
114 NULLIFY (piglet_therm%gle_s)
115 ALLOCATE (piglet_therm%gle_s(piglet_therm%nsp1, piglet_therm%nsp1, p))
116 piglet_therm%gle_s(:, :, :) = 0.0_dp
117 NULLIFY (piglet_therm%smalls)
118 ALLOCATE (piglet_therm%smalls(piglet_therm%nsp1, ndim*p))
119 piglet_therm%smalls(:, :) = 0.0_dp
120 NULLIFY (piglet_therm%temp1)
121 ALLOCATE (piglet_therm%temp1(piglet_therm%nsp1, ndim))
122 piglet_therm%temp1(:, :) = 0.0_dp
123 NULLIFY (piglet_therm%temp2)
124 ALLOCATE (piglet_therm%temp2(piglet_therm%nsp1, ndim))
125 piglet_therm%temp2(:, :) = 0.0_dp
126 NULLIFY (piglet_therm%sqrtmass)
127 ALLOCATE (piglet_therm%sqrtmass(piglet_therm%p, piglet_therm%ndim))
128 piglet_therm%sqrtmass(:, :) = 0.0_dp
142 TYPE(piglet_therm_type),
INTENT(INOUT) :: piglet_therm
143 TYPE(pint_env_type),
INTENT(INOUT) :: pint_env
144 TYPE(section_vals_type),
POINTER :: section
145 REAL(kind=
dp),
INTENT(IN) :: dt
146 TYPE(mp_para_env_type),
POINTER :: para_env
148 CHARACTER(len=20) :: default_format, read_unit
149 CHARACTER(len=default_path_length) :: matrices_file_name
150 CHARACTER(len=default_string_length) :: msg, temp_input
151 CHARACTER(LEN=rng_record_length) :: rng_record
152 INTEGER :: cbrac, i, ibead, idim, imode, &
153 input_unit, isp, j, matrix_init, ns, &
156 REAL(kind=
dp),
DIMENSION(3, 2) :: initial_seed
157 REAL(kind=
dp),
DIMENSION(:),
POINTER :: smallstmp
159 DIMENSION(piglet_therm%nsp1, piglet_therm%nsp1) :: mtmp, tmpmatrix
160 TYPE(section_vals_type),
POINTER :: rng_section, smalls_section
163 pint_env%e_piglet = 0.0_dp
164 pint_env%piglet_therm%thermostat_energy = 0.0_dp
170 cpabort(
"PIGLET is designed to work with the RPMD propagator")
174 IF (para_env%is_source())
THEN
175 CALL pint_write_line(
"PIGLET| Initalizing S-matrices using cholesky decomposition.")
178 IF (para_env%is_source())
THEN
179 CALL pint_write_line(
"PIGLET| Initalizing S-matrices using full diagonalization.")
182 cpwarn(
"No PIGLET init algorithm selected. Selecting cholesky decomposition")
186 IF (para_env%is_source())
THEN
190 c_val=matrices_file_name)
193 CALL open_file(file_name=trim(matrices_file_name), &
194 file_action=
"READ", file_status=
"OLD", unit_number=input_unit)
197 DO WHILE (read_err == 0)
198 READ (input_unit, default_format, iostat=read_err) temp_input
199 IF (read_err /= 0)
EXIT
201 IF (index(temp_input,
"#") /= 0)
THEN
202 IF (index(temp_input,
"T=") /= 0)
THEN
203 CALL check_temperature(line=temp_input, &
204 propagator=pint_env%propagator%prop_kind, &
205 targettemp=pint_env%kT*pint_env%propagator%temp_sim2phys)
206 ELSE IF (index(temp_input,
"A MATRIX") /= 0)
THEN
207 obrac = index(temp_input,
"(") + 1
208 cbrac = index(temp_input,
")") - 1
209 read_unit = temp_input(obrac:cbrac)
211 READ (input_unit, default_format) temp_input
212 DO i = 1, piglet_therm%nsp1
213 READ (input_unit, *, iostat=read_err) &
214 (piglet_therm%a_mat(i, j, imode), j=1, piglet_therm%nsp1)
215 IF (read_err /= 0)
THEN
216 WRITE (unit=msg, fmt=*)
"Invalid PIGLET A-matrix Nr.", i - 1
223 IF (read_err == 0)
THEN
224 CALL a_mat_to_cp2k(piglet_therm%a_mat, p, &
225 piglet_therm%nsp1, read_unit, msg)
227 ELSE IF (index(temp_input,
"C MATRIX") /= 0)
THEN
228 obrac = index(temp_input,
"(") + 1
229 cbrac = index(temp_input,
")") - 1
230 read_unit = temp_input(obrac:cbrac)
232 READ (input_unit, default_format) temp_input
233 DO i = 1, piglet_therm%nsp1
234 READ (input_unit, *, iostat=read_err) &
235 (piglet_therm%c_mat(i, j, imode), j=1, piglet_therm%nsp1)
236 IF (read_err /= 0)
THEN
237 WRITE (unit=msg, fmt=*)
"Invalid PIGLET C-matrix Nr.", i - 1
243 IF (read_err == 0)
THEN
244 CALL c_mat_to_cp2k(piglet_therm%c_mat, p, &
245 piglet_therm%nsp1, read_unit, msg)
253 CALL para_env%bcast(piglet_therm%a_mat, &
255 CALL para_env%bcast(piglet_therm%c_mat, &
259 NULLIFY (rng_section)
261 subsection_name=
"RNG_INIT")
265 i_rep_val=1, c_val=rng_record)
268 initial_seed(:, :) = real(pint_env%thermostat_rng_seed,
dp)
269 piglet_therm%gaussian_rng_stream = rng_stream_type( &
270 name=
"piglet_rng_gaussian", distribution_type=
gaussian, &
271 extended_precision=.true., &
281 n=piglet_therm%nsp1, &
284 em=piglet_therm%gle_t(:, :, i))
293 piglet_therm%gle_t(:, :, i), &
295 piglet_therm%c_mat(:, :, i), &
309 piglet_therm%gle_t(:, :, i), &
315 mtmp(:, :) = piglet_therm%c_mat(:, :, i) - mtmp(:, :)
320 piglet_therm%gle_s(:, :, i), &
324 CALL sqrt_pos_def_mat(piglet_therm%nsp1, &
326 piglet_therm%gle_s(:, :, i))
334 piglet_therm%smalls = 0.0_dp
335 NULLIFY (smalls_section)
345 DO isp = 2, piglet_therm%nsp1
346 DO ibead = 1, piglet_therm%p*piglet_therm%ndim
347 piglet_therm%smalls(isp, ibead) = smallstmp(i)
352 DO ibead = 1, piglet_therm%p
359 CALL sqrt_pos_def_mat(piglet_therm%nsp1, &
360 piglet_therm%c_mat(:, :, ibead), &
364 DO idim = 1, piglet_therm%ndim
365 DO j = 1, piglet_therm%nsp1
366 piglet_therm%temp2(j, idim) = piglet_therm%gaussian_rng_stream%next()
378 piglet_therm%temp2, &
381 piglet_therm%temp1, &
384 DO idim = 1, piglet_therm%ndim
385 j = (idim - 1)*piglet_therm%p + ibead
386 DO i = 1, piglet_therm%nsp1
387 piglet_therm%smalls(i, j) = piglet_therm%temp1(i, idim)
394 DO idim = 1, piglet_therm%ndim
395 DO ibead = 1, piglet_therm%p
396 piglet_therm%sqrtmass(ibead, idim) = sqrt(pint_env%mass_fict(ibead, idim))
411 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: vold, vnew
412 INTEGER,
INTENT(IN) :: first_mode
413 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: masses
414 TYPE(piglet_therm_type),
POINTER :: piglet_therm
416 CHARACTER(len=*),
PARAMETER :: routinen =
'pint_piglet_step'
418 INTEGER :: handle, i, ibead, idim, j, ndim, ndimp, &
420 REAL(kind=
dp) :: delta_ekin
422 CALL timeset(routinen, handle)
423 nsp1 = piglet_therm%nsp1
424 ndim = piglet_therm%ndim
431 DO ibead = first_mode, p
435 piglet_therm%temp1(1, idim) = vold(ibead, idim)*piglet_therm%sqrtmass(ibead, idim)
440 piglet_therm%temp1(i, idim) = piglet_therm%smalls(i, (ibead - 1)*ndim + idim)
447 piglet_therm%temp2(j, idim) = piglet_therm%gaussian_rng_stream%next()
452 i = (ibead - 1)*piglet_therm%ndim + 1
460 piglet_therm%gle_s(:, :, ibead), &
462 piglet_therm%temp2, &
465 piglet_therm%smalls(:, i), &
476 piglet_therm%gle_t(:, :, ibead), &
478 piglet_therm%temp1, &
481 piglet_therm%smalls(:, i), &
489 vnew(ibead, idim) = piglet_therm%smalls(1, (ibead - 1)*ndim + idim)/piglet_therm%sqrtmass(ibead, idim)
490 delta_ekin = delta_ekin + masses(ibead, idim)*( &
491 vnew(ibead, idim)*vnew(ibead, idim) - &
492 vold(ibead, idim)*vold(ibead, idim))
497 piglet_therm%thermostat_energy = piglet_therm%thermostat_energy - 0.5_dp*delta_ekin
499 CALL timestop(handle)
510 TYPE(piglet_therm_type),
INTENT(INOUT) :: piglet_therm
512 DEALLOCATE (piglet_therm%a_mat)
513 DEALLOCATE (piglet_therm%c_mat)
514 DEALLOCATE (piglet_therm%gle_t)
515 DEALLOCATE (piglet_therm%gle_s)
516 DEALLOCATE (piglet_therm%smalls)
517 DEALLOCATE (piglet_therm%temp1)
518 DEALLOCATE (piglet_therm%temp2)
519 DEALLOCATE (piglet_therm%sqrtmass)
532 SUBROUTINE a_mat_to_cp2k(a_mat, p, nsp1, myunit, msg)
534 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: a_mat
535 INTEGER,
INTENT(IN) :: p, nsp1
536 CHARACTER(LEN=20),
INTENT(IN) :: myunit
537 CHARACTER(default_string_length),
INTENT(OUT) :: msg
539 CHARACTER(LEN=20) :: isunit
540 INTEGER :: i, imode, j
543 SELECT CASE (trim(myunit))
544 CASE (
"femtoseconds^-1")
546 CASE (
"picoseconds^-1")
550 CASE (
"atomic time units^-1")
553 msg =
"Unknown unit of A-Matrices for PIGLET. Assuming a.u."
576 SUBROUTINE c_mat_to_cp2k(c_mat, p, nsp1, myunit, msg)
578 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: c_mat
579 INTEGER,
INTENT(IN) :: p, nsp1
580 CHARACTER(LEN=20),
INTENT(IN) :: myunit
581 CHARACTER(default_string_length),
INTENT(OUT) :: msg
583 CHARACTER(LEN=20) :: isunit
584 INTEGER :: i, imode, j
587 SELECT CASE (trim(myunit))
592 CASE (
"atomic energy units ")
595 msg =
"Unknown unit of C-Matrices for PIGLET. Assuming a.u."
608 END SUBROUTINE c_mat_to_cp2k
617 SUBROUTINE check_temperature(line, propagator, targettemp)
619 CHARACTER(len=*),
INTENT(IN) :: line
620 INTEGER,
INTENT(IN) :: propagator
621 REAL(kind=
dp),
INTENT(IN) :: targettemp
623 CHARACTER(len=default_string_length) :: msg
625 REAL(kind=
dp) :: convttemp, deviation, matrixtemp, ttemp
628 posnumber = index(line,
"T=") + 2
631 READ (line(posnumber:), *) matrixtemp
633 IF (index(line,
"K") /= 0)
THEN
635 IF (abs(convttemp - matrixtemp) > convttemp/deviation)
THEN
636 WRITE (unit=msg, fmt=*)
"PIGLET Simulation temperature (", &
637 convttemp,
"K) /= matrix temperature (", matrixtemp,
"K)"
640 ELSE IF (index(line,
"eV") /= 0)
THEN
642 IF (abs(convttemp - matrixtemp) > convttemp/deviation)
THEN
643 WRITE (unit=msg, fmt=*)
"PIGLET Simulation temperature (", &
644 convttemp,
"K) /= matrix temperature (", matrixtemp,
"K)"
647 ELSE IF (index(line,
"atomic energy units") /= 0)
THEN
649 IF (abs(convttemp - matrixtemp) > convttemp/deviation)
THEN
650 WRITE (unit=msg, fmt=*)
"PIGLET Simulation temperature (", &
651 convttemp,
"K) /= matrix temperature (", matrixtemp,
"K)"
655 WRITE (unit=msg, fmt=*)
"Unknown PIGLET matrix temperature. Assuming a.u."
658 IF (abs(convttemp - matrixtemp) > convttemp/deviation)
THEN
659 WRITE (unit=msg, fmt=*)
"PIGLET Simulation temperature (", &
660 convttemp,
"K) /= matrix temperature (", matrixtemp,
"K)"
665 END SUBROUTINE check_temperature
673 TYPE(pint_env_type),
INTENT(INOUT) :: pint_env
675 IF (
ASSOCIATED(pint_env%piglet_therm))
THEN
676 pint_env%e_piglet = pint_env%piglet_therm%thermostat_energy
678 pint_env%e_piglet = 0.0d0
691 SUBROUTINE sqrt_pos_def_mat(n, SST, S)
693 INTEGER,
INTENT(IN) :: n
694 REAL(kind=
dp),
DIMENSION(n, n),
INTENT(IN) :: sst
695 REAL(kind=
dp),
DIMENSION(n, n),
INTENT(OUT) :: s
697 INTEGER :: i, info, lwork
698 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
699 REAL(kind=
dp),
DIMENSION(1) :: tmplwork
700 REAL(kind=
dp),
DIMENSION(n) :: eigval
701 REAL(kind=
dp),
DIMENSION(n, n) :: a, tmpmatrix
729 lwork = int(tmplwork(1) + 0.5_dp)
730 ALLOCATE (work(lwork))
748 IF (eigval(i) > 0.0_dp)
THEN
749 s(i, i) = sqrt(eigval(i))
753 tmpmatrix(:, :) = 0.0_dp
784 END SUBROUTINE sqrt_pos_def_mat
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
subroutine, public gle_cholesky_stab(SST, S, n)
...
subroutine, public gle_matrix_exp(M, n, j, k, EM)
...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Interface to the message passing library MPI.
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
type(rng_stream_type) function, public rng_stream_type_from_record(rng_record)
Create a RNG stream from a record given as an internal file (string).
integer, parameter, public rng_record_length
integer, parameter, public gaussian
I/O subroutines for pint_env.
subroutine, public pint_write_line(line)
Writes out a line of text to the default output unit.
Methods to apply the piglet thermostat to PI runs.
elemental subroutine, public pint_calc_piglet_energy(pint_env)
returns the piglet kinetic energy contribution
subroutine, public pint_piglet_release(piglet_therm)
releases the piglet environment
subroutine, public pint_piglet_create(piglet_therm, pint_env, section)
creates the data structure for a piglet thermostating in PI runs
subroutine, public pint_piglet_step(vold, vnew, first_mode, masses, piglet_therm)
...
subroutine, public pint_piglet_init(piglet_therm, pint_env, section, dt, para_env)
initializes the data for a piglet run