22#include "../base/base_uses.f90"
31 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'realspace_grid_cube'
32 INTEGER,
PARAMETER,
PRIVATE :: cube_entry_len = 13, &
33 cube_num_entries_line = 6
34 INTEGER,
PARAMETER,
PRIVATE :: cube_line_len = cube_entry_len*cube_num_entries_line
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: missing_zeff_warning = &
38 "Effective nuclear charges were not supplied; "// &
39 "zeros will be written to the Cube atom records."
40 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
50 CHARACTER(LEN=*),
INTENT(IN) :: values
51 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: buffer
53 CHARACTER(LEN=cube_entry_len) :: value
54 INTEGER :: i, pos, readstat
56 READ (values, *, iostat=readstat) buffer
57 IF (readstat == 0)
RETURN
60 DO i = 1,
SIZE(buffer)
61 IF (pos + cube_entry_len - 1 > len(values)) cpabort(
"Unexpected end of cube data.")
62 value = values(pos:pos + cube_entry_len - 1)
63 READ (
value,
'(E13.5)', iostat=readstat) buffer(i)
64 IF (readstat /= 0) cpabort(
"Bad value while reading cube data.")
65 pos = pos + cube_entry_len
66 IF (
modulo(i, cube_num_entries_line) == 0)
THEN
67 IF (pos <= len(values))
THEN
68 IF (values(pos:pos) == new_line(
'C')) pos = pos + 1
89 SUBROUTINE pw_to_cube(pw, unit_nr, title, particles_r, particles_z, particles_zeff, &
90 stride, max_file_size_mb, zero_tails, silent, mpi_io)
92 INTEGER,
INTENT(IN) :: unit_nr
93 CHARACTER(*),
INTENT(IN),
OPTIONAL :: title
94 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
95 OPTIONAL :: particles_r
96 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_z
97 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_zeff
98 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: stride
99 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: max_file_size_mb
100 LOGICAL,
INTENT(IN),
OPTIONAL :: zero_tails, silent, mpi_io
102 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_to_cube'
103 INTEGER,
PARAMETER :: entry_len = 13, num_entries_line = 6
105 INTEGER :: checksum, dest, handle, i, i1, i2, i3, iat, ip, l1, l2, l3, msglen, my_rank, &
106 my_stride(3), np, num_linebreak, num_pe, rank(2), size_of_z, source, tag, u1, u2, u3
107 LOGICAL :: be_silent, my_zero_tails, parallel_write
108 REAL(kind=
dp) :: compression_factor, my_max_file_size_mb
109 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buf
113 CALL timeset(routinen, handle)
115 my_zero_tails = .false.
117 parallel_write = .false.
118 my_max_file_size_mb = 0.0_dp
119 IF (
PRESENT(zero_tails)) my_zero_tails = zero_tails
120 IF (
PRESENT(silent)) be_silent = silent
121 IF (
PRESENT(mpi_io)) parallel_write = mpi_io
122 IF (
PRESENT(max_file_size_mb)) my_max_file_size_mb = max_file_size_mb
123 cpassert(my_max_file_size_mb >= 0)
124 IF (.NOT. parallel_write .AND.
PRESENT(particles_z) .AND. &
125 .NOT.
PRESENT(particles_zeff))
THEN
126 cpwarn(missing_zeff_warning)
130 IF (
PRESENT(stride))
THEN
131 IF (
SIZE(stride) /= 1 .AND.
SIZE(stride) /= 3)
THEN
132 CALL cp_abort(__location__,
"STRIDE keyword can accept only 1 "// &
133 "(the same for X,Y,Z) or 3 values. Correct your input file.")
135 IF (
SIZE(stride) == 1)
THEN
137 my_stride(i) = stride(1)
140 my_stride = stride(1:3)
144 IF (my_max_file_size_mb > 0)
THEN
146 compression_factor = 1.3e-05_dp*product(real(pw%pw_grid%npts,
dp))/max_file_size_mb
147 my_stride(:) = int(compression_factor**(1.0/3.0)) + 1
150 cpassert(my_stride(1) > 0)
151 cpassert(my_stride(2) > 0)
152 cpassert(my_stride(3) > 0)
154 IF (.NOT. parallel_write)
THEN
155 IF (unit_nr > 0)
THEN
158 WRITE (unit_nr,
'(a11)')
"-Quickstep-"
159 IF (
PRESENT(title))
THEN
160 WRITE (unit_nr, *) trim(title)
162 WRITE (unit_nr, *)
"No Title"
165 cpassert(
PRESENT(particles_z) .EQV.
PRESENT(particles_r))
167 IF (
PRESENT(particles_z))
THEN
168 cpassert(
SIZE(particles_z) ==
SIZE(particles_r, dim=2))
171 np = min(99999,
SIZE(particles_z))
174 WRITE (unit_nr,
'(I5,3f12.6)') np, 0.0_dp, 0._dp, 0._dp
176 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(1) + my_stride(1) - 1)/my_stride(1), &
177 pw%pw_grid%dh(1, 1)*real(my_stride(1),
dp), pw%pw_grid%dh(2, 1)*real(my_stride(1),
dp), &
178 pw%pw_grid%dh(3, 1)*real(my_stride(1),
dp)
179 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(2) + my_stride(2) - 1)/my_stride(2), &
180 pw%pw_grid%dh(1, 2)*real(my_stride(2),
dp), pw%pw_grid%dh(2, 2)*real(my_stride(2),
dp), &
181 pw%pw_grid%dh(3, 2)*real(my_stride(2),
dp)
182 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(3) + my_stride(3) - 1)/my_stride(3), &
183 pw%pw_grid%dh(1, 3)*real(my_stride(3),
dp), pw%pw_grid%dh(2, 3)*real(my_stride(3),
dp), &
184 pw%pw_grid%dh(3, 3)*real(my_stride(3),
dp)
186 IF (
PRESENT(particles_z))
THEN
187 IF (
PRESENT(particles_zeff))
THEN
189 WRITE (unit_nr,
'(I5,4f12.6)') particles_z(iat), particles_zeff(iat), particles_r(:, iat)
193 WRITE (unit_nr,
'(I5,4f12.6)') particles_z(iat), 0._dp, particles_r(:, iat)
200 l1 = pw%pw_grid%bounds(1, 1)
201 l2 = pw%pw_grid%bounds(1, 2)
202 l3 = pw%pw_grid%bounds(1, 3)
203 u1 = pw%pw_grid%bounds(2, 1)
204 u2 = pw%pw_grid%bounds(2, 2)
205 u3 = pw%pw_grid%bounds(2, 3)
207 ALLOCATE (buf(l3:u3))
209 my_rank = pw%pw_grid%para%group%mepos
210 gid = pw%pw_grid%para%group
211 num_pe = pw%pw_grid%para%group%num_pe
217 IF (unit_nr > 0) checksum = 1
219 CALL gid%sum(checksum)
220 cpassert(checksum == 1)
222 CALL gid%maxloc(rank)
223 cpassert(rank(1) > 0)
226 DO i1 = l1, u1, my_stride(1)
227 DO i2 = l2, u2, my_stride(2)
231 DO ip = 0, num_pe - 1
232 IF (pw%pw_grid%para%bo(1, 1, ip, 1) <= i1 - l1 + 1 .AND. pw%pw_grid%para%bo(2, 1, ip, 1) >= i1 - l1 + 1 .AND. &
233 pw%pw_grid%para%bo(1, 2, ip, 1) <= i2 - l2 + 1 .AND. pw%pw_grid%para%bo(2, 2, ip, 1) >= i2 - l2 + 1)
THEN
241 IF (source == dest)
THEN
242 IF (my_rank == source)
THEN
243 buf(:) = pw%array(i1, i2, :)
246 IF (my_rank == source)
THEN
247 buf(:) = pw%array(i1, i2, :)
248 CALL gid%send(buf, dest, tag)
250 IF (my_rank == dest)
THEN
251 CALL gid%recv(buf, source, tag)
255 IF (unit_nr > 0)
THEN
256 IF (my_zero_tails)
THEN
258 IF (buf(i3) < 1.e-7_dp) buf(i3) = 0.0_dp
277 size_of_z = ceiling(real(pw%pw_grid%bounds(2, 3) - pw%pw_grid%bounds(1, 3) + 1,
dp)/real(my_stride(3),
dp))
278 num_linebreak = size_of_z/num_entries_line
279 IF (
modulo(size_of_z, num_entries_line) /= 0)
THEN
280 num_linebreak = num_linebreak + 1
283 CALL mp_unit%set_handle(unit_nr)
284 CALL pw_to_cube_parallel(pw, mp_unit, title, particles_r, particles_z, particles_zeff, &
285 my_stride, my_zero_tails, msglen)
288 CALL timestop(handle)
304 SUBROUTINE cube_to_pw(grid, filename, scaling, parallel_read, silent)
307 CHARACTER(len=*),
INTENT(in) :: filename
308 REAL(kind=
dp),
INTENT(in) :: scaling
309 LOGICAL,
INTENT(in) :: parallel_read
310 LOGICAL,
INTENT(in),
OPTIONAL :: silent
312 CHARACTER(len=*),
PARAMETER :: routinen =
'cube_to_pw'
313 INTEGER,
PARAMETER :: entry_len = 13, num_entries_line = 6
315 CHARACTER(LEN=cube_line_len) :: value_line
316 INTEGER :: extunit, handle, i, j, k, last_z, &
317 msglen, my_rank, nat, ndum, &
318 num_linebreak, num_pe, output_unit, &
320 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, npoints, &
321 npoints_local, ubounds, ubounds_local
323 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buffer
324 REAL(kind=
dp),
DIMENSION(3) :: dr, rdum
329 CALL timeset(routinen, handle)
332 IF (
PRESENT(silent))
THEN
336 gid = grid%pw_grid%para%group
337 my_rank = grid%pw_grid%para%group%mepos
338 num_pe = grid%pw_grid%para%group%num_pe
341 lbounds_local = grid%pw_grid%bounds_local(1, :)
342 ubounds_local = grid%pw_grid%bounds_local(2, :)
343 size_of_z = ubounds_local(3) - lbounds_local(3) + 1
345 IF (.NOT. parallel_read)
THEN
346 npoints = grid%pw_grid%npts
347 lbounds = grid%pw_grid%bounds(1, :)
348 ubounds = grid%pw_grid%bounds(2, :)
351 dr(i) = grid%pw_grid%dh(i, i)
354 npoints_local = grid%pw_grid%npts_local
356 ALLOCATE (buffer(lbounds(3):ubounds(3)))
358 IF (my_rank == 0)
THEN
359 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
360 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A,/)")
"Reading the cube file: ", trim(filename)
365 file_form=
"FORMATTED", &
366 file_action=
"READ", &
373 READ (extunit, *) nat, rdum
375 READ (extunit, *) ndum, rdum
376 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
377 output_unit > 0)
THEN
378 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
379 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
380 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
390 DO i = lbounds(1), ubounds(1)
391 DO j = lbounds(2), ubounds(2)
392 IF (my_rank == 0)
THEN
393 DO k = lbounds(3), ubounds(3), cube_num_entries_line
394 last_z = min(k + cube_num_entries_line - 1, ubounds(3))
395 READ (extunit,
'(A)') value_line
399 CALL gid%bcast(buffer(lbounds(3):ubounds(3)), 0)
402 IF ((lbounds_local(1) <= i) .AND. (i <= ubounds_local(1)) .AND. (lbounds_local(2) <= j) &
403 .AND. (j <= ubounds_local(2)))
THEN
405 grid%array(i, j, lbounds(3):ubounds(3)) = buffer(lbounds(3):ubounds(3))*scaling
411 IF (my_rank == 0)
CALL close_file(unit_number=extunit)
420 num_linebreak = size_of_z/num_entries_line
421 IF (
modulo(size_of_z, num_entries_line) /= 0)
THEN
422 num_linebreak = num_linebreak + 1
425 CALL cube_to_pw_parallel(grid, filename, scaling, msglen, silent=silent)
428 CALL timestop(handle)
443 SUBROUTINE cube_to_pw_parallel(grid, filename, scaling, msglen, silent)
446 CHARACTER(len=*),
INTENT(in) :: filename
447 REAL(kind=
dp),
INTENT(in) :: scaling
448 INTEGER,
INTENT(in) :: msglen
449 LOGICAL,
INTENT(in),
OPTIONAL :: silent
451 CHARACTER(LEN=cube_line_len) :: value_line
452 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, npoints, &
453 npoints_local, ubounds, ubounds_local
454 INTEGER,
ALLOCATABLE,
DIMENSION(:),
TARGET :: blocklengths
455 INTEGER(kind=file_offset),
ALLOCATABLE, &
456 DIMENSION(:),
TARGET :: displacements
457 INTEGER(kind=file_offset) :: bof
458 INTEGER :: extunit_handle, i, islice, j, k, last_z, &
459 my_rank, nat, ndum, nslices, num_pe, &
460 offset_global, output_unit, size_of_z, &
462 CHARACTER(LEN=msglen),
ALLOCATABLE,
DIMENSION(:) ::
readbuffer
463 LOGICAL :: be_silent, should_read(2)
464 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buffer
465 REAL(kind=
dp),
DIMENSION(3) :: dr, rdum
473 IF (
PRESENT(silent))
THEN
478 gid = grid%pw_grid%para%group
479 my_rank = grid%pw_grid%para%group%mepos
480 num_pe = grid%pw_grid%para%group%num_pe
484 dr(i) = grid%pw_grid%dh(i, i)
487 npoints = grid%pw_grid%npts
488 lbounds = grid%pw_grid%bounds(1, :)
489 ubounds = grid%pw_grid%bounds(2, :)
491 npoints_local = grid%pw_grid%npts_local
492 lbounds_local = grid%pw_grid%bounds_local(1, :)
493 ubounds_local = grid%pw_grid%bounds_local(2, :)
494 size_of_z = ubounds_local(3) - lbounds_local(3) + 1
495 nslices = (ubounds_local(1) - lbounds_local(1) + 1)*(ubounds_local(2) - lbounds_local(2) + 1)
499 IF (my_rank == 0)
THEN
500 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
501 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A,/)")
"Reading the cube file: ", trim(filename)
506 file_form=
"FORMATTED", &
507 file_action=
"READ", &
508 file_access=
"STREAM", &
509 unit_number=extunit_handle)
513 READ (extunit_handle, *)
515 READ (extunit_handle, *) nat, rdum
517 READ (extunit_handle, *) ndum, rdum
518 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
519 output_unit > 0)
THEN
520 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
521 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
522 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
527 READ (extunit_handle, *)
530 INQUIRE (extunit_handle, pos=offset_global)
534 CALL gid%bcast(offset_global, grid%pw_grid%para%group%source)
537 bof = offset_global - 1
538 CALL extunit%open(groupid=gid, filepath=filename, amode_status=
file_amode_rdonly)
540 ALLOCATE (displacements(nslices))
542 DO i = lbounds(1), ubounds(1)
543 should_read(:) = .true.
544 IF (i < lbounds_local(1))
THEN
545 should_read(1) = .false.
546 ELSE IF (i > ubounds_local(1))
THEN
549 DO j = lbounds(2), ubounds(2)
550 should_read(2) = .true.
551 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
552 should_read(2) = .false.
554 IF (all(should_read .EQV. .true.))
THEN
555 IF (islice > nslices) cpabort(
"Index out of bounds.")
556 displacements(islice) = bof
564 ALLOCATE (blocklengths(nslices))
565 blocklengths(:) = msglen
573 CALL extunit%read_all(msglen, nslices,
readbuffer, mp_file_desc)
579 ALLOCATE (buffer(lbounds(3):ubounds(3)))
581 DO islice = 1, nslices
584 grid%array(i, j, lbounds(3):ubounds(3)) = scaling*buffer(lbounds(3):ubounds(3))
586 IF (j > ubounds_local(2))
THEN
592 DEALLOCATE (blocklengths, displacements)
593 IF (debug_this_module)
THEN
596 IF (my_rank == 0)
THEN
597 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
598 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A)")
"Reading the cube file: ", filename
603 file_form=
"FORMATTED", &
604 file_action=
"READ", &
605 unit_number=extunit_handle)
609 READ (extunit_handle, *)
611 READ (extunit_handle, *) nat, rdum
613 READ (extunit_handle, *) ndum, rdum
614 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
615 output_unit > 0)
THEN
616 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
617 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
618 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
623 READ (extunit_handle, *)
628 DO i = lbounds(1), ubounds(1)
629 DO j = lbounds(2), ubounds(2)
630 IF (my_rank == 0)
THEN
631 DO k = lbounds(3), ubounds(3), cube_num_entries_line
632 last_z = min(k + cube_num_entries_line - 1, ubounds(3))
633 READ (extunit_handle,
'(A)') value_line
637 CALL gid%bcast(buffer(lbounds(3):ubounds(3)), 0)
640 IF ((lbounds_local(1) <= i) .AND. (i <= ubounds_local(1)) .AND. (lbounds_local(2) <= j) &
641 .AND. (j <= ubounds_local(2)))
THEN
643 IF (any(grid%array(i, j, lbounds(3):ubounds(3)) /= buffer(lbounds(3):ubounds(3))*scaling))
THEN
644 CALL cp_abort(__location__, &
645 "Error in parallel read of input cube file.")
652 IF (my_rank == 0)
CALL close_file(unit_number=extunit_handle)
658 END SUBROUTINE cube_to_pw_parallel
674 SUBROUTINE pw_to_cube_parallel(grid, unit_nr, title, particles_r, particles_z, particles_zeff, &
675 stride, zero_tails, msglen)
679 CHARACTER(*),
INTENT(IN),
OPTIONAL :: title
680 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
681 OPTIONAL :: particles_r
682 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_z
683 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_zeff
684 INTEGER,
INTENT(IN) :: stride(3)
685 LOGICAL,
INTENT(IN) :: zero_tails
686 INTEGER,
INTENT(IN) :: msglen
688 INTEGER,
PARAMETER :: entry_len = 13, header_len = 41, &
689 header_len_z = 53, num_entries_line = 6
691 CHARACTER(LEN=entry_len) :: value
692 CHARACTER(LEN=header_len) ::
header
693 CHARACTER(LEN=header_len_z) :: header_z
694 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, ubounds, &
696 INTEGER,
ALLOCATABLE,
DIMENSION(:),
TARGET :: blocklengths
697 INTEGER(kind=file_offset),
ALLOCATABLE, &
698 DIMENSION(:),
TARGET :: displacements
699 INTEGER(kind=file_offset) :: bof
700 INTEGER :: counter, i, islice, j, k, last_z, &
701 my_rank, np, nslices, size_of_z
702 CHARACTER(LEN=msglen),
ALLOCATABLE,
DIMENSION(:) ::
writebuffer
703 CHARACTER(LEN=msglen) :: tmp
704 LOGICAL :: should_write(2)
709 gid = grid%pw_grid%para%group
710 my_rank = grid%pw_grid%para%group%mepos
711 IF (
PRESENT(particles_z) .AND. .NOT.
PRESENT(particles_zeff))
THEN
712 cpwarn(missing_zeff_warning)
716 lbounds = grid%pw_grid%bounds(1, :)
717 ubounds = grid%pw_grid%bounds(2, :)
718 lbounds_local = grid%pw_grid%bounds_local(1, :)
719 ubounds_local = grid%pw_grid%bounds_local(2, :)
721 size_of_z = ceiling(real(ubounds_local(3) - lbounds_local(3) + 1,
dp)/real(stride(3),
dp))
723 DO i = lbounds(1), ubounds(1), stride(1)
724 should_write(:) = .true.
725 IF (i < lbounds_local(1))
THEN
726 should_write(1) = .false.
727 ELSE IF (i > ubounds_local(1))
THEN
730 DO j = lbounds(2), ubounds(2), stride(2)
731 should_write(2) = .true.
732 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
733 should_write(2) = .false.
735 IF (all(should_write .EQV. .true.))
THEN
741 DO k = lbounds(3), ubounds(3), stride(3)
742 IF (k + stride(3) > ubounds(3)) last_z = k
746 CALL unit_nr%get_position(bof)
748 IF (my_rank == 0)
THEN
751 CALL unit_nr%write_at(bof,
"-Quickstep-"//new_line(
"C"))
753 IF (
PRESENT(title))
THEN
754 CALL unit_nr%write_at(bof, trim(title)//new_line(
"C"))
757 CALL unit_nr%write_at(bof,
"No Title"//new_line(
"C"))
761 cpassert(
PRESENT(particles_z) .EQV.
PRESENT(particles_r))
763 IF (
PRESENT(particles_z))
THEN
764 cpassert(
SIZE(particles_z) ==
SIZE(particles_r, dim=2))
767 np = min(99999,
SIZE(particles_z))
770 WRITE (
header,
'(I5,3f12.6)') np, 0.0_dp, 0._dp, 0._dp
771 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
774 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(1) + stride(1) - 1)/stride(1), &
775 grid%pw_grid%dh(1, 1)*real(stride(1),
dp), grid%pw_grid%dh(2, 1)*real(stride(1),
dp), &
776 grid%pw_grid%dh(3, 1)*real(stride(1),
dp)
777 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
780 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(2) + stride(2) - 1)/stride(2), &
781 grid%pw_grid%dh(1, 2)*real(stride(2),
dp), grid%pw_grid%dh(2, 2)*real(stride(2),
dp), &
782 grid%pw_grid%dh(3, 2)*real(stride(2),
dp)
783 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
786 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(3) + stride(3) - 1)/stride(3), &
787 grid%pw_grid%dh(1, 3)*real(stride(3),
dp), grid%pw_grid%dh(2, 3)*real(stride(3),
dp), &
788 grid%pw_grid%dh(3, 3)*real(stride(3),
dp)
789 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
792 IF (
PRESENT(particles_z))
THEN
793 IF (
PRESENT(particles_zeff))
THEN
795 WRITE (header_z,
'(I5,4f12.6)') particles_z(i), particles_zeff(i), particles_r(:, i)
796 CALL unit_nr%write_at(bof, header_z//new_line(
"C"))
801 WRITE (header_z,
'(I5,4f12.6)') particles_z(i), 0._dp, particles_r(:, i)
802 CALL unit_nr%write_at(bof, header_z//new_line(
"C"))
809 CALL gid%bcast(bof, grid%pw_grid%para%group%source)
812 ALLOCATE (displacements(nslices))
816 DO i = lbounds(1), ubounds(1), stride(1)
817 should_write(:) = .true.
818 IF (i < lbounds_local(1))
THEN
819 should_write(1) = .false.
820 ELSE IF (i > ubounds_local(1))
THEN
823 DO j = lbounds(2), ubounds(2), stride(2)
824 should_write(2) = .true.
825 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
826 should_write(2) = .false.
828 IF (all(should_write .EQV. .true.))
THEN
829 IF (islice > nslices) cpabort(
"Index out of bounds.")
830 displacements(islice) = bof
833 DO k = lbounds(3), ubounds(3), stride(3)
834 IF (zero_tails .AND. grid%array(i, j, k) < 1.e-7_dp)
THEN
839 tmp = trim(tmp)//trim(
value)
840 counter = counter + 1
841 IF (
modulo(counter, num_entries_line) == 0 .OR. k == last_z)
THEN
842 tmp = trim(tmp)//new_line(
'C')
854 ALLOCATE (blocklengths(nslices))
855 blocklengths(:) = msglen
864 CALL unit_nr%write_all(msglen, nslices,
writebuffer, mp_desc)
868 DEALLOCATE (blocklengths, displacements)
870 END SUBROUTINE pw_to_cube_parallel
884 INTEGER,
INTENT(IN) :: unit_nr
885 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: stride
888 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_to_simple_volumetric'
890 INTEGER :: checksum, dest, handle, i, i1, i2, i3, &
891 ip, l1, l2, l3, my_rank, my_stride(3), &
892 ngrids, npoints, num_pe, rank(2), &
893 source, tag, u1, u2, u3
895 REAL(kind=
dp) :: x, y, z
896 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buf, buf2
899 CALL timeset(routinen, handle)
903 IF (
PRESENT(pw2)) double = .true.
906 IF (
PRESENT(stride))
THEN
907 IF (
SIZE(stride) /= 1 .AND.
SIZE(stride) /= 3)
THEN
908 CALL cp_abort(__location__,
"STRIDE keyword can accept only 1 "// &
909 "(the same for X,Y,Z) or 3 values. Correct your input file.")
911 IF (
SIZE(stride) == 1)
THEN
913 my_stride(i) = stride(1)
916 my_stride = stride(1:3)
918 cpassert(my_stride(1) > 0)
919 cpassert(my_stride(2) > 0)
920 cpassert(my_stride(3) > 0)
924 l1 = pw%pw_grid%bounds(1, 1)
925 l2 = pw%pw_grid%bounds(1, 2)
926 l3 = pw%pw_grid%bounds(1, 3)
927 u1 = pw%pw_grid%bounds(2, 1)
928 u2 = pw%pw_grid%bounds(2, 2)
929 u3 = pw%pw_grid%bounds(2, 3)
933 IF (double) ngrids = 2
934 npoints = ((pw%pw_grid%npts(1) + my_stride(1) - 1)/my_stride(1))* &
935 ((pw%pw_grid%npts(2) + my_stride(2) - 1)/my_stride(1))* &
936 ((pw%pw_grid%npts(3) + my_stride(3) - 1)/my_stride(1))
937 IF (unit_nr > 1)
WRITE (unit_nr,
'(I7,I5)') npoints, ngrids
939 ALLOCATE (buf(l3:u3))
940 IF (double)
ALLOCATE (buf2(l3:u3))
942 my_rank = pw%pw_grid%para%group%mepos
943 gid = pw%pw_grid%para%group
944 num_pe = pw%pw_grid%para%group%num_pe
950 IF (unit_nr > 0) checksum = 1
952 CALL gid%sum(checksum)
953 cpassert(checksum == 1)
955 CALL gid%maxloc(rank)
956 cpassert(rank(1) > 0)
959 DO i1 = l1, u1, my_stride(1)
960 DO i2 = l2, u2, my_stride(2)
964 DO ip = 0, num_pe - 1
965 IF (pw%pw_grid%para%bo(1, 1, ip, 1) <= i1 - l1 + 1 .AND. pw%pw_grid%para%bo(2, 1, ip, 1) >= i1 - l1 + 1 .AND. &
966 pw%pw_grid%para%bo(1, 2, ip, 1) <= i2 - l2 + 1 .AND. pw%pw_grid%para%bo(2, 2, ip, 1) >= i2 - l2 + 1)
THEN
974 IF (source == dest)
THEN
975 IF (my_rank == source)
THEN
976 buf(:) = pw%array(i1, i2, :)
977 IF (double) buf2(:) = pw2%array(i1, i2, :)
980 IF (my_rank == source)
THEN
981 buf(:) = pw%array(i1, i2, :)
982 CALL gid%send(buf, dest, tag)
984 buf2(:) = pw2%array(i1, i2, :)
985 CALL gid%send(buf2, dest, tag)
988 IF (my_rank == dest)
THEN
989 CALL gid%recv(buf, source, tag)
990 IF (double)
CALL gid%recv(buf2, source, tag)
994 IF (.NOT. double)
THEN
995 DO i3 = l3, u3, my_stride(3)
996 x = pw%pw_grid%dh(1, 1)*i1 + &
997 pw%pw_grid%dh(2, 1)*i2 + &
998 pw%pw_grid%dh(3, 1)*i3
1000 y = pw%pw_grid%dh(1, 2)*i1 + &
1001 pw%pw_grid%dh(2, 2)*i2 + &
1002 pw%pw_grid%dh(3, 2)*i3
1004 z = pw%pw_grid%dh(1, 3)*i1 + &
1005 pw%pw_grid%dh(2, 3)*i2 + &
1006 pw%pw_grid%dh(3, 3)*i3
1008 IF (unit_nr > 0)
THEN
1009 WRITE (unit_nr,
'(6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3))') x, y, z, buf(i3)
1015 DO i3 = l3, u3, my_stride(3)
1016 x = pw%pw_grid%dh(1, 1)*i1 + &
1017 pw%pw_grid%dh(2, 1)*i2 + &
1018 pw%pw_grid%dh(3, 1)*i3
1020 y = pw%pw_grid%dh(1, 2)*i1 + &
1021 pw%pw_grid%dh(2, 2)*i2 + &
1022 pw%pw_grid%dh(3, 2)*i3
1024 z = pw%pw_grid%dh(1, 3)*i1 + &
1025 pw%pw_grid%dh(2, 3)*i2 + &
1026 pw%pw_grid%dh(3, 3)*i3
1028 IF (unit_nr > 0)
THEN
1029 WRITE (unit_nr,
'(6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3))') x, y, z, buf(i3), buf2(i3)
1047 IF (double)
DEALLOCATE (buf2)
1049 CALL timestop(handle)
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
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.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
type(mp_file_descriptor_type) function, public mp_file_type_hindexed_make_chv(count, lengths, displs)
Creates an indexed MPI type for arrays of strings using bytes for spacing (hindexed type)
subroutine, public mp_file_type_free(type_descriptor)
Releases the type used for MPI I/O.
integer, parameter, public mpi_character_size
integer, parameter, public file_offset
integer, parameter, public file_amode_rdonly
subroutine, public mp_file_type_set_view_chv(fh, offset, type_descriptor)
Uses a previously created indexed MPI character type to tell the MPI processes how to partition (set_...
integer, parameter, public pw_mode_local
Generate Gaussian cube files.
subroutine, public cube_to_pw(grid, filename, scaling, parallel_read, silent)
Computes the external density on the grid hacked from external_read_density.
character(len= *), parameter, public cube_values_format
subroutine, public pw_to_simple_volumetric(pw, unit_nr, stride, pw2)
Prints a simple grid file: X Y Z value.
character(len= *), parameter, public cube_value_format
subroutine, public pw_to_cube(pw, unit_nr, title, particles_r, particles_z, particles_zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
subroutine, public cube_read_values(values, buffer)
Read cube values from a character buffer.
void writebuffer(int *psockfd, char *data, int *plen)
Writes to a socket.
void readbuffer(int *psockfd, char *data, int *plen)
Reads from a socket.