(git:8917686)
Loading...
Searching...
No Matches
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-2026 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
21
22 USE kinds, ONLY: dp, int_4
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, &
42 PUBLIC :: cp_1d_c_p_type, &
53 PUBLIC :: cp_1d_i_p_type, &
64 PUBLIC :: cp_1d_logical_p_type, &
75
76 ! generic interfaces
77 PUBLIC :: cp_guarantee_size
78
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
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! **************************************************************************************************
333 logical, dimension(:, :, :), contiguous, pointer :: array => null()
334 end type cp_3d_logical_cp_type
335
336
337CONTAINS
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) == 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) THEN
370 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
371 END IF
372 ELSE
373 DO i = 1, SIZE(array) - 1
374 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
375 IF (mod(i, 5) == 0) THEN ! only a few elements per line
376 WRITE (unit=unit_nr, fmt="(',')")
377 ELSE
378 WRITE (unit=unit_nr, fmt="(',')", advance="no")
379 END IF
380 END DO
381 IF (SIZE(array) > 0) THEN
382 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
383 END IF
384 END IF
385 WRITE (unit=unit_nr, fmt="(' )')")
386 call m_flush(unit_nr)
387
388 END SUBROUTINE cp_1d_r_write
389
390! **************************************************************************************************
391!> \brief writes an array to the given unit
392!> \param array the array to write
393!> \param unit_nr the unit to write to (defaults to the standard out)
394!> \param el_format the format of a single element
395!> \par History
396!> 4.2002 created [fawzi]
397!> \author Fawzi Mohamed
398!> \note
399!> maybe I will move to a comma separated parentized list
400! **************************************************************************************************
401 SUBROUTINE cp_2d_r_write(array, unit_nr, el_format)
402 REAL(kind=dp), INTENT(in) :: array(:, :)
403 INTEGER, INTENT(in) :: unit_nr
404 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
405
406 INTEGER :: iostat, i
407 CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
408 CHARACTER(len=200) :: fmtstr
409 CHARACTER(len=25) :: nriga
410
411 nriga = cp_to_string(SIZE(array, 2))
412 DO i = 1, SIZE(array, 1)
413 IF (PRESENT(el_format)) THEN
414 fmtstr = '(" ",'//nriga//el_format//')'
415 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
416 ELSE
417 fmtstr = '(" ",'//nriga//defaultformat//')'
418 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
419 END IF
420 cpassert(iostat == 0)
421 END DO
422 call m_flush(unit_nr)
423 END SUBROUTINE cp_2d_r_write
424
425! **************************************************************************************************
426!> \brief If the size of the array is changes reallocate it.
427!> Issues a warning when the size changes (but not on allocation
428!> and deallocation).
429!>
430!> The data is NOT preserved (if you want to preserve the data see
431!> the realloc in the module memory_utilities)
432!> \param array the array to reallocate if necessary
433!> \param n the wanted size
434!> \par History
435!> 12.2001 first version [fawzi]
436!> 3.2002 templatized [fawzi]
437!> \author Fawzi Mohamed
438!> \note
439!> this is a different behaviour than the realloc in the module
440!> memory_utilities. It is quite low level
441! **************************************************************************************************
442 SUBROUTINE cp_1d_r_guarantee_size(array, n)
443 REAL(kind=dp), POINTER :: array(:)
444 INTEGER, INTENT(in) :: n
445
446 cpassert(n >= 0)
447 IF (ASSOCIATED(array)) THEN
448 IF (SIZE(array) /= n) THEN
449 cpwarn('size has changed')
450 DEALLOCATE (array)
451 END IF
452 END IF
453 IF (.NOT. ASSOCIATED(array)) THEN
454 ALLOCATE (array(n))
455 END IF
456 END SUBROUTINE cp_1d_r_guarantee_size
457
458! **************************************************************************************************
459!> \brief If the size of the array is changes reallocate it.
460!> Issues a warning when the size changes (but not on allocation
461!> and deallocation).
462!>
463!> The data is NOT preserved (if you want to preserve the data see
464!> the realloc in the module memory_utilities)
465!> \param array the array to reallocate if necessary
466!> \param n_rows the wanted number of rows
467!> \param n_cols the wanted number of cols
468!> \par History
469!> 5.2001 first version [fawzi]
470!> \author Fawzi Mohamed
471!> \note
472!> this is a different behaviour than the realloc in the module
473!> memory_utilities. It is quite low level
474! **************************************************************************************************
475 SUBROUTINE cp_2d_r_guarantee_size(array, n_rows, n_cols)
476 REAL(kind=dp), POINTER :: array(:, :)
477 INTEGER, INTENT(in) :: n_rows, n_cols
478
479 cpassert(n_cols >= 0)
480 cpassert(n_rows >= 0)
481 IF (ASSOCIATED(array)) THEN
482 IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
483 cpwarn('size has changed')
484 DEALLOCATE (array)
485 END IF
486 END IF
487 IF (.NOT. ASSOCIATED(array)) THEN
488 ALLOCATE (array(n_rows, n_cols))
489 END IF
490 END SUBROUTINE cp_2d_r_guarantee_size
491
492! **************************************************************************************************
493!> \brief returns the index at which the element el should be inserted in the
494!> array to keep it ordered (array(i)>=el).
495!> If the element is bigger than all the elements in the array returns
496!> the last index+1.
497!> \param array the array to search
498!> \param el the element to look for
499!> \param l_index the lower index for binary search (defaults to 1)
500!> \param u_index the upper index for binary search (defaults to size(array))
501!> \return ...
502!> \par History
503!> 06.2003 created [fawzi]
504!> \author Fawzi Mohamed
505!> \note
506!> the array should be ordered in growing order
507! **************************************************************************************************
508 FUNCTION cp_1d_r_bsearch(array, el, l_index, u_index) result(res)
509 REAL(kind=dp), intent(in) :: array(:)
510 REAL(kind=dp), intent(in) :: el
511 INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
512 integer :: res
513
514 INTEGER :: lindex, uindex, aindex
515
516 lindex = 1
517 uindex = size(array)
518 if (present(l_index)) lindex = l_index
519 if (present(u_index)) uindex = u_index
520 DO WHILE (lindex <= uindex)
521 aindex = (lindex + uindex)/2
522 IF ( array(aindex) < el) THEN
523 lindex = aindex + 1
524 ELSE
525 uindex = aindex - 1
526 END IF
527 END DO
528 res = lindex
529 END FUNCTION cp_1d_r_bsearch
530! **************************************************************************************************
531!> \brief writes an array to the given unit
532!> \param array the array to write
533!> \param unit_nr the unit to write to (defaults to the standard out)
534!> \param el_format the format of a single element
535!> \par History
536!> 4.2002 created [fawzi]
537!> \author Fawzi Mohamed
538!> \note
539!> maybe I will move to a comma separated paretized list
540! **************************************************************************************************
541 SUBROUTINE cp_1d_c_write(array, unit_nr, el_format)
542 COMPLEX(KIND=dp), INTENT(in) :: array(:)
543 INTEGER, INTENT(in) :: unit_nr
544 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
545
546 INTEGER :: iostat, i
547 CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
548
549 WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
550 cpassert(iostat == 0)
551 IF (PRESENT(el_format)) THEN
552 DO i = 1, SIZE(array) - 1
553 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
554 IF (mod(i, 5) == 0) THEN ! only a few elements per line
555 WRITE (unit=unit_nr, fmt="(',')")
556 ELSE
557 WRITE (unit=unit_nr, fmt="(',')", advance="no")
558 END IF
559 END DO
560 IF (SIZE(array) > 0) THEN
561 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
562 END IF
563 ELSE
564 DO i = 1, SIZE(array) - 1
565 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
566 IF (mod(i, 5) == 0) THEN ! only a few elements per line
567 WRITE (unit=unit_nr, fmt="(',')")
568 ELSE
569 WRITE (unit=unit_nr, fmt="(',')", advance="no")
570 END IF
571 END DO
572 IF (SIZE(array) > 0) THEN
573 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
574 END IF
575 END IF
576 WRITE (unit=unit_nr, fmt="(' )')")
577 call m_flush(unit_nr)
578
579 END SUBROUTINE cp_1d_c_write
580
581! **************************************************************************************************
582!> \brief writes an array to the given unit
583!> \param array the array to write
584!> \param unit_nr the unit to write to (defaults to the standard out)
585!> \param el_format the format of a single element
586!> \par History
587!> 4.2002 created [fawzi]
588!> \author Fawzi Mohamed
589!> \note
590!> maybe I will move to a comma separated parentized list
591! **************************************************************************************************
592 SUBROUTINE cp_2d_c_write(array, unit_nr, el_format)
593 COMPLEX(KIND=dp), INTENT(in) :: array(:, :)
594 INTEGER, INTENT(in) :: unit_nr
595 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
596
597 INTEGER :: iostat, i
598 CHARACTER(len=*), PARAMETER :: defaultformat = "(es14.6)"
599 CHARACTER(len=200) :: fmtstr
600 CHARACTER(len=25) :: nriga
601
602 nriga = cp_to_string(SIZE(array, 2))
603 DO i = 1, SIZE(array, 1)
604 IF (PRESENT(el_format)) THEN
605 fmtstr = '(" ",'//nriga//el_format//')'
606 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
607 ELSE
608 fmtstr = '(" ",'//nriga//defaultformat//')'
609 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
610 END IF
611 cpassert(iostat == 0)
612 END DO
613 call m_flush(unit_nr)
614 END SUBROUTINE cp_2d_c_write
615
616! **************************************************************************************************
617!> \brief If the size of the array is changes reallocate it.
618!> Issues a warning when the size changes (but not on allocation
619!> and deallocation).
620!>
621!> The data is NOT preserved (if you want to preserve the data see
622!> the realloc in the module memory_utilities)
623!> \param array the array to reallocate if necessary
624!> \param n the wanted size
625!> \par History
626!> 12.2001 first version [fawzi]
627!> 3.2002 templatized [fawzi]
628!> \author Fawzi Mohamed
629!> \note
630!> this is a different behaviour than the realloc in the module
631!> memory_utilities. It is quite low level
632! **************************************************************************************************
633 SUBROUTINE cp_1d_c_guarantee_size(array, n)
634 COMPLEX(KIND=dp), POINTER :: array(:)
635 INTEGER, INTENT(in) :: n
636
637 cpassert(n >= 0)
638 IF (ASSOCIATED(array)) THEN
639 IF (SIZE(array) /= n) THEN
640 cpwarn('size has changed')
641 DEALLOCATE (array)
642 END IF
643 END IF
644 IF (.NOT. ASSOCIATED(array)) THEN
645 ALLOCATE (array(n))
646 END IF
647 END SUBROUTINE cp_1d_c_guarantee_size
648
649! **************************************************************************************************
650!> \brief If the size of the array is changes reallocate it.
651!> Issues a warning when the size changes (but not on allocation
652!> and deallocation).
653!>
654!> The data is NOT preserved (if you want to preserve the data see
655!> the realloc in the module memory_utilities)
656!> \param array the array to reallocate if necessary
657!> \param n_rows the wanted number of rows
658!> \param n_cols the wanted number of cols
659!> \par History
660!> 5.2001 first version [fawzi]
661!> \author Fawzi Mohamed
662!> \note
663!> this is a different behaviour than the realloc in the module
664!> memory_utilities. It is quite low level
665! **************************************************************************************************
666 SUBROUTINE cp_2d_c_guarantee_size(array, n_rows, n_cols)
667 COMPLEX(KIND=dp), POINTER :: array(:, :)
668 INTEGER, INTENT(in) :: n_rows, n_cols
669
670 cpassert(n_cols >= 0)
671 cpassert(n_rows >= 0)
672 IF (ASSOCIATED(array)) THEN
673 IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
674 cpwarn('size has changed')
675 DEALLOCATE (array)
676 END IF
677 END IF
678 IF (.NOT. ASSOCIATED(array)) THEN
679 ALLOCATE (array(n_rows, n_cols))
680 END IF
681 END SUBROUTINE cp_2d_c_guarantee_size
682
683! **************************************************************************************************
684!> \brief returns the index at which the element el should be inserted in the
685!> array to keep it ordered (array(i)>=el).
686!> If the element is bigger than all the elements in the array returns
687!> the last index+1.
688!> \param array the array to search
689!> \param el the element to look for
690!> \param l_index the lower index for binary search (defaults to 1)
691!> \param u_index the upper index for binary search (defaults to size(array))
692!> \return ...
693!> \par History
694!> 06.2003 created [fawzi]
695!> \author Fawzi Mohamed
696!> \note
697!> the array should be ordered in growing order
698! **************************************************************************************************
699 FUNCTION cp_1d_c_bsearch(array, el, l_index, u_index) result(res)
700 COMPLEX(KIND=dp), intent(in) :: array(:)
701 COMPLEX(KIND=dp), intent(in) :: el
702 INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
703 integer :: res
704
705 INTEGER :: lindex, uindex, aindex
706
707 lindex = 1
708 uindex = size(array)
709 if (present(l_index)) lindex = l_index
710 if (present(u_index)) uindex = u_index
711 DO WHILE (lindex <= uindex)
712 aindex = (lindex + uindex)/2
713 IF (real(array(aindex)) < real(el) .OR. (abs(real(array(aindex))-real(el)) < epsilon(max(abs(real(array(aindex))),&
714 & abs(real(el)))) .and. aimag(array(aindex)) < aimag(el))) THEN
715 lindex = aindex + 1
716 ELSE
717 uindex = aindex - 1
718 END IF
719 END DO
720 res = lindex
721 END FUNCTION cp_1d_c_bsearch
722! **************************************************************************************************
723!> \brief writes an array to the given unit
724!> \param array the array to write
725!> \param unit_nr the unit to write to (defaults to the standard out)
726!> \param el_format the format of a single element
727!> \par History
728!> 4.2002 created [fawzi]
729!> \author Fawzi Mohamed
730!> \note
731!> maybe I will move to a comma separated paretized list
732! **************************************************************************************************
733 SUBROUTINE cp_1d_i_write(array, unit_nr, el_format)
734 INTEGER(kind=int_4), INTENT(in) :: array(:)
735 INTEGER, INTENT(in) :: unit_nr
736 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
737
738 INTEGER :: iostat, i
739 CHARACTER(len=*), PARAMETER :: defaultformat = "(i6)"
740
741 WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
742 cpassert(iostat == 0)
743 IF (PRESENT(el_format)) THEN
744 DO i = 1, SIZE(array) - 1
745 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
746 IF (mod(i, 5) == 0) THEN ! only a few elements per line
747 WRITE (unit=unit_nr, fmt="(',')")
748 ELSE
749 WRITE (unit=unit_nr, fmt="(',')", advance="no")
750 END IF
751 END DO
752 IF (SIZE(array) > 0) THEN
753 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
754 END IF
755 ELSE
756 DO i = 1, SIZE(array) - 1
757 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
758 IF (mod(i, 5) == 0) THEN ! only a few elements per line
759 WRITE (unit=unit_nr, fmt="(',')")
760 ELSE
761 WRITE (unit=unit_nr, fmt="(',')", advance="no")
762 END IF
763 END DO
764 IF (SIZE(array) > 0) THEN
765 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
766 END IF
767 END IF
768 WRITE (unit=unit_nr, fmt="(' )')")
769 call m_flush(unit_nr)
770
771 END SUBROUTINE cp_1d_i_write
772
773! **************************************************************************************************
774!> \brief writes an array to the given unit
775!> \param array the array to write
776!> \param unit_nr the unit to write to (defaults to the standard out)
777!> \param el_format the format of a single element
778!> \par History
779!> 4.2002 created [fawzi]
780!> \author Fawzi Mohamed
781!> \note
782!> maybe I will move to a comma separated parentized list
783! **************************************************************************************************
784 SUBROUTINE cp_2d_i_write(array, unit_nr, el_format)
785 INTEGER(kind=int_4), INTENT(in) :: array(:, :)
786 INTEGER, INTENT(in) :: unit_nr
787 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
788
789 INTEGER :: iostat, i
790 CHARACTER(len=*), PARAMETER :: defaultformat = "(i6)"
791 CHARACTER(len=200) :: fmtstr
792 CHARACTER(len=25) :: nriga
793
794 nriga = cp_to_string(SIZE(array, 2))
795 DO i = 1, SIZE(array, 1)
796 IF (PRESENT(el_format)) THEN
797 fmtstr = '(" ",'//nriga//el_format//')'
798 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
799 ELSE
800 fmtstr = '(" ",'//nriga//defaultformat//')'
801 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
802 END IF
803 cpassert(iostat == 0)
804 END DO
805 call m_flush(unit_nr)
806 END SUBROUTINE cp_2d_i_write
807
808! **************************************************************************************************
809!> \brief If the size of the array is changes reallocate it.
810!> Issues a warning when the size changes (but not on allocation
811!> and deallocation).
812!>
813!> The data is NOT preserved (if you want to preserve the data see
814!> the realloc in the module memory_utilities)
815!> \param array the array to reallocate if necessary
816!> \param n the wanted size
817!> \par History
818!> 12.2001 first version [fawzi]
819!> 3.2002 templatized [fawzi]
820!> \author Fawzi Mohamed
821!> \note
822!> this is a different behaviour than the realloc in the module
823!> memory_utilities. It is quite low level
824! **************************************************************************************************
825 SUBROUTINE cp_1d_i_guarantee_size(array, n)
826 INTEGER(kind=int_4), POINTER :: array(:)
827 INTEGER, INTENT(in) :: n
828
829 cpassert(n >= 0)
830 IF (ASSOCIATED(array)) THEN
831 IF (SIZE(array) /= n) THEN
832 cpwarn('size has changed')
833 DEALLOCATE (array)
834 END IF
835 END IF
836 IF (.NOT. ASSOCIATED(array)) THEN
837 ALLOCATE (array(n))
838 END IF
839 END SUBROUTINE cp_1d_i_guarantee_size
840
841! **************************************************************************************************
842!> \brief If the size of the array is changes reallocate it.
843!> Issues a warning when the size changes (but not on allocation
844!> and deallocation).
845!>
846!> The data is NOT preserved (if you want to preserve the data see
847!> the realloc in the module memory_utilities)
848!> \param array the array to reallocate if necessary
849!> \param n_rows the wanted number of rows
850!> \param n_cols the wanted number of cols
851!> \par History
852!> 5.2001 first version [fawzi]
853!> \author Fawzi Mohamed
854!> \note
855!> this is a different behaviour than the realloc in the module
856!> memory_utilities. It is quite low level
857! **************************************************************************************************
858 SUBROUTINE cp_2d_i_guarantee_size(array, n_rows, n_cols)
859 INTEGER(kind=int_4), POINTER :: array(:, :)
860 INTEGER, INTENT(in) :: n_rows, n_cols
861
862 cpassert(n_cols >= 0)
863 cpassert(n_rows >= 0)
864 IF (ASSOCIATED(array)) THEN
865 IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
866 cpwarn('size has changed')
867 DEALLOCATE (array)
868 END IF
869 END IF
870 IF (.NOT. ASSOCIATED(array)) THEN
871 ALLOCATE (array(n_rows, n_cols))
872 END IF
873 END SUBROUTINE cp_2d_i_guarantee_size
874
875! **************************************************************************************************
876!> \brief returns the index at which the element el should be inserted in the
877!> array to keep it ordered (array(i)>=el).
878!> If the element is bigger than all the elements in the array returns
879!> the last index+1.
880!> \param array the array to search
881!> \param el the element to look for
882!> \param l_index the lower index for binary search (defaults to 1)
883!> \param u_index the upper index for binary search (defaults to size(array))
884!> \return ...
885!> \par History
886!> 06.2003 created [fawzi]
887!> \author Fawzi Mohamed
888!> \note
889!> the array should be ordered in growing order
890! **************************************************************************************************
891 FUNCTION cp_1d_i_bsearch(array, el, l_index, u_index) result(res)
892 INTEGER(kind=int_4), intent(in) :: array(:)
893 INTEGER(kind=int_4), intent(in) :: el
894 INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
895 integer :: res
896
897 INTEGER :: lindex, uindex, aindex
898
899 lindex = 1
900 uindex = size(array)
901 if (present(l_index)) lindex = l_index
902 if (present(u_index)) uindex = u_index
903 DO WHILE (lindex <= uindex)
904 aindex = (lindex + uindex)/2
905 IF ( array(aindex) < el) THEN
906 lindex = aindex + 1
907 ELSE
908 uindex = aindex - 1
909 END IF
910 END DO
911 res = lindex
912 END FUNCTION cp_1d_i_bsearch
913! **************************************************************************************************
914!> \brief writes an array to the given unit
915!> \param array the array to write
916!> \param unit_nr the unit to write to (defaults to the standard out)
917!> \param el_format the format of a single element
918!> \par History
919!> 4.2002 created [fawzi]
920!> \author Fawzi Mohamed
921!> \note
922!> maybe I will move to a comma separated paretized list
923! **************************************************************************************************
924 SUBROUTINE cp_1d_logical_write(array, unit_nr, el_format)
925 logical, INTENT(in) :: array(:)
926 INTEGER, INTENT(in) :: unit_nr
927 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
928
929 INTEGER :: iostat, i
930 CHARACTER(len=*), PARAMETER :: defaultformat = "(l1)"
931
932 WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
933 cpassert(iostat == 0)
934 IF (PRESENT(el_format)) THEN
935 DO i = 1, SIZE(array) - 1
936 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
937 IF (mod(i, 5) == 0) THEN ! only a few elements per line
938 WRITE (unit=unit_nr, fmt="(',')")
939 ELSE
940 WRITE (unit=unit_nr, fmt="(',')", advance="no")
941 END IF
942 END DO
943 IF (SIZE(array) > 0) THEN
944 WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
945 END IF
946 ELSE
947 DO i = 1, SIZE(array) - 1
948 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(i)
949 IF (mod(i, 5) == 0) THEN ! only a few elements per line
950 WRITE (unit=unit_nr, fmt="(',')")
951 ELSE
952 WRITE (unit=unit_nr, fmt="(',')", advance="no")
953 END IF
954 END DO
955 IF (SIZE(array) > 0) THEN
956 WRITE (unit=unit_nr, fmt=defaultformat, advance="no") array(SIZE(array))
957 END IF
958 END IF
959 WRITE (unit=unit_nr, fmt="(' )')")
960 call m_flush(unit_nr)
961
962 END SUBROUTINE cp_1d_logical_write
963
964! **************************************************************************************************
965!> \brief writes an array to the given unit
966!> \param array the array to write
967!> \param unit_nr the unit to write to (defaults to the standard out)
968!> \param el_format the format of a single element
969!> \par History
970!> 4.2002 created [fawzi]
971!> \author Fawzi Mohamed
972!> \note
973!> maybe I will move to a comma separated parentized list
974! **************************************************************************************************
975 SUBROUTINE cp_2d_logical_write(array, unit_nr, el_format)
976 logical, INTENT(in) :: array(:, :)
977 INTEGER, INTENT(in) :: unit_nr
978 CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
979
980 INTEGER :: iostat, i
981 CHARACTER(len=*), PARAMETER :: defaultformat = "(l1)"
982 CHARACTER(len=200) :: fmtstr
983 CHARACTER(len=25) :: nriga
984
985 nriga = cp_to_string(SIZE(array, 2))
986 DO i = 1, SIZE(array, 1)
987 IF (PRESENT(el_format)) THEN
988 fmtstr = '(" ",'//nriga//el_format//')'
989 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
990 ELSE
991 fmtstr = '(" ",'//nriga//defaultformat//')'
992 WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
993 END IF
994 cpassert(iostat == 0)
995 END DO
996 call m_flush(unit_nr)
997 END SUBROUTINE cp_2d_logical_write
998
999! **************************************************************************************************
1000!> \brief If the size of the array is changes reallocate it.
1001!> Issues a warning when the size changes (but not on allocation
1002!> and deallocation).
1003!>
1004!> The data is NOT preserved (if you want to preserve the data see
1005!> the realloc in the module memory_utilities)
1006!> \param array the array to reallocate if necessary
1007!> \param n the wanted size
1008!> \par History
1009!> 12.2001 first version [fawzi]
1010!> 3.2002 templatized [fawzi]
1011!> \author Fawzi Mohamed
1012!> \note
1013!> this is a different behaviour than the realloc in the module
1014!> memory_utilities. It is quite low level
1015! **************************************************************************************************
1016 SUBROUTINE cp_1d_logical_guarantee_size(array, n)
1017 logical, POINTER :: array(:)
1018 INTEGER, INTENT(in) :: n
1019
1020 cpassert(n >= 0)
1021 IF (ASSOCIATED(array)) THEN
1022 IF (SIZE(array) /= n) THEN
1023 cpwarn('size has changed')
1024 DEALLOCATE (array)
1025 END IF
1026 END IF
1027 IF (.NOT. ASSOCIATED(array)) THEN
1028 ALLOCATE (array(n))
1029 END IF
1030 END SUBROUTINE cp_1d_logical_guarantee_size
1031
1032! **************************************************************************************************
1033!> \brief If the size of the array is changes reallocate it.
1034!> Issues a warning when the size changes (but not on allocation
1035!> and deallocation).
1036!>
1037!> The data is NOT preserved (if you want to preserve the data see
1038!> the realloc in the module memory_utilities)
1039!> \param array the array to reallocate if necessary
1040!> \param n_rows the wanted number of rows
1041!> \param n_cols the wanted number of cols
1042!> \par History
1043!> 5.2001 first version [fawzi]
1044!> \author Fawzi Mohamed
1045!> \note
1046!> this is a different behaviour than the realloc in the module
1047!> memory_utilities. It is quite low level
1048! **************************************************************************************************
1049 SUBROUTINE cp_2d_logical_guarantee_size(array, n_rows, n_cols)
1050 logical, POINTER :: array(:, :)
1051 INTEGER, INTENT(in) :: n_rows, n_cols
1052
1053 cpassert(n_cols >= 0)
1054 cpassert(n_rows >= 0)
1055 IF (ASSOCIATED(array)) THEN
1056 IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
1057 cpwarn('size has changed')
1058 DEALLOCATE (array)
1059 END IF
1060 END IF
1061 IF (.NOT. ASSOCIATED(array)) THEN
1062 ALLOCATE (array(n_rows, n_cols))
1063 END IF
1064 END SUBROUTINE cp_2d_logical_guarantee_size
1065
1066! **************************************************************************************************
1067!> \brief returns the index at which the element el should be inserted in the
1068!> array to keep it ordered (array(i)>=el).
1069!> If the element is bigger than all the elements in the array returns
1070!> the last index+1.
1071!> \param array the array to search
1072!> \param el the element to look for
1073!> \param l_index the lower index for binary search (defaults to 1)
1074!> \param u_index the upper index for binary search (defaults to size(array))
1075!> \return ...
1076!> \par History
1077!> 06.2003 created [fawzi]
1078!> \author Fawzi Mohamed
1079!> \note
1080!> the array should be ordered in growing order
1081! **************************************************************************************************
1082 FUNCTION cp_1d_logical_bsearch(array, el, l_index, u_index) result(res)
1083 logical, intent(in) :: array(:)
1084 logical, intent(in) :: el
1085 INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
1086 integer :: res
1087
1088 INTEGER :: lindex, uindex, aindex
1089
1090 lindex = 1
1091 uindex = size(array)
1092 if (present(l_index)) lindex = l_index
1093 if (present(u_index)) uindex = u_index
1094 DO WHILE (lindex <= uindex)
1095 aindex = (lindex + uindex)/2
1096 IF ( (.not. array(aindex)) .and. el) THEN
1097 lindex = aindex + 1
1098 ELSE
1099 uindex = aindex - 1
1100 END IF
1101 END DO
1102 res = lindex
1103 END FUNCTION cp_1d_logical_bsearch
1104
1105END 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:124
represent a pointer to a contiguous 1d array
represent a pointer to a 1d array
represent a pointer to a contiguous 1d array
represent a pointer to a 1d array
represent a pointer to a contiguous 1d array
represent a pointer to a 1d array
represent a pointer to a contiguous 1d array
represent a pointer to a 1d array
represent a pointer to a contiguous 2d array
represent a pointer to a 2d array
represent a pointer to a contiguous 2d array
represent a pointer to a 2d array
represent a pointer to a contiguous 2d array
represent a pointer to a 2d array
represent a pointer to a contiguous 2d array
represent a pointer to a 2d array
represent a pointer to a contiguous 3d array
represent a pointer to a 3d array
represent a pointer to a contiguous 3d array
represent a pointer to a 3d array
represent a pointer to a contiguous 3d array
represent a pointer to a 3d array
represent a pointer to a contiguous 3d array
represent a pointer to a 3d array