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 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
47 CHARACTER(LEN=*),
INTENT(IN) :: values
48 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: buffer
50 CHARACTER(LEN=cube_entry_len) :: value
51 INTEGER :: i, pos, readstat
53 READ (values, *, iostat=readstat) buffer
54 IF (readstat == 0)
RETURN
57 DO i = 1,
SIZE(buffer)
58 IF (pos + cube_entry_len - 1 > len(values)) cpabort(
"Unexpected end of cube data.")
59 value = values(pos:pos + cube_entry_len - 1)
60 READ (
value,
'(E13.5)', iostat=readstat) buffer(i)
61 IF (readstat /= 0) cpabort(
"Bad value while reading cube data.")
62 pos = pos + cube_entry_len
63 IF (
modulo(i, cube_num_entries_line) == 0)
THEN
64 IF (pos <= len(values))
THEN
65 IF (values(pos:pos) == new_line(
'C')) pos = pos + 1
86 SUBROUTINE pw_to_cube(pw, unit_nr, title, particles_r, particles_z, particles_zeff, &
87 stride, max_file_size_mb, zero_tails, silent, mpi_io)
89 INTEGER,
INTENT(IN) :: unit_nr
90 CHARACTER(*),
INTENT(IN),
OPTIONAL :: title
91 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
92 OPTIONAL :: particles_r
93 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_z
94 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_zeff
95 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: stride
96 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: max_file_size_mb
97 LOGICAL,
INTENT(IN),
OPTIONAL :: zero_tails, silent, mpi_io
99 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_to_cube'
100 INTEGER,
PARAMETER :: entry_len = 13, num_entries_line = 6
102 INTEGER :: checksum, dest, handle, i, i1, i2, i3, iat, ip, l1, l2, l3, msglen, my_rank, &
103 my_stride(3), np, num_linebreak, num_pe, rank(2), size_of_z, source, tag, u1, u2, u3
104 LOGICAL :: be_silent, my_zero_tails, parallel_write
105 REAL(kind=
dp) :: compression_factor, my_max_file_size_mb
106 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buf
110 CALL timeset(routinen, handle)
112 my_zero_tails = .false.
114 parallel_write = .false.
115 my_max_file_size_mb = 0.0_dp
116 IF (
PRESENT(zero_tails)) my_zero_tails = zero_tails
117 IF (
PRESENT(silent)) be_silent = silent
118 IF (
PRESENT(mpi_io)) parallel_write = mpi_io
119 IF (
PRESENT(max_file_size_mb)) my_max_file_size_mb = max_file_size_mb
120 cpassert(my_max_file_size_mb >= 0)
123 IF (
PRESENT(stride))
THEN
124 IF (
SIZE(stride) /= 1 .AND.
SIZE(stride) /= 3)
THEN
125 CALL cp_abort(__location__,
"STRIDE keyword can accept only 1 "// &
126 "(the same for X,Y,Z) or 3 values. Correct your input file.")
128 IF (
SIZE(stride) == 1)
THEN
130 my_stride(i) = stride(1)
133 my_stride = stride(1:3)
137 IF (my_max_file_size_mb > 0)
THEN
139 compression_factor = 1.3e-05_dp*product(real(pw%pw_grid%npts,
dp))/max_file_size_mb
140 my_stride(:) = int(compression_factor**(1.0/3.0)) + 1
143 cpassert(my_stride(1) > 0)
144 cpassert(my_stride(2) > 0)
145 cpassert(my_stride(3) > 0)
147 IF (.NOT. parallel_write)
THEN
148 IF (unit_nr > 0)
THEN
151 WRITE (unit_nr,
'(a11)')
"-Quickstep-"
152 IF (
PRESENT(title))
THEN
153 WRITE (unit_nr, *) trim(title)
155 WRITE (unit_nr, *)
"No Title"
158 cpassert(
PRESENT(particles_z) .EQV.
PRESENT(particles_r))
160 IF (
PRESENT(particles_z))
THEN
161 cpassert(
SIZE(particles_z) ==
SIZE(particles_r, dim=2))
164 np = min(99999,
SIZE(particles_z))
167 WRITE (unit_nr,
'(I5,3f12.6)') np, 0.0_dp, 0._dp, 0._dp
169 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(1) + my_stride(1) - 1)/my_stride(1), &
170 pw%pw_grid%dh(1, 1)*real(my_stride(1),
dp), pw%pw_grid%dh(2, 1)*real(my_stride(1),
dp), &
171 pw%pw_grid%dh(3, 1)*real(my_stride(1),
dp)
172 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(2) + my_stride(2) - 1)/my_stride(2), &
173 pw%pw_grid%dh(1, 2)*real(my_stride(2),
dp), pw%pw_grid%dh(2, 2)*real(my_stride(2),
dp), &
174 pw%pw_grid%dh(3, 2)*real(my_stride(2),
dp)
175 WRITE (unit_nr,
'(I5,3f12.6)') (pw%pw_grid%npts(3) + my_stride(3) - 1)/my_stride(3), &
176 pw%pw_grid%dh(1, 3)*real(my_stride(3),
dp), pw%pw_grid%dh(2, 3)*real(my_stride(3),
dp), &
177 pw%pw_grid%dh(3, 3)*real(my_stride(3),
dp)
179 IF (
PRESENT(particles_z))
THEN
180 IF (
PRESENT(particles_zeff))
THEN
182 WRITE (unit_nr,
'(I5,4f12.6)') particles_z(iat), particles_zeff(iat), particles_r(:, iat)
186 WRITE (unit_nr,
'(I5,4f12.6)') particles_z(iat), 0._dp, particles_r(:, iat)
193 l1 = pw%pw_grid%bounds(1, 1)
194 l2 = pw%pw_grid%bounds(1, 2)
195 l3 = pw%pw_grid%bounds(1, 3)
196 u1 = pw%pw_grid%bounds(2, 1)
197 u2 = pw%pw_grid%bounds(2, 2)
198 u3 = pw%pw_grid%bounds(2, 3)
200 ALLOCATE (buf(l3:u3))
202 my_rank = pw%pw_grid%para%group%mepos
203 gid = pw%pw_grid%para%group
204 num_pe = pw%pw_grid%para%group%num_pe
210 IF (unit_nr > 0) checksum = 1
212 CALL gid%sum(checksum)
213 cpassert(checksum == 1)
215 CALL gid%maxloc(rank)
216 cpassert(rank(1) > 0)
219 DO i1 = l1, u1, my_stride(1)
220 DO i2 = l2, u2, my_stride(2)
224 DO ip = 0, num_pe - 1
225 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. &
226 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
234 IF (source == dest)
THEN
235 IF (my_rank == source)
THEN
236 buf(:) = pw%array(i1, i2, :)
239 IF (my_rank == source)
THEN
240 buf(:) = pw%array(i1, i2, :)
241 CALL gid%send(buf, dest, tag)
243 IF (my_rank == dest)
THEN
244 CALL gid%recv(buf, source, tag)
248 IF (unit_nr > 0)
THEN
249 IF (my_zero_tails)
THEN
251 IF (buf(i3) < 1.e-7_dp) buf(i3) = 0.0_dp
270 size_of_z = ceiling(real(pw%pw_grid%bounds(2, 3) - pw%pw_grid%bounds(1, 3) + 1,
dp)/real(my_stride(3),
dp))
271 num_linebreak = size_of_z/num_entries_line
272 IF (
modulo(size_of_z, num_entries_line) /= 0)
THEN
273 num_linebreak = num_linebreak + 1
276 CALL mp_unit%set_handle(unit_nr)
277 CALL pw_to_cube_parallel(pw, mp_unit, title, particles_r, particles_z, particles_zeff, &
278 my_stride, my_zero_tails, msglen)
281 CALL timestop(handle)
297 SUBROUTINE cube_to_pw(grid, filename, scaling, parallel_read, silent)
300 CHARACTER(len=*),
INTENT(in) :: filename
301 REAL(kind=
dp),
INTENT(in) :: scaling
302 LOGICAL,
INTENT(in) :: parallel_read
303 LOGICAL,
INTENT(in),
OPTIONAL :: silent
305 CHARACTER(len=*),
PARAMETER :: routinen =
'cube_to_pw'
306 INTEGER,
PARAMETER :: entry_len = 13, num_entries_line = 6
308 CHARACTER(LEN=cube_line_len) :: value_line
309 INTEGER :: extunit, handle, i, j, k, last_z, &
310 msglen, my_rank, nat, ndum, &
311 num_linebreak, num_pe, output_unit, &
313 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, npoints, &
314 npoints_local, ubounds, ubounds_local
316 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buffer
317 REAL(kind=
dp),
DIMENSION(3) :: dr, rdum
322 CALL timeset(routinen, handle)
325 IF (
PRESENT(silent))
THEN
329 gid = grid%pw_grid%para%group
330 my_rank = grid%pw_grid%para%group%mepos
331 num_pe = grid%pw_grid%para%group%num_pe
334 lbounds_local = grid%pw_grid%bounds_local(1, :)
335 ubounds_local = grid%pw_grid%bounds_local(2, :)
336 size_of_z = ubounds_local(3) - lbounds_local(3) + 1
338 IF (.NOT. parallel_read)
THEN
339 npoints = grid%pw_grid%npts
340 lbounds = grid%pw_grid%bounds(1, :)
341 ubounds = grid%pw_grid%bounds(2, :)
344 dr(i) = grid%pw_grid%dh(i, i)
347 npoints_local = grid%pw_grid%npts_local
349 ALLOCATE (buffer(lbounds(3):ubounds(3)))
351 IF (my_rank == 0)
THEN
352 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
353 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A,/)")
"Reading the cube file: ", trim(filename)
358 file_form=
"FORMATTED", &
359 file_action=
"READ", &
366 READ (extunit, *) nat, rdum
368 READ (extunit, *) ndum, rdum
369 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
370 output_unit > 0)
THEN
371 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
372 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
373 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
383 DO i = lbounds(1), ubounds(1)
384 DO j = lbounds(2), ubounds(2)
385 IF (my_rank == 0)
THEN
386 DO k = lbounds(3), ubounds(3), cube_num_entries_line
387 last_z = min(k + cube_num_entries_line - 1, ubounds(3))
388 READ (extunit,
'(A)') value_line
392 CALL gid%bcast(buffer(lbounds(3):ubounds(3)), 0)
395 IF ((lbounds_local(1) <= i) .AND. (i <= ubounds_local(1)) .AND. (lbounds_local(2) <= j) &
396 .AND. (j <= ubounds_local(2)))
THEN
398 grid%array(i, j, lbounds(3):ubounds(3)) = buffer(lbounds(3):ubounds(3))*scaling
404 IF (my_rank == 0)
CALL close_file(unit_number=extunit)
413 num_linebreak = size_of_z/num_entries_line
414 IF (
modulo(size_of_z, num_entries_line) /= 0)
THEN
415 num_linebreak = num_linebreak + 1
418 CALL cube_to_pw_parallel(grid, filename, scaling, msglen, silent=silent)
421 CALL timestop(handle)
436 SUBROUTINE cube_to_pw_parallel(grid, filename, scaling, msglen, silent)
439 CHARACTER(len=*),
INTENT(in) :: filename
440 REAL(kind=
dp),
INTENT(in) :: scaling
441 INTEGER,
INTENT(in) :: msglen
442 LOGICAL,
INTENT(in),
OPTIONAL :: silent
444 CHARACTER(LEN=cube_line_len) :: value_line
445 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, npoints, &
446 npoints_local, ubounds, ubounds_local
447 INTEGER,
ALLOCATABLE,
DIMENSION(:),
TARGET :: blocklengths
448 INTEGER(kind=file_offset),
ALLOCATABLE, &
449 DIMENSION(:),
TARGET :: displacements
450 INTEGER(kind=file_offset) :: bof
451 INTEGER :: extunit_handle, i, islice, j, k, last_z, &
452 my_rank, nat, ndum, nslices, num_pe, &
453 offset_global, output_unit, size_of_z, &
455 CHARACTER(LEN=msglen),
ALLOCATABLE,
DIMENSION(:) ::
readbuffer
456 LOGICAL :: be_silent, should_read(2)
457 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buffer
458 REAL(kind=
dp),
DIMENSION(3) :: dr, rdum
466 IF (
PRESENT(silent))
THEN
471 gid = grid%pw_grid%para%group
472 my_rank = grid%pw_grid%para%group%mepos
473 num_pe = grid%pw_grid%para%group%num_pe
477 dr(i) = grid%pw_grid%dh(i, i)
480 npoints = grid%pw_grid%npts
481 lbounds = grid%pw_grid%bounds(1, :)
482 ubounds = grid%pw_grid%bounds(2, :)
484 npoints_local = grid%pw_grid%npts_local
485 lbounds_local = grid%pw_grid%bounds_local(1, :)
486 ubounds_local = grid%pw_grid%bounds_local(2, :)
487 size_of_z = ubounds_local(3) - lbounds_local(3) + 1
488 nslices = (ubounds_local(1) - lbounds_local(1) + 1)*(ubounds_local(2) - lbounds_local(2) + 1)
492 IF (my_rank == 0)
THEN
493 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
494 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A,/)")
"Reading the cube file: ", trim(filename)
499 file_form=
"FORMATTED", &
500 file_action=
"READ", &
501 file_access=
"STREAM", &
502 unit_number=extunit_handle)
506 READ (extunit_handle, *)
508 READ (extunit_handle, *) nat, rdum
510 READ (extunit_handle, *) ndum, rdum
511 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
512 output_unit > 0)
THEN
513 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
514 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
515 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
520 READ (extunit_handle, *)
523 INQUIRE (extunit_handle, pos=offset_global)
527 CALL gid%bcast(offset_global, grid%pw_grid%para%group%source)
530 bof = offset_global - 1
531 CALL extunit%open(groupid=gid, filepath=filename, amode_status=
file_amode_rdonly)
533 ALLOCATE (displacements(nslices))
535 DO i = lbounds(1), ubounds(1)
536 should_read(:) = .true.
537 IF (i < lbounds_local(1))
THEN
538 should_read(1) = .false.
539 ELSE IF (i > ubounds_local(1))
THEN
542 DO j = lbounds(2), ubounds(2)
543 should_read(2) = .true.
544 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
545 should_read(2) = .false.
547 IF (all(should_read .EQV. .true.))
THEN
548 IF (islice > nslices) cpabort(
"Index out of bounds.")
549 displacements(islice) = bof
557 ALLOCATE (blocklengths(nslices))
558 blocklengths(:) = msglen
566 CALL extunit%read_all(msglen, nslices,
readbuffer, mp_file_desc)
572 ALLOCATE (buffer(lbounds(3):ubounds(3)))
574 DO islice = 1, nslices
577 grid%array(i, j, lbounds(3):ubounds(3)) = scaling*buffer(lbounds(3):ubounds(3))
579 IF (j > ubounds_local(2))
THEN
585 DEALLOCATE (blocklengths, displacements)
586 IF (debug_this_module)
THEN
589 IF (my_rank == 0)
THEN
590 IF (output_unit > 0 .AND. .NOT. be_silent)
THEN
591 WRITE (output_unit, fmt=
"(/,T2,A,/,/,T2,A)")
"Reading the cube file: ", filename
596 file_form=
"FORMATTED", &
597 file_action=
"READ", &
598 unit_number=extunit_handle)
602 READ (extunit_handle, *)
604 READ (extunit_handle, *) nat, rdum
606 READ (extunit_handle, *) ndum, rdum
607 IF ((ndum /= npoints(i) .OR. (abs(rdum(i) - dr(i)) > 1e-4)) .AND. &
608 output_unit > 0)
THEN
609 WRITE (output_unit, *)
"Restart from density | ERROR! | CUBE FILE NOT COINCIDENT WITH INTERNAL GRID ", i
610 WRITE (output_unit, *)
"Restart from density | ", ndum,
" DIFFERS FROM ", npoints(i)
611 WRITE (output_unit, *)
"Restart from density | ", rdum,
" DIFFERS FROM ", dr(i)
616 READ (extunit_handle, *)
621 DO i = lbounds(1), ubounds(1)
622 DO j = lbounds(2), ubounds(2)
623 IF (my_rank == 0)
THEN
624 DO k = lbounds(3), ubounds(3), cube_num_entries_line
625 last_z = min(k + cube_num_entries_line - 1, ubounds(3))
626 READ (extunit_handle,
'(A)') value_line
630 CALL gid%bcast(buffer(lbounds(3):ubounds(3)), 0)
633 IF ((lbounds_local(1) <= i) .AND. (i <= ubounds_local(1)) .AND. (lbounds_local(2) <= j) &
634 .AND. (j <= ubounds_local(2)))
THEN
636 IF (any(grid%array(i, j, lbounds(3):ubounds(3)) /= buffer(lbounds(3):ubounds(3))*scaling))
THEN
637 CALL cp_abort(__location__, &
638 "Error in parallel read of input cube file.")
645 IF (my_rank == 0)
CALL close_file(unit_number=extunit_handle)
651 END SUBROUTINE cube_to_pw_parallel
667 SUBROUTINE pw_to_cube_parallel(grid, unit_nr, title, particles_r, particles_z, particles_zeff, &
668 stride, zero_tails, msglen)
672 CHARACTER(*),
INTENT(IN),
OPTIONAL :: title
673 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
674 OPTIONAL :: particles_r
675 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_z
676 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: particles_zeff
677 INTEGER,
INTENT(IN) :: stride(3)
678 LOGICAL,
INTENT(IN) :: zero_tails
679 INTEGER,
INTENT(IN) :: msglen
681 INTEGER,
PARAMETER :: entry_len = 13, header_len = 41, &
682 header_len_z = 53, num_entries_line = 6
684 CHARACTER(LEN=entry_len) :: value
685 CHARACTER(LEN=header_len) ::
header
686 CHARACTER(LEN=header_len_z) :: header_z
687 INTEGER,
DIMENSION(3) :: lbounds, lbounds_local, ubounds, &
689 INTEGER,
ALLOCATABLE,
DIMENSION(:),
TARGET :: blocklengths
690 INTEGER(kind=file_offset),
ALLOCATABLE, &
691 DIMENSION(:),
TARGET :: displacements
692 INTEGER(kind=file_offset) :: bof
693 INTEGER :: counter, i, islice, j, k, last_z, &
694 my_rank, np, nslices, size_of_z
695 CHARACTER(LEN=msglen),
ALLOCATABLE,
DIMENSION(:) ::
writebuffer
696 CHARACTER(LEN=msglen) :: tmp
697 LOGICAL :: should_write(2)
702 gid = grid%pw_grid%para%group
703 my_rank = grid%pw_grid%para%group%mepos
706 lbounds = grid%pw_grid%bounds(1, :)
707 ubounds = grid%pw_grid%bounds(2, :)
708 lbounds_local = grid%pw_grid%bounds_local(1, :)
709 ubounds_local = grid%pw_grid%bounds_local(2, :)
711 size_of_z = ceiling(real(ubounds_local(3) - lbounds_local(3) + 1,
dp)/real(stride(3),
dp))
713 DO i = lbounds(1), ubounds(1), stride(1)
714 should_write(:) = .true.
715 IF (i < lbounds_local(1))
THEN
716 should_write(1) = .false.
717 ELSE IF (i > ubounds_local(1))
THEN
720 DO j = lbounds(2), ubounds(2), stride(2)
721 should_write(2) = .true.
722 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
723 should_write(2) = .false.
725 IF (all(should_write .EQV. .true.))
THEN
731 DO k = lbounds(3), ubounds(3), stride(3)
732 IF (k + stride(3) > ubounds(3)) last_z = k
736 CALL unit_nr%get_position(bof)
738 IF (my_rank == 0)
THEN
741 CALL unit_nr%write_at(bof,
"-Quickstep-"//new_line(
"C"))
743 IF (
PRESENT(title))
THEN
744 CALL unit_nr%write_at(bof, trim(title)//new_line(
"C"))
747 CALL unit_nr%write_at(bof,
"No Title"//new_line(
"C"))
751 cpassert(
PRESENT(particles_z) .EQV.
PRESENT(particles_r))
753 IF (
PRESENT(particles_z))
THEN
754 cpassert(
SIZE(particles_z) ==
SIZE(particles_r, dim=2))
757 np = min(99999,
SIZE(particles_z))
760 WRITE (
header,
'(I5,3f12.6)') np, 0.0_dp, 0._dp, 0._dp
761 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
764 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(1) + stride(1) - 1)/stride(1), &
765 grid%pw_grid%dh(1, 1)*real(stride(1),
dp), grid%pw_grid%dh(2, 1)*real(stride(1),
dp), &
766 grid%pw_grid%dh(3, 1)*real(stride(1),
dp)
767 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
770 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(2) + stride(2) - 1)/stride(2), &
771 grid%pw_grid%dh(1, 2)*real(stride(2),
dp), grid%pw_grid%dh(2, 2)*real(stride(2),
dp), &
772 grid%pw_grid%dh(3, 2)*real(stride(2),
dp)
773 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
776 WRITE (
header,
'(I5,3f12.6)') (grid%pw_grid%npts(3) + stride(3) - 1)/stride(3), &
777 grid%pw_grid%dh(1, 3)*real(stride(3),
dp), grid%pw_grid%dh(2, 3)*real(stride(3),
dp), &
778 grid%pw_grid%dh(3, 3)*real(stride(3),
dp)
779 CALL unit_nr%write_at(bof,
header//new_line(
"C"))
782 IF (
PRESENT(particles_z))
THEN
783 IF (
PRESENT(particles_zeff))
THEN
785 WRITE (header_z,
'(I5,4f12.6)') particles_z(i), particles_zeff(i), particles_r(:, i)
786 CALL unit_nr%write_at(bof, header_z//new_line(
"C"))
791 WRITE (header_z,
'(I5,4f12.6)') particles_z(i), 0._dp, particles_r(:, i)
792 CALL unit_nr%write_at(bof, header_z//new_line(
"C"))
799 CALL gid%bcast(bof, grid%pw_grid%para%group%source)
802 ALLOCATE (displacements(nslices))
806 DO i = lbounds(1), ubounds(1), stride(1)
807 should_write(:) = .true.
808 IF (i < lbounds_local(1))
THEN
809 should_write(1) = .false.
810 ELSE IF (i > ubounds_local(1))
THEN
813 DO j = lbounds(2), ubounds(2), stride(2)
814 should_write(2) = .true.
815 IF (j < lbounds_local(2) .OR. j > ubounds_local(2))
THEN
816 should_write(2) = .false.
818 IF (all(should_write .EQV. .true.))
THEN
819 IF (islice > nslices) cpabort(
"Index out of bounds.")
820 displacements(islice) = bof
823 DO k = lbounds(3), ubounds(3), stride(3)
824 IF (zero_tails .AND. grid%array(i, j, k) < 1.e-7_dp)
THEN
829 tmp = trim(tmp)//trim(
value)
830 counter = counter + 1
831 IF (
modulo(counter, num_entries_line) == 0 .OR. k == last_z)
THEN
832 tmp = trim(tmp)//new_line(
'C')
844 ALLOCATE (blocklengths(nslices))
845 blocklengths(:) = msglen
854 CALL unit_nr%write_all(msglen, nslices,
writebuffer, mp_desc)
858 DEALLOCATE (blocklengths, displacements)
860 END SUBROUTINE pw_to_cube_parallel
874 INTEGER,
INTENT(IN) :: unit_nr
875 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: stride
878 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_to_simple_volumetric'
880 INTEGER :: checksum, dest, handle, i, i1, i2, i3, &
881 ip, l1, l2, l3, my_rank, my_stride(3), &
882 ngrids, npoints, num_pe, rank(2), &
883 source, tag, u1, u2, u3
885 REAL(kind=
dp) :: x, y, z
886 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buf, buf2
889 CALL timeset(routinen, handle)
893 IF (
PRESENT(pw2)) double = .true.
896 IF (
PRESENT(stride))
THEN
897 IF (
SIZE(stride) /= 1 .AND.
SIZE(stride) /= 3)
THEN
898 CALL cp_abort(__location__,
"STRIDE keyword can accept only 1 "// &
899 "(the same for X,Y,Z) or 3 values. Correct your input file.")
901 IF (
SIZE(stride) == 1)
THEN
903 my_stride(i) = stride(1)
906 my_stride = stride(1:3)
908 cpassert(my_stride(1) > 0)
909 cpassert(my_stride(2) > 0)
910 cpassert(my_stride(3) > 0)
914 l1 = pw%pw_grid%bounds(1, 1)
915 l2 = pw%pw_grid%bounds(1, 2)
916 l3 = pw%pw_grid%bounds(1, 3)
917 u1 = pw%pw_grid%bounds(2, 1)
918 u2 = pw%pw_grid%bounds(2, 2)
919 u3 = pw%pw_grid%bounds(2, 3)
923 IF (double) ngrids = 2
924 npoints = ((pw%pw_grid%npts(1) + my_stride(1) - 1)/my_stride(1))* &
925 ((pw%pw_grid%npts(2) + my_stride(2) - 1)/my_stride(1))* &
926 ((pw%pw_grid%npts(3) + my_stride(3) - 1)/my_stride(1))
927 IF (unit_nr > 1)
WRITE (unit_nr,
'(I7,I5)') npoints, ngrids
929 ALLOCATE (buf(l3:u3))
930 IF (double)
ALLOCATE (buf2(l3:u3))
932 my_rank = pw%pw_grid%para%group%mepos
933 gid = pw%pw_grid%para%group
934 num_pe = pw%pw_grid%para%group%num_pe
940 IF (unit_nr > 0) checksum = 1
942 CALL gid%sum(checksum)
943 cpassert(checksum == 1)
945 CALL gid%maxloc(rank)
946 cpassert(rank(1) > 0)
949 DO i1 = l1, u1, my_stride(1)
950 DO i2 = l2, u2, my_stride(2)
954 DO ip = 0, num_pe - 1
955 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. &
956 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
964 IF (source == dest)
THEN
965 IF (my_rank == source)
THEN
966 buf(:) = pw%array(i1, i2, :)
967 IF (double) buf2(:) = pw2%array(i1, i2, :)
970 IF (my_rank == source)
THEN
971 buf(:) = pw%array(i1, i2, :)
972 CALL gid%send(buf, dest, tag)
974 buf2(:) = pw2%array(i1, i2, :)
975 CALL gid%send(buf2, dest, tag)
978 IF (my_rank == dest)
THEN
979 CALL gid%recv(buf, source, tag)
980 IF (double)
CALL gid%recv(buf2, source, tag)
984 IF (.NOT. double)
THEN
985 DO i3 = l3, u3, my_stride(3)
986 x = pw%pw_grid%dh(1, 1)*i1 + &
987 pw%pw_grid%dh(2, 1)*i2 + &
988 pw%pw_grid%dh(3, 1)*i3
990 y = pw%pw_grid%dh(1, 2)*i1 + &
991 pw%pw_grid%dh(2, 2)*i2 + &
992 pw%pw_grid%dh(3, 2)*i3
994 z = pw%pw_grid%dh(1, 3)*i1 + &
995 pw%pw_grid%dh(2, 3)*i2 + &
996 pw%pw_grid%dh(3, 3)*i3
998 IF (unit_nr > 0)
THEN
999 WRITE (unit_nr,
'(6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3), 6(1X,ES12.4E3))') x, y, z, buf(i3)
1005 DO i3 = l3, u3, my_stride(3)
1006 x = pw%pw_grid%dh(1, 1)*i1 + &
1007 pw%pw_grid%dh(2, 1)*i2 + &
1008 pw%pw_grid%dh(3, 1)*i3
1010 y = pw%pw_grid%dh(1, 2)*i1 + &
1011 pw%pw_grid%dh(2, 2)*i2 + &
1012 pw%pw_grid%dh(3, 2)*i3
1014 z = pw%pw_grid%dh(1, 3)*i1 + &
1015 pw%pw_grid%dh(2, 3)*i2 + &
1016 pw%pw_grid%dh(3, 3)*i3
1018 IF (unit_nr > 0)
THEN
1019 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)
1037 IF (double)
DEALLOCATE (buf2)
1039 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.