(git:374b731)
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-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
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) .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
1101END 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
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