(git:ccc2433)
cp_array_utils.F
Go to the documentation of this file.
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 ! **************************************************************************************************
10 !> \brief various utilities that regard array of different kinds:
11 !> output, allocation,...
12 !> maybe it is not a good idea mixing output and memeory utils...
13 !> \par History
14 !> 12.2001 first version [fawzi]
15 !> 3.2002 templatized [fawzi]
16 !> \author Fawzi Mohamed
17 ! **************************************************************************************************
19  USE machine, ONLY: m_flush
20  USE cp_log_handling, ONLY: cp_to_string
21 
22  USE kinds, ONLY: int_4, dp
23 
24 #include "../base/base_uses.f90"
25  IMPLICIT NONE
26  PRIVATE
27 
28  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
29  CHARACTER(len=*), PRIVATE, PARAMETER :: moduleN = 'cp_array_utils'
30 
31  PUBLIC :: cp_1d_r_p_type, &
32  cp_2d_r_p_type, &
33  cp_3d_r_p_type, &
34  cp_1d_r_cp_type, &
35  cp_2d_r_cp_type, &
36  cp_3d_r_cp_type, &
38  cp_1d_r_write, &
39  cp_2d_r_write, &
42  PUBLIC :: cp_1d_c_p_type, &
43  cp_2d_c_p_type, &
44  cp_3d_c_p_type, &
45  cp_1d_c_cp_type, &
46  cp_2d_c_cp_type, &
47  cp_3d_c_cp_type, &
49  cp_1d_c_write, &
50  cp_2d_c_write, &
53  PUBLIC :: cp_1d_i_p_type, &
54  cp_2d_i_p_type, &
55  cp_3d_i_p_type, &
56  cp_1d_i_cp_type, &
57  cp_2d_i_cp_type, &
58  cp_3d_i_cp_type, &
60  cp_1d_i_write, &
61  cp_2d_i_write, &
64  PUBLIC :: cp_1d_logical_p_type, &
65  cp_2d_logical_p_type, &
66  cp_3d_logical_p_type, &
67  cp_1d_logical_cp_type, &
68  cp_2d_logical_cp_type, &
69  cp_3d_logical_cp_type, &
75 
76  ! generic interfaces
77  PUBLIC :: cp_guarantee_size
78 
79  INTERFACE cp_guarantee_size
80  MODULE PROCEDURE cp_1d_r_guarantee_size, &
82  MODULE PROCEDURE cp_1d_c_guarantee_size, &
84  MODULE PROCEDURE cp_1d_i_guarantee_size, &
86  MODULE PROCEDURE cp_1d_logical_guarantee_size, &
88  END INTERFACE
89 
90 !***
91 
92 
93 ! **************************************************************************************************
94 !> \brief represent a pointer to a 1d array
95 !> \par History
96 !> 02.2003 created [fawzi]
97 !> \author fawzi
98 ! **************************************************************************************************
99  type cp_1d_r_p_type
100  REAL(kind=dp), dimension(:), pointer :: array => null()
101  end type cp_1d_r_p_type
102 
103 ! **************************************************************************************************
104 !> \brief represent a pointer to a 2d array
105 !> \par History
106 !> 02.2003 created [fawzi]
107 !> \author fawzi
108 ! **************************************************************************************************
109  type cp_2d_r_p_type
110  REAL(kind=dp), dimension(:, :), pointer :: array => null()
111  end type cp_2d_r_p_type
112 
113 ! **************************************************************************************************
114 !> \brief represent a pointer to a 3d array
115 !> \par History
116 !> 02.2003 created [fawzi]
117 !> \author fawzi
118 ! **************************************************************************************************
119  type cp_3d_r_p_type
120  REAL(kind=dp), dimension(:, :, :), pointer :: array => null()
121  end type cp_3d_r_p_type
122 
123 ! **************************************************************************************************
124 !> \brief represent a pointer to a contiguous 1d array
125 !> \par History
126 !> 02.2003 created [fawzi]
127 !> \author fawzi
128 ! **************************************************************************************************
129  type cp_1d_r_cp_type
130  REAL(kind=dp), dimension(:), contiguous, pointer :: array => null()
131  end type cp_1d_r_cp_type
132 
133 ! **************************************************************************************************
134 !> \brief represent a pointer to a contiguous 2d array
135 !> \par History
136 !> 02.2003 created [fawzi]
137 !> \author fawzi
138 ! **************************************************************************************************
139  type cp_2d_r_cp_type
140  REAL(kind=dp), dimension(:, :), contiguous, pointer :: array => null()
141  end type cp_2d_r_cp_type
142 
143 ! **************************************************************************************************
144 !> \brief represent a pointer to a contiguous 3d array
145 !> \par History
146 !> 02.2003 created [fawzi]
147 !> \author fawzi
148 ! **************************************************************************************************
149  type cp_3d_r_cp_type
150  REAL(kind=dp), dimension(:, :, :), contiguous, pointer :: array => null()
151  end type cp_3d_r_cp_type
152 
153 
154 ! **************************************************************************************************
155 !> \brief represent a pointer to a 1d array
156 !> \par History
157 !> 02.2003 created [fawzi]
158 !> \author fawzi
159 ! **************************************************************************************************
160  type cp_1d_c_p_type
161  COMPLEX(KIND=dp), dimension(:), pointer :: array => null()
162  end type cp_1d_c_p_type
163 
164 ! **************************************************************************************************
165 !> \brief represent a pointer to a 2d array
166 !> \par History
167 !> 02.2003 created [fawzi]
168 !> \author fawzi
169 ! **************************************************************************************************
170  type cp_2d_c_p_type
171  COMPLEX(KIND=dp), dimension(:, :), pointer :: array => null()
172  end type cp_2d_c_p_type
173 
174 ! **************************************************************************************************
175 !> \brief represent a pointer to a 3d array
176 !> \par History
177 !> 02.2003 created [fawzi]
178 !> \author fawzi
179 ! **************************************************************************************************
180  type cp_3d_c_p_type
181  COMPLEX(KIND=dp), dimension(:, :, :), pointer :: array => null()
182  end type cp_3d_c_p_type
183 
184 ! **************************************************************************************************
185 !> \brief represent a pointer to a contiguous 1d array
186 !> \par History
187 !> 02.2003 created [fawzi]
188 !> \author fawzi
189 ! **************************************************************************************************
190  type cp_1d_c_cp_type
191  COMPLEX(KIND=dp), dimension(:), contiguous, pointer :: array => null()
192  end type cp_1d_c_cp_type
193 
194 ! **************************************************************************************************
195 !> \brief represent a pointer to a contiguous 2d array
196 !> \par History
197 !> 02.2003 created [fawzi]
198 !> \author fawzi
199 ! **************************************************************************************************
200  type cp_2d_c_cp_type
201  COMPLEX(KIND=dp), dimension(:, :), contiguous, pointer :: array => null()
202  end type cp_2d_c_cp_type
203 
204 ! **************************************************************************************************
205 !> \brief represent a pointer to a contiguous 3d array
206 !> \par History
207 !> 02.2003 created [fawzi]
208 !> \author fawzi
209 ! **************************************************************************************************
210  type cp_3d_c_cp_type
211  COMPLEX(KIND=dp), dimension(:, :, :), contiguous, pointer :: array => null()
212  end type cp_3d_c_cp_type
213 
214 
215 ! **************************************************************************************************
216 !> \brief represent a pointer to a 1d array
217 !> \par History
218 !> 02.2003 created [fawzi]
219 !> \author fawzi
220 ! **************************************************************************************************
221  type cp_1d_i_p_type
222  INTEGER(kind=int_4), dimension(:), pointer :: array => null()
223  end type cp_1d_i_p_type
224 
225 ! **************************************************************************************************
226 !> \brief represent a pointer to a 2d array
227 !> \par History
228 !> 02.2003 created [fawzi]
229 !> \author fawzi
230 ! **************************************************************************************************
231  type cp_2d_i_p_type
232  INTEGER(kind=int_4), dimension(:, :), pointer :: array => null()
233  end type cp_2d_i_p_type
234 
235 ! **************************************************************************************************
236 !> \brief represent a pointer to a 3d array
237 !> \par History
238 !> 02.2003 created [fawzi]
239 !> \author fawzi
240 ! **************************************************************************************************
241  type cp_3d_i_p_type
242  INTEGER(kind=int_4), dimension(:, :, :), pointer :: array => null()
243  end type cp_3d_i_p_type
244 
245 ! **************************************************************************************************
246 !> \brief represent a pointer to a contiguous 1d array
247 !> \par History
248 !> 02.2003 created [fawzi]
249 !> \author fawzi
250 ! **************************************************************************************************
251  type cp_1d_i_cp_type
252  INTEGER(kind=int_4), dimension(:), contiguous, pointer :: array => null()
253  end type cp_1d_i_cp_type
254 
255 ! **************************************************************************************************
256 !> \brief represent a pointer to a contiguous 2d array
257 !> \par History
258 !> 02.2003 created [fawzi]
259 !> \author fawzi
260 ! **************************************************************************************************
261  type cp_2d_i_cp_type
262  INTEGER(kind=int_4), dimension(:, :), contiguous, pointer :: array => null()
263  end type cp_2d_i_cp_type
264 
265 ! **************************************************************************************************
266 !> \brief represent a pointer to a contiguous 3d array
267 !> \par History
268 !> 02.2003 created [fawzi]
269 !> \author fawzi
270 ! **************************************************************************************************
271  type cp_3d_i_cp_type
272  INTEGER(kind=int_4), dimension(:, :, :), contiguous, pointer :: array => null()
273  end type cp_3d_i_cp_type
274 
275 
276 ! **************************************************************************************************
277 !> \brief represent a pointer to a 1d array
278 !> \par History
279 !> 02.2003 created [fawzi]
280 !> \author fawzi
281 ! **************************************************************************************************
282  type cp_1d_logical_p_type
283  logical, dimension(:), pointer :: array => null()
284  end type cp_1d_logical_p_type
285 
286 ! **************************************************************************************************
287 !> \brief represent a pointer to a 2d array
288 !> \par History
289 !> 02.2003 created [fawzi]
290 !> \author fawzi
291 ! **************************************************************************************************
292  type cp_2d_logical_p_type
293  logical, dimension(:, :), pointer :: array => null()
294  end type cp_2d_logical_p_type
295 
296 ! **************************************************************************************************
297 !> \brief represent a pointer to a 3d array
298 !> \par History
299 !> 02.2003 created [fawzi]
300 !> \author fawzi
301 ! **************************************************************************************************
302  type cp_3d_logical_p_type
303  logical, dimension(:, :, :), pointer :: array => null()
304  end type cp_3d_logical_p_type
305 
306 ! **************************************************************************************************
307 !> \brief represent a pointer to a contiguous 1d array
308 !> \par History
309 !> 02.2003 created [fawzi]
310 !> \author fawzi
311 ! **************************************************************************************************
312  type cp_1d_logical_cp_type
313  logical, dimension(:), contiguous, pointer :: array => null()
314  end type cp_1d_logical_cp_type
315 
316 ! **************************************************************************************************
317 !> \brief represent a pointer to a contiguous 2d array
318 !> \par History
319 !> 02.2003 created [fawzi]
320 !> \author fawzi
321 ! **************************************************************************************************
322  type cp_2d_logical_cp_type
323  logical, dimension(:, :), contiguous, pointer :: array => null()
324  end type cp_2d_logical_cp_type
325 
326 ! **************************************************************************************************
327 !> \brief represent a pointer to a contiguous 3d array
328 !> \par History
329 !> 02.2003 created [fawzi]
330 !> \author fawzi
331 ! **************************************************************************************************
332  type cp_3d_logical_cp_type
333  logical, dimension(:, :, :), contiguous, pointer :: array => null()
334  end type cp_3d_logical_cp_type
335 
336 
337 CONTAINS
338 
339 ! **************************************************************************************************
340 !> \brief writes an array to the given unit
341 !> \param array the array to write
342 !> \param unit_nr the unit to write to (defaults to the standard out)
343 !> \param el_format the format of a single element
344 !> \par History
345 !> 4.2002 created [fawzi]
346 !> \author Fawzi Mohamed
347 !> \note
348 !> maybe I will move to a comma separated paretized list
349 ! **************************************************************************************************
350  SUBROUTINE cp_1d_r_write(array, unit_nr, el_format)
351  REAL(kind=dp), INTENT(in) :: array(:)
352  INTEGER, INTENT(in) :: unit_nr
353  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
354 
355  INTEGER :: iostat, i
356  CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
357 
358  WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
359  cpassert(iostat == 0)
360  IF (PRESENT(el_format)) THEN
361  DO i = 1, SIZE(array) - 1
362  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
363  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
364  WRITE (unit=unit_nr, fmt="(',')")
365  ELSE
366  WRITE (unit=unit_nr, fmt="(',')", advance="no")
367  END IF
368  END DO
369  IF (SIZE(array) > 0) &
370  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
371  ELSE
372  DO i = 1, SIZE(array) - 1
373  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
374  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
375  WRITE (unit=unit_nr, fmt="(',')")
376  ELSE
377  WRITE (unit=unit_nr, fmt="(',')", advance="no")
378  END IF
379  END DO
380  IF (SIZE(array) > 0) &
381  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
382  END IF
383  WRITE (unit=unit_nr, fmt="(' )')")
384  call m_flush(unit_nr)
385 
386  END SUBROUTINE cp_1d_r_write
387 
388 ! **************************************************************************************************
389 !> \brief writes an array to the given unit
390 !> \param array the array to write
391 !> \param unit_nr the unit to write to (defaults to the standard out)
392 !> \param el_format the format of a single element
393 !> \par History
394 !> 4.2002 created [fawzi]
395 !> \author Fawzi Mohamed
396 !> \note
397 !> maybe I will move to a comma separated parentized list
398 ! **************************************************************************************************
399  SUBROUTINE cp_2d_r_write(array, unit_nr, el_format)
400  REAL(kind=dp), INTENT(in) :: array(:, :)
401  INTEGER, INTENT(in) :: unit_nr
402  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
403 
404  INTEGER :: iostat, i
405  CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
406  CHARACTER(len=200) :: fmtstr
407  CHARACTER(len=10) :: nriga
408 
409  nriga = cp_to_string(SIZE(array, 2))
410  DO i = 1, SIZE(array, 1)
411  IF (PRESENT(el_format)) THEN
412  fmtstr = '(" ",'//nriga//el_format//')'
413  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
414  ELSE
415  fmtstr = '(" ",'//nriga//defaultformat//')'
416  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
417  END IF
418  cpassert(iostat == 0)
419  END DO
420  call m_flush(unit_nr)
421  END SUBROUTINE cp_2d_r_write
422 
423 ! **************************************************************************************************
424 !> \brief If the size of the array is changes reallocate it.
425 !> Issues a warning when the size changes (but not on allocation
426 !> and deallocation).
427 !>
428 !> The data is NOT preserved (if you want to preserve the data see
429 !> the realloc in the module memory_utilities)
430 !> \param array the array to reallocate if necessary
431 !> \param n the wanted size
432 !> \par History
433 !> 12.2001 first version [fawzi]
434 !> 3.2002 templatized [fawzi]
435 !> \author Fawzi Mohamed
436 !> \note
437 !> this is a different behaviour than the realloc in the module
438 !> memory_utilities. It is quite low level
439 ! **************************************************************************************************
440  SUBROUTINE cp_1d_r_guarantee_size(array, n)
441  REAL(kind=dp), POINTER :: array(:)
442  INTEGER, INTENT(in) :: n
443 
444  cpassert(n >= 0)
445  IF (ASSOCIATED(array)) THEN
446  IF (SIZE(array) /= n) THEN
447  cpwarn('size has changed')
448  DEALLOCATE (array)
449  END IF
450  END IF
451  IF (.NOT. ASSOCIATED(array)) THEN
452  ALLOCATE (array(n))
453  END IF
454  END SUBROUTINE cp_1d_r_guarantee_size
455 
456 ! **************************************************************************************************
457 !> \brief If the size of the array is changes reallocate it.
458 !> Issues a warning when the size changes (but not on allocation
459 !> and deallocation).
460 !>
461 !> The data is NOT preserved (if you want to preserve the data see
462 !> the realloc in the module memory_utilities)
463 !> \param array the array to reallocate if necessary
464 !> \param n_rows the wanted number of rows
465 !> \param n_cols the wanted number of cols
466 !> \par History
467 !> 5.2001 first version [fawzi]
468 !> \author Fawzi Mohamed
469 !> \note
470 !> this is a different behaviour than the realloc in the module
471 !> memory_utilities. It is quite low level
472 ! **************************************************************************************************
473  SUBROUTINE cp_2d_r_guarantee_size(array, n_rows, n_cols)
474  REAL(kind=dp), POINTER :: array(:, :)
475  INTEGER, INTENT(in) :: n_rows, n_cols
476 
477  cpassert(n_cols >= 0)
478  cpassert(n_rows >= 0)
479  IF (ASSOCIATED(array)) THEN
480  IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
481  cpwarn('size has changed')
482  DEALLOCATE (array)
483  END IF
484  END IF
485  IF (.NOT. ASSOCIATED(array)) THEN
486  ALLOCATE (array(n_rows, n_cols))
487  END IF
488  END SUBROUTINE cp_2d_r_guarantee_size
489 
490 ! **************************************************************************************************
491 !> \brief returns the index at which the element el should be inserted in the
492 !> array to keep it ordered (array(i)>=el).
493 !> If the element is bigger than all the elements in the array returns
494 !> the last index+1.
495 !> \param array the array to search
496 !> \param el the element to look for
497 !> \param l_index the lower index for binary search (defaults to 1)
498 !> \param u_index the upper index for binary search (defaults to size(array))
499 !> \return ...
500 !> \par History
501 !> 06.2003 created [fawzi]
502 !> \author Fawzi Mohamed
503 !> \note
504 !> the array should be ordered in growing order
505 ! **************************************************************************************************
506  FUNCTION cp_1d_r_bsearch(array, el, l_index, u_index) &
507  result(res)
508  REAL(kind=dp), intent(in) :: array(:)
509  REAL(kind=dp), intent(in) :: el
510  INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
511  integer :: res
512 
513  INTEGER :: lindex, uindex, aindex
514 
515  lindex = 1
516  uindex = size(array)
517  if (present(l_index)) lindex = l_index
518  if (present(u_index)) uindex = u_index
519  DO WHILE (lindex <= uindex)
520  aindex = (lindex + uindex)/2
521  IF ( array(aindex) < el) THEN
522  lindex = aindex + 1
523  ELSE
524  uindex = aindex - 1
525  END IF
526  END DO
527  res = lindex
528  END FUNCTION cp_1d_r_bsearch
529 ! **************************************************************************************************
530 !> \brief writes an array to the given unit
531 !> \param array the array to write
532 !> \param unit_nr the unit to write to (defaults to the standard out)
533 !> \param el_format the format of a single element
534 !> \par History
535 !> 4.2002 created [fawzi]
536 !> \author Fawzi Mohamed
537 !> \note
538 !> maybe I will move to a comma separated paretized list
539 ! **************************************************************************************************
540  SUBROUTINE cp_1d_c_write(array, unit_nr, el_format)
541  COMPLEX(KIND=dp), INTENT(in) :: array(:)
542  INTEGER, INTENT(in) :: unit_nr
543  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
544 
545  INTEGER :: iostat, i
546  CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
547 
548  WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
549  cpassert(iostat == 0)
550  IF (PRESENT(el_format)) THEN
551  DO i = 1, SIZE(array) - 1
552  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
553  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
554  WRITE (unit=unit_nr, fmt="(',')")
555  ELSE
556  WRITE (unit=unit_nr, fmt="(',')", advance="no")
557  END IF
558  END DO
559  IF (SIZE(array) > 0) &
560  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
561  ELSE
562  DO i = 1, SIZE(array) - 1
563  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
564  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
565  WRITE (unit=unit_nr, fmt="(',')")
566  ELSE
567  WRITE (unit=unit_nr, fmt="(',')", advance="no")
568  END IF
569  END DO
570  IF (SIZE(array) > 0) &
571  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
572  END IF
573  WRITE (unit=unit_nr, fmt="(' )')")
574  call m_flush(unit_nr)
575 
576  END SUBROUTINE cp_1d_c_write
577 
578 ! **************************************************************************************************
579 !> \brief writes an array to the given unit
580 !> \param array the array to write
581 !> \param unit_nr the unit to write to (defaults to the standard out)
582 !> \param el_format the format of a single element
583 !> \par History
584 !> 4.2002 created [fawzi]
585 !> \author Fawzi Mohamed
586 !> \note
587 !> maybe I will move to a comma separated parentized list
588 ! **************************************************************************************************
589  SUBROUTINE cp_2d_c_write(array, unit_nr, el_format)
590  COMPLEX(KIND=dp), INTENT(in) :: array(:, :)
591  INTEGER, INTENT(in) :: unit_nr
592  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
593 
594  INTEGER :: iostat, i
595  CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
596  CHARACTER(len=200) :: fmtstr
597  CHARACTER(len=10) :: nriga
598 
599  nriga = cp_to_string(SIZE(array, 2))
600  DO i = 1, SIZE(array, 1)
601  IF (PRESENT(el_format)) THEN
602  fmtstr = '(" ",'//nriga//el_format//')'
603  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
604  ELSE
605  fmtstr = '(" ",'//nriga//defaultformat//')'
606  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
607  END IF
608  cpassert(iostat == 0)
609  END DO
610  call m_flush(unit_nr)
611  END SUBROUTINE cp_2d_c_write
612 
613 ! **************************************************************************************************
614 !> \brief If the size of the array is changes reallocate it.
615 !> Issues a warning when the size changes (but not on allocation
616 !> and deallocation).
617 !>
618 !> The data is NOT preserved (if you want to preserve the data see
619 !> the realloc in the module memory_utilities)
620 !> \param array the array to reallocate if necessary
621 !> \param n the wanted size
622 !> \par History
623 !> 12.2001 first version [fawzi]
624 !> 3.2002 templatized [fawzi]
625 !> \author Fawzi Mohamed
626 !> \note
627 !> this is a different behaviour than the realloc in the module
628 !> memory_utilities. It is quite low level
629 ! **************************************************************************************************
630  SUBROUTINE cp_1d_c_guarantee_size(array, n)
631  COMPLEX(KIND=dp), POINTER :: array(:)
632  INTEGER, INTENT(in) :: n
633 
634  cpassert(n >= 0)
635  IF (ASSOCIATED(array)) THEN
636  IF (SIZE(array) /= n) THEN
637  cpwarn('size has changed')
638  DEALLOCATE (array)
639  END IF
640  END IF
641  IF (.NOT. ASSOCIATED(array)) THEN
642  ALLOCATE (array(n))
643  END IF
644  END SUBROUTINE cp_1d_c_guarantee_size
645 
646 ! **************************************************************************************************
647 !> \brief If the size of the array is changes reallocate it.
648 !> Issues a warning when the size changes (but not on allocation
649 !> and deallocation).
650 !>
651 !> The data is NOT preserved (if you want to preserve the data see
652 !> the realloc in the module memory_utilities)
653 !> \param array the array to reallocate if necessary
654 !> \param n_rows the wanted number of rows
655 !> \param n_cols the wanted number of cols
656 !> \par History
657 !> 5.2001 first version [fawzi]
658 !> \author Fawzi Mohamed
659 !> \note
660 !> this is a different behaviour than the realloc in the module
661 !> memory_utilities. It is quite low level
662 ! **************************************************************************************************
663  SUBROUTINE cp_2d_c_guarantee_size(array, n_rows, n_cols)
664  COMPLEX(KIND=dp), POINTER :: array(:, :)
665  INTEGER, INTENT(in) :: n_rows, n_cols
666 
667  cpassert(n_cols >= 0)
668  cpassert(n_rows >= 0)
669  IF (ASSOCIATED(array)) THEN
670  IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
671  cpwarn('size has changed')
672  DEALLOCATE (array)
673  END IF
674  END IF
675  IF (.NOT. ASSOCIATED(array)) THEN
676  ALLOCATE (array(n_rows, n_cols))
677  END IF
678  END SUBROUTINE cp_2d_c_guarantee_size
679 
680 ! **************************************************************************************************
681 !> \brief returns the index at which the element el should be inserted in the
682 !> array to keep it ordered (array(i)>=el).
683 !> If the element is bigger than all the elements in the array returns
684 !> the last index+1.
685 !> \param array the array to search
686 !> \param el the element to look for
687 !> \param l_index the lower index for binary search (defaults to 1)
688 !> \param u_index the upper index for binary search (defaults to size(array))
689 !> \return ...
690 !> \par History
691 !> 06.2003 created [fawzi]
692 !> \author Fawzi Mohamed
693 !> \note
694 !> the array should be ordered in growing order
695 ! **************************************************************************************************
696  FUNCTION cp_1d_c_bsearch(array, el, l_index, u_index) &
697  result(res)
698  COMPLEX(KIND=dp), intent(in) :: array(:)
699  COMPLEX(KIND=dp), intent(in) :: el
700  INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
701  integer :: res
702 
703  INTEGER :: lindex, uindex, aindex
704 
705  lindex = 1
706  uindex = size(array)
707  if (present(l_index)) lindex = l_index
708  if (present(u_index)) uindex = u_index
709  DO WHILE (lindex <= uindex)
710  aindex = (lindex + uindex)/2
711  IF (real(array(aindex)) < real(el) .OR. (abs(real(array(aindex))-real(el)) < epsilon(max(abs(real(array(aindex))),&
712  & abs(real(el)))) .and. aimag(array(aindex)) < aimag(el))) THEN
713  lindex = aindex + 1
714  ELSE
715  uindex = aindex - 1
716  END IF
717  END DO
718  res = lindex
719  END FUNCTION cp_1d_c_bsearch
720 ! **************************************************************************************************
721 !> \brief writes an array to the given unit
722 !> \param array the array to write
723 !> \param unit_nr the unit to write to (defaults to the standard out)
724 !> \param el_format the format of a single element
725 !> \par History
726 !> 4.2002 created [fawzi]
727 !> \author Fawzi Mohamed
728 !> \note
729 !> maybe I will move to a comma separated paretized list
730 ! **************************************************************************************************
731  SUBROUTINE cp_1d_i_write(array, unit_nr, el_format)
732  INTEGER(kind=int_4), INTENT(in) :: array(:)
733  INTEGER, INTENT(in) :: unit_nr
734  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
735 
736  INTEGER :: iostat, i
737  CHARACTER(len=*), PARAMETER :: defaultformat = "(i6)"
738 
739  WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
740  cpassert(iostat == 0)
741  IF (PRESENT(el_format)) THEN
742  DO i = 1, SIZE(array) - 1
743  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
744  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
745  WRITE (unit=unit_nr, fmt="(',')")
746  ELSE
747  WRITE (unit=unit_nr, fmt="(',')", advance="no")
748  END IF
749  END DO
750  IF (SIZE(array) > 0) &
751  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
752  ELSE
753  DO i = 1, SIZE(array) - 1
754  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
755  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
756  WRITE (unit=unit_nr, fmt="(',')")
757  ELSE
758  WRITE (unit=unit_nr, fmt="(',')", advance="no")
759  END IF
760  END DO
761  IF (SIZE(array) > 0) &
762  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
763  END IF
764  WRITE (unit=unit_nr, fmt="(' )')")
765  call m_flush(unit_nr)
766 
767  END SUBROUTINE cp_1d_i_write
768 
769 ! **************************************************************************************************
770 !> \brief writes an array to the given unit
771 !> \param array the array to write
772 !> \param unit_nr the unit to write to (defaults to the standard out)
773 !> \param el_format the format of a single element
774 !> \par History
775 !> 4.2002 created [fawzi]
776 !> \author Fawzi Mohamed
777 !> \note
778 !> maybe I will move to a comma separated parentized list
779 ! **************************************************************************************************
780  SUBROUTINE cp_2d_i_write(array, unit_nr, el_format)
781  INTEGER(kind=int_4), INTENT(in) :: array(:, :)
782  INTEGER, INTENT(in) :: unit_nr
783  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
784 
785  INTEGER :: iostat, i
786  CHARACTER(len=*), PARAMETER :: defaultformat = "(i6)"
787  CHARACTER(len=200) :: fmtstr
788  CHARACTER(len=10) :: nriga
789 
790  nriga = cp_to_string(SIZE(array, 2))
791  DO i = 1, SIZE(array, 1)
792  IF (PRESENT(el_format)) THEN
793  fmtstr = '(" ",'//nriga//el_format//')'
794  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
795  ELSE
796  fmtstr = '(" ",'//nriga//defaultformat//')'
797  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
798  END IF
799  cpassert(iostat == 0)
800  END DO
801  call m_flush(unit_nr)
802  END SUBROUTINE cp_2d_i_write
803 
804 ! **************************************************************************************************
805 !> \brief If the size of the array is changes reallocate it.
806 !> Issues a warning when the size changes (but not on allocation
807 !> and deallocation).
808 !>
809 !> The data is NOT preserved (if you want to preserve the data see
810 !> the realloc in the module memory_utilities)
811 !> \param array the array to reallocate if necessary
812 !> \param n the wanted size
813 !> \par History
814 !> 12.2001 first version [fawzi]
815 !> 3.2002 templatized [fawzi]
816 !> \author Fawzi Mohamed
817 !> \note
818 !> this is a different behaviour than the realloc in the module
819 !> memory_utilities. It is quite low level
820 ! **************************************************************************************************
821  SUBROUTINE cp_1d_i_guarantee_size(array, n)
822  INTEGER(kind=int_4), POINTER :: array(:)
823  INTEGER, INTENT(in) :: n
824 
825  cpassert(n >= 0)
826  IF (ASSOCIATED(array)) THEN
827  IF (SIZE(array) /= n) THEN
828  cpwarn('size has changed')
829  DEALLOCATE (array)
830  END IF
831  END IF
832  IF (.NOT. ASSOCIATED(array)) THEN
833  ALLOCATE (array(n))
834  END IF
835  END SUBROUTINE cp_1d_i_guarantee_size
836 
837 ! **************************************************************************************************
838 !> \brief If the size of the array is changes reallocate it.
839 !> Issues a warning when the size changes (but not on allocation
840 !> and deallocation).
841 !>
842 !> The data is NOT preserved (if you want to preserve the data see
843 !> the realloc in the module memory_utilities)
844 !> \param array the array to reallocate if necessary
845 !> \param n_rows the wanted number of rows
846 !> \param n_cols the wanted number of cols
847 !> \par History
848 !> 5.2001 first version [fawzi]
849 !> \author Fawzi Mohamed
850 !> \note
851 !> this is a different behaviour than the realloc in the module
852 !> memory_utilities. It is quite low level
853 ! **************************************************************************************************
854  SUBROUTINE cp_2d_i_guarantee_size(array, n_rows, n_cols)
855  INTEGER(kind=int_4), POINTER :: array(:, :)
856  INTEGER, INTENT(in) :: n_rows, n_cols
857 
858  cpassert(n_cols >= 0)
859  cpassert(n_rows >= 0)
860  IF (ASSOCIATED(array)) THEN
861  IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
862  cpwarn('size has changed')
863  DEALLOCATE (array)
864  END IF
865  END IF
866  IF (.NOT. ASSOCIATED(array)) THEN
867  ALLOCATE (array(n_rows, n_cols))
868  END IF
869  END SUBROUTINE cp_2d_i_guarantee_size
870 
871 ! **************************************************************************************************
872 !> \brief returns the index at which the element el should be inserted in the
873 !> array to keep it ordered (array(i)>=el).
874 !> If the element is bigger than all the elements in the array returns
875 !> the last index+1.
876 !> \param array the array to search
877 !> \param el the element to look for
878 !> \param l_index the lower index for binary search (defaults to 1)
879 !> \param u_index the upper index for binary search (defaults to size(array))
880 !> \return ...
881 !> \par History
882 !> 06.2003 created [fawzi]
883 !> \author Fawzi Mohamed
884 !> \note
885 !> the array should be ordered in growing order
886 ! **************************************************************************************************
887  FUNCTION cp_1d_i_bsearch(array, el, l_index, u_index) &
888  result(res)
889  INTEGER(kind=int_4), intent(in) :: array(:)
890  INTEGER(kind=int_4), intent(in) :: el
891  INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
892  integer :: res
893 
894  INTEGER :: lindex, uindex, aindex
895 
896  lindex = 1
897  uindex = size(array)
898  if (present(l_index)) lindex = l_index
899  if (present(u_index)) uindex = u_index
900  DO WHILE (lindex <= uindex)
901  aindex = (lindex + uindex)/2
902  IF ( array(aindex) < el) THEN
903  lindex = aindex + 1
904  ELSE
905  uindex = aindex - 1
906  END IF
907  END DO
908  res = lindex
909  END FUNCTION cp_1d_i_bsearch
910 ! **************************************************************************************************
911 !> \brief writes an array to the given unit
912 !> \param array the array to write
913 !> \param unit_nr the unit to write to (defaults to the standard out)
914 !> \param el_format the format of a single element
915 !> \par History
916 !> 4.2002 created [fawzi]
917 !> \author Fawzi Mohamed
918 !> \note
919 !> maybe I will move to a comma separated paretized list
920 ! **************************************************************************************************
921  SUBROUTINE cp_1d_logical_write(array, unit_nr, el_format)
922  logical, INTENT(in) :: array(:)
923  INTEGER, INTENT(in) :: unit_nr
924  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
925 
926  INTEGER :: iostat, i
927  CHARACTER(len=*), PARAMETER :: defaultformat = "(l1)"
928 
929  WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
930  cpassert(iostat == 0)
931  IF (PRESENT(el_format)) THEN
932  DO i = 1, SIZE(array) - 1
933  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
934  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
935  WRITE (unit=unit_nr, fmt="(',')")
936  ELSE
937  WRITE (unit=unit_nr, fmt="(',')", advance="no")
938  END IF
939  END DO
940  IF (SIZE(array) > 0) &
941  WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
942  ELSE
943  DO i = 1, SIZE(array) - 1
944  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
945  IF (mod(i, 5) .EQ. 0) THEN ! only a few elements per line
946  WRITE (unit=unit_nr, fmt="(',')")
947  ELSE
948  WRITE (unit=unit_nr, fmt="(',')", advance="no")
949  END IF
950  END DO
951  IF (SIZE(array) > 0) &
952  WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
953  END IF
954  WRITE (unit=unit_nr, fmt="(' )')")
955  call m_flush(unit_nr)
956 
957  END SUBROUTINE cp_1d_logical_write
958 
959 ! **************************************************************************************************
960 !> \brief writes an array to the given unit
961 !> \param array the array to write
962 !> \param unit_nr the unit to write to (defaults to the standard out)
963 !> \param el_format the format of a single element
964 !> \par History
965 !> 4.2002 created [fawzi]
966 !> \author Fawzi Mohamed
967 !> \note
968 !> maybe I will move to a comma separated parentized list
969 ! **************************************************************************************************
970  SUBROUTINE cp_2d_logical_write(array, unit_nr, el_format)
971  logical, INTENT(in) :: array(:, :)
972  INTEGER, INTENT(in) :: unit_nr
973  CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
974 
975  INTEGER :: iostat, i
976  CHARACTER(len=*), PARAMETER :: defaultformat = "(l1)"
977  CHARACTER(len=200) :: fmtstr
978  CHARACTER(len=10) :: nriga
979 
980  nriga = cp_to_string(SIZE(array, 2))
981  DO i = 1, SIZE(array, 1)
982  IF (PRESENT(el_format)) THEN
983  fmtstr = '(" ",'//nriga//el_format//')'
984  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
985  ELSE
986  fmtstr = '(" ",'//nriga//defaultformat//')'
987  WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
988  END IF
989  cpassert(iostat == 0)
990  END DO
991  call m_flush(unit_nr)
992  END SUBROUTINE cp_2d_logical_write
993 
994 ! **************************************************************************************************
995 !> \brief If the size of the array is changes reallocate it.
996 !> Issues a warning when the size changes (but not on allocation
997 !> and deallocation).
998 !>
999 !> The data is NOT preserved (if you want to preserve the data see
1000 !> the realloc in the module memory_utilities)
1001 !> \param array the array to reallocate if necessary
1002 !> \param n the wanted size
1003 !> \par History
1004 !> 12.2001 first version [fawzi]
1005 !> 3.2002 templatized [fawzi]
1006 !> \author Fawzi Mohamed
1007 !> \note
1008 !> this is a different behaviour than the realloc in the module
1009 !> memory_utilities. It is quite low level
1010 ! **************************************************************************************************
1011  SUBROUTINE cp_1d_logical_guarantee_size(array, n)
1012  logical, POINTER :: array(:)
1013  INTEGER, INTENT(in) :: n
1014 
1015  cpassert(n >= 0)
1016  IF (ASSOCIATED(array)) THEN
1017  IF (SIZE(array) /= n) THEN
1018  cpwarn('size has changed')
1019  DEALLOCATE (array)
1020  END IF
1021  END IF
1022  IF (.NOT. ASSOCIATED(array)) THEN
1023  ALLOCATE (array(n))
1024  END IF
1025  END SUBROUTINE cp_1d_logical_guarantee_size
1026 
1027 ! **************************************************************************************************
1028 !> \brief If the size of the array is changes reallocate it.
1029 !> Issues a warning when the size changes (but not on allocation
1030 !> and deallocation).
1031 !>
1032 !> The data is NOT preserved (if you want to preserve the data see
1033 !> the realloc in the module memory_utilities)
1034 !> \param array the array to reallocate if necessary
1035 !> \param n_rows the wanted number of rows
1036 !> \param n_cols the wanted number of cols
1037 !> \par History
1038 !> 5.2001 first version [fawzi]
1039 !> \author Fawzi Mohamed
1040 !> \note
1041 !> this is a different behaviour than the realloc in the module
1042 !> memory_utilities. It is quite low level
1043 ! **************************************************************************************************
1044  SUBROUTINE cp_2d_logical_guarantee_size(array, n_rows, n_cols)
1045  logical, POINTER :: array(:, :)
1046  INTEGER, INTENT(in) :: n_rows, n_cols
1047 
1048  cpassert(n_cols >= 0)
1049  cpassert(n_rows >= 0)
1050  IF (ASSOCIATED(array)) THEN
1051  IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
1052  cpwarn('size has changed')
1053  DEALLOCATE (array)
1054  END IF
1055  END IF
1056  IF (.NOT. ASSOCIATED(array)) THEN
1057  ALLOCATE (array(n_rows, n_cols))
1058  END IF
1059  END SUBROUTINE cp_2d_logical_guarantee_size
1060 
1061 ! **************************************************************************************************
1062 !> \brief returns the index at which the element el should be inserted in the
1063 !> array to keep it ordered (array(i)>=el).
1064 !> If the element is bigger than all the elements in the array returns
1065 !> the last index+1.
1066 !> \param array the array to search
1067 !> \param el the element to look for
1068 !> \param l_index the lower index for binary search (defaults to 1)
1069 !> \param u_index the upper index for binary search (defaults to size(array))
1070 !> \return ...
1071 !> \par History
1072 !> 06.2003 created [fawzi]
1073 !> \author Fawzi Mohamed
1074 !> \note
1075 !> the array should be ordered in growing order
1076 ! **************************************************************************************************
1077  FUNCTION cp_1d_logical_bsearch(array, el, l_index, u_index) &
1078  result(res)
1079  logical, intent(in) :: array(:)
1080  logical, intent(in) :: el
1081  INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
1082  integer :: res
1083 
1084  INTEGER :: lindex, uindex, aindex
1085 
1086  lindex = 1
1087  uindex = size(array)
1088  if (present(l_index)) lindex = l_index
1089  if (present(u_index)) uindex = u_index
1090  DO WHILE (lindex <= uindex)
1091  aindex = (lindex + uindex)/2
1092  IF ( (.not. array(aindex)) .and. el) THEN
1093  lindex = aindex + 1
1094  ELSE
1095  uindex = aindex - 1
1096  END IF
1097  END DO
1098  res = lindex
1099  END FUNCTION cp_1d_logical_bsearch
1100 
1101 END MODULE cp_array_utils
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
subroutine, public cp_2d_c_guarantee_size(array, n_rows, n_cols)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_1d_i_guarantee_size(array, n)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_2d_r_guarantee_size(array, n_rows, n_cols)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
integer function, public cp_1d_logical_bsearch(array, el, l_index, u_index)
returns the index at which the element el should be inserted in the array to keep it ordered (array(i...
integer function, public cp_1d_c_bsearch(array, el, l_index, u_index)
returns the index at which the element el should be inserted in the array to keep it ordered (array(i...
subroutine, public cp_1d_i_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_1d_logical_write(array, unit_nr, el_format)
writes an array to the given unit
integer function, public cp_1d_i_bsearch(array, el, l_index, u_index)
returns the index at which the element el should be inserted in the array to keep it ordered (array(i...
subroutine, public cp_2d_i_guarantee_size(array, n_rows, n_cols)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_2d_c_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_1d_r_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_1d_logical_guarantee_size(array, n)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
integer function, public cp_1d_r_bsearch(array, el, l_index, u_index)
returns the index at which the element el should be inserted in the array to keep it ordered (array(i...
subroutine, public cp_1d_c_guarantee_size(array, n)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_2d_logical_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_2d_logical_guarantee_size(array, n_rows, n_cols)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_1d_c_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_2d_r_write(array, unit_nr, el_format)
writes an array to the given unit
subroutine, public cp_1d_r_guarantee_size(array, n)
If the size of the array is changes reallocate it. Issues a warning when the size changes (but not on...
subroutine, public cp_2d_i_write(array, unit_nr, el_format)
writes an array to the given unit
various routines to log and control the output. The idea is that decisions about where to log should ...
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public int_4
Definition: kinds.F:51
Machine interface based on Fortran 2003 and POSIX.
Definition: machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition: machine.F:106