3
!******************************************************************************
5
! Provides utilities for copying data from one array shape to another
7
! Written by Nick R. Papior, Feb.2017
8
!******************************************************************************
10
! PUBLIC procedures available from this module:
11
! array_copy : Copies an array from one dimension to another array with another dimension
12
! array_add : Adds an array from one dimension to another array with another dimension
14
! PUBLIC parameters, types, and variables available from this module:
17
! The intent of this module is to bypass the use of the intrinsic reshape
19
! Sadly many compilers implement the reshape with a guard on pointers such
20
! that a temporary array is created upon reshaping. For very large segments
21
! this turns out to be a substantial memory consumption on the heap which
22
! may easily be circumvented by doing explicit copying.
23
! These routines are extremely simple and does nothing but copy data from
24
! one shape to another.
26
! Currently only these copies and adds are implemented:
28
! 1D -> 2D [integer, real(sp), real(dp)]
29
! 1D -> 3D [integer, real(sp), real(dp)]
30
! 2D -> 1D [integer, real(sp), real(dp)]
31
! 3D -> 1D [integer, real(sp), real(dp)]
35
use precision, only: sp, dp
36
use sys, only: die ! Termination routine
44
module procedure ac_1d_2d_ip, ac_1d_2d_sp, ac_1d_2d_dp
45
module procedure ac_1d_3d_ip, ac_1d_3d_sp, ac_1d_3d_dp
46
module procedure ac_2d_1d_ip, ac_2d_1d_sp, ac_2d_1d_dp
47
module procedure ac_3d_1d_ip, ac_3d_1d_sp, ac_3d_1d_dp
48
module procedure ac_4d_1d_ip, ac_4d_1d_sp, ac_4d_1d_dp
49
end interface array_copy
52
module procedure aa_1d_2d_ip, aa_1d_2d_sp, aa_1d_2d_dp
53
module procedure aa_1d_3d_ip, aa_1d_3d_sp, aa_1d_3d_dp
54
module procedure aa_1d_4d_ip, aa_1d_4d_sp, aa_1d_4d_dp
55
module procedure aa_2d_1d_ip, aa_2d_1d_sp, aa_2d_1d_dp
56
module procedure aa_3d_1d_ip, aa_3d_1d_sp, aa_3d_1d_dp
57
module procedure aa_4d_1d_ip, aa_4d_1d_sp, aa_4d_1d_dp
58
end interface array_add
62
! Copies a 1D array to a 2D array
63
subroutine ac_1d_2d_ip(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
64
integer, intent(in) :: from_1D, to_1D
65
integer, intent(in) :: in1D(:)
66
integer, intent(in) :: from_2D(2), to_2D(2)
67
integer, intent(inout) :: out2D(:,:)
69
! Local variables for copying
70
integer :: i1D, i2D, j2D
74
do i1D = from_1D, to_1D
75
out2D(i2D, j2D) = in1D(i1D)
77
if ( i2D > to_2D(1) ) then
83
if ( i2D /= from_2D(1) ) &
84
call die("integer: 1D->2D failed (i)")
85
if ( j2D <= to_2D(2) ) &
86
call die("integer: 1D->2D failed (j)")
88
end subroutine ac_1d_2d_ip
89
subroutine ac_1d_2d_sp(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
90
integer, intent(in) :: from_1D, to_1D
91
real(sp), intent(in) :: in1D(:)
92
integer, intent(in) :: from_2D(2), to_2D(2)
93
real(sp), intent(inout) :: out2D(:,:)
95
! Local variables for copying
96
integer :: i1D, i2D, j2D
100
do i1D = from_1D, to_1D
101
out2D(i2D, j2D) = in1D(i1D)
103
if ( i2D > to_2D(1) ) then
109
if ( i2D /= from_2D(1) ) &
110
call die("real: 1D->2D failed (i)")
111
if ( j2D <= to_2D(2) ) &
112
call die("real: 1D->2D failed (j)")
114
end subroutine ac_1d_2d_sp
115
subroutine ac_1d_2d_dp(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
116
integer, intent(in) :: from_1D, to_1D
117
real(dp), intent(in) :: in1D(:)
118
integer, intent(in) :: from_2D(2), to_2D(2)
119
real(dp), intent(inout) :: out2D(:,:)
121
! Local variables for copying
122
integer :: i1D, i2D, j2D
126
do i1D = from_1D, to_1D
127
out2D(i2D, j2D) = in1D(i1D)
129
if ( i2D > to_2D(1) ) then
135
if ( i2D /= from_2D(1) ) &
136
call die("double: 1D->2D failed (i)")
137
if ( j2D <= to_2D(2) ) &
138
call die("double: 1D->2D failed (j)")
140
end subroutine ac_1d_2d_dp
142
! Copies a 1D array to a 3D array
143
subroutine ac_1d_3d_ip(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
144
integer, intent(in) :: from_1D, to_1D
145
integer, intent(in) :: in1D(:)
146
integer, intent(in) :: from_3D(3), to_3D(3)
147
integer, intent(inout) :: out3D(:,:,:)
149
! Local variables for copying
150
integer :: i1D, i3D, j3D, k3D
155
do i1D = from_1D, to_1D
156
out3D(i3D, j3D, k3D) = in1D(i1D)
158
if ( i3D > to_3D(1) ) then
162
if ( j3D > to_3D(2) ) then
168
if ( i3D /= from_3D(1) ) &
169
call die("integer: 1D->3D failed (i)")
170
if ( j3D /= from_3D(2) ) &
171
call die("integer: 1D->3D failed (j)")
172
if ( k3D <= to_3D(3) ) &
173
call die("integer: 1D->3D failed (k)")
175
end subroutine ac_1d_3d_ip
176
subroutine ac_1d_3d_sp(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
177
integer, intent(in) :: from_1D, to_1D
178
real(sp), intent(in) :: in1D(:)
179
integer, intent(in) :: from_3D(3), to_3D(3)
180
real(sp), intent(inout) :: out3D(:,:,:)
182
! Local variables for copying
183
integer :: i1D, i3D, j3D, k3D
188
do i1D = from_1D, to_1D
189
out3D(i3D, j3D, k3D) = in1D(i1D)
191
if ( i3D > to_3D(1) ) then
195
if ( j3D > to_3D(2) ) then
201
if ( i3D /= from_3D(1) ) &
202
call die("real: 1D->3D failed (i)")
203
if ( j3D /= from_3D(2) ) &
204
call die("real: 1D->3D failed (j)")
205
if ( k3D <= to_3D(3) ) &
206
call die("real: 1D->3D failed (k)")
208
end subroutine ac_1d_3d_sp
209
subroutine ac_1d_3d_dp(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
210
integer, intent(in) :: from_1D, to_1D
211
real(dp), intent(in) :: in1D(:)
212
integer, intent(in) :: from_3D(3), to_3D(3)
213
real(dp), intent(inout) :: out3D(:,:,:)
215
! Local variables for copying
216
integer :: i1D, i3D, j3D, k3D
221
do i1D = from_1D, to_1D
222
out3D(i3D, j3D, k3D) = in1D(i1D)
224
if ( i3D > to_3D(1) ) then
228
if ( j3D > to_3D(2) ) then
234
if ( i3D /= from_3D(1) ) &
235
call die("double: 1D->3D failed (i)")
236
if ( j3D /= from_3D(2) ) &
237
call die("double: 1D->3D failed (j)")
238
if ( k3D <= to_3D(3) ) &
239
call die("double: 1D->3D failed (k)")
241
end subroutine ac_1d_3d_dp
243
! Copies a 2D array to a 1D array
244
subroutine ac_2d_1d_ip(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
245
integer, intent(in) :: from_2D(2), to_2D(2)
246
integer, intent(in) :: in2D(:,:)
247
integer, intent(in) :: from_1D, to_1D
248
integer, intent(inout) :: out1D(:)
250
! Local variables for copying
251
integer :: i2D, j2D, i1D
254
do j2D = from_2D(2), to_2D(2)
255
do i2D = from_2D(1), to_2D(1)
256
out1D(i1D) = in2D(i2D, j2D)
261
if ( i1D <= to_1D ) &
262
call die("integer: 2D->1D failed")
264
end subroutine ac_2d_1d_ip
265
subroutine ac_2d_1d_sp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
266
integer, intent(in) :: from_2D(2), to_2D(2)
267
real(sp), intent(in) :: in2D(:,:)
268
integer, intent(in) :: from_1D, to_1D
269
real(sp), intent(inout) :: out1D(:)
271
! Local variables for copying
272
integer :: i2D, j2D, i1D
275
do j2D = from_2D(2), to_2D(2)
276
do i2D = from_2D(1), to_2D(1)
277
out1D(i1D) = in2D(i2D, j2D)
282
if ( i1D <= to_1D ) &
283
call die("real: 2D->1D failed")
285
end subroutine ac_2d_1d_sp
286
subroutine ac_2d_1d_dp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
287
integer, intent(in) :: from_2D(2), to_2D(2)
288
real(dp), intent(in) :: in2D(:,:)
289
integer, intent(in) :: from_1D, to_1D
290
real(dp), intent(inout) :: out1D(:)
292
! Local variables for copying
293
integer :: i2D, j2D, i1D
296
do j2D = from_2D(2), to_2D(2)
297
do i2D = from_2D(1), to_2D(1)
298
out1D(i1D) = in2D(i2D, j2D)
303
if ( i1D <= to_1D ) &
304
call die("double: 2D->1D failed")
306
end subroutine ac_2d_1d_dp
308
! Copies a 3D array to a 1D array
309
subroutine ac_3d_1d_ip(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
310
integer, intent(in) :: from_3D(3), to_3D(3)
311
integer, intent(in) :: in3D(:,:,:)
312
integer, intent(in) :: from_1D, to_1D
313
integer, intent(inout) :: out1D(:)
315
! Local variables for copying
316
integer :: i3D, j3D, k3D, i1D
319
do k3D = from_3D(3), to_3D(3)
320
do j3D = from_3D(2), to_3D(2)
321
do i3D = from_3D(1), to_3D(1)
322
out1D(i1D) = in3D(i3D, j3D, k3D)
328
if ( i1D <= to_1D ) &
329
call die("integer: 3D->1D failed")
331
end subroutine ac_3d_1d_ip
332
subroutine ac_3d_1d_sp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
333
integer, intent(in) :: from_3D(3), to_3D(3)
334
real(sp), intent(in) :: in3D(:,:,:)
335
integer, intent(in) :: from_1D, to_1D
336
real(sp), intent(inout) :: out1D(:)
338
! Local variables for copying
339
integer :: i3D, j3D, k3D, i1D
342
do k3D = from_3D(3), to_3D(3)
343
do j3D = from_3D(2), to_3D(2)
344
do i3D = from_3D(1), to_3D(1)
345
out1D(i1D) = in3D(i3D, j3D, k3D)
351
if ( i1D <= to_1D ) &
352
call die("real: 3D->1D failed")
354
end subroutine ac_3d_1d_sp
355
subroutine ac_3d_1d_dp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
356
integer, intent(in) :: from_3D(3), to_3D(3)
357
real(dp), intent(in) :: in3D(:,:,:)
358
integer, intent(in) :: from_1D, to_1D
359
real(dp), intent(inout) :: out1D(:)
361
! Local variables for copying
362
integer :: i3D, j3D, k3D, i1D
365
do k3D = from_3D(3), to_3D(3)
366
do j3D = from_3D(2), to_3D(2)
367
do i3D = from_3D(1), to_3D(1)
368
out1D(i1D) = in3D(i3D, j3D, k3D)
374
if ( i1D <= to_1D ) &
375
call die("double: 3D->1D failed")
377
end subroutine ac_3d_1d_dp
379
! Copies a 4D array to a 1D array
380
subroutine ac_4d_1d_ip(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
381
integer, intent(in) :: from_4D(4), to_4D(4)
382
integer, intent(in) :: in4D(:,:,:,:)
383
integer, intent(in) :: from_1D, to_1D
384
integer, intent(inout) :: out1D(:)
386
! Local variables for copying
387
integer :: i4D, j4D, k4D, m4D, i1D
390
do m4D = from_4D(4), to_4D(4)
391
do k4D = from_4D(3), to_4D(3)
392
do j4D = from_4D(2), to_4D(2)
393
do i4D = from_4D(1), to_4D(1)
394
out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
401
if ( i1D <= to_1D ) &
402
call die("integer: 4D->1D failed")
404
end subroutine ac_4d_1d_ip
405
subroutine ac_4d_1d_sp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
406
integer, intent(in) :: from_4D(4), to_4D(4)
407
real(sp), intent(in) :: in4D(:,:,:,:)
408
integer, intent(in) :: from_1D, to_1D
409
real(sp), intent(inout) :: out1D(:)
411
! Local variables for copying
412
integer :: i4D, j4D, k4D, m4D, i1D
415
do m4D = from_4D(4), to_4D(4)
416
do k4D = from_4D(3), to_4D(3)
417
do j4D = from_4D(2), to_4D(2)
418
do i4D = from_4D(1), to_4D(1)
419
out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
426
if ( i1D <= to_1D ) &
427
call die("real: 4D->1D failed")
429
end subroutine ac_4d_1d_sp
430
subroutine ac_4d_1d_dp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
431
integer, intent(in) :: from_4D(4), to_4D(4)
432
real(dp), intent(in) :: in4D(:,:,:,:)
433
integer, intent(in) :: from_1D, to_1D
434
real(dp), intent(inout) :: out1D(:)
436
! Local variables for copying
437
integer :: i4D, j4D, k4D, m4D, i1D
440
do m4D = from_4D(4), to_4D(4)
441
do k4D = from_4D(3), to_4D(3)
442
do j4D = from_4D(2), to_4D(2)
443
do i4D = from_4D(1), to_4D(1)
444
out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
451
if ( i1D <= to_1D ) &
452
call die("double: 4D->1D failed")
454
end subroutine ac_4d_1d_dp
457
! Adds a 1D array to a 2D array
458
subroutine aa_1d_2d_ip(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
459
integer, intent(in) :: from_1D, to_1D
460
integer, intent(in) :: a1D(:)
461
integer, intent(in) :: from_2D(2), to_2D(2)
462
integer, intent(inout) :: out2D(:,:)
464
! Local variables for copying
465
integer :: i1D, i2D, j2D
469
do i1D = from_1D, to_1D
470
out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
472
if ( i2D > to_2D(1) ) then
478
if ( i2D /= from_2D(1) ) &
479
call die("integer: 1D+>2D failed (i)")
480
if ( j2D <= to_2D(2) ) &
481
call die("integer: 1D+>2D failed (j)")
483
end subroutine aa_1d_2d_ip
484
subroutine aa_1d_2d_sp(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
485
integer, intent(in) :: from_1D, to_1D
486
real(sp), intent(in) :: a1D(:)
487
integer, intent(in) :: from_2D(2), to_2D(2)
488
real(sp), intent(inout) :: out2D(:,:)
490
! Local variables for copying
491
integer :: i1D, i2D, j2D
495
do i1D = from_1D, to_1D
496
out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
498
if ( i2D > to_2D(1) ) then
504
if ( i2D /= from_2D(1) ) &
505
call die("real: 1D+>2D failed (i)")
506
if ( j2D <= to_2D(2) ) &
507
call die("real: 1D+>2D failed (j)")
509
end subroutine aa_1d_2d_sp
510
subroutine aa_1d_2d_dp(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
511
integer, intent(in) :: from_1D, to_1D
512
real(dp), intent(in) :: a1D(:)
513
integer, intent(in) :: from_2D(2), to_2D(2)
514
real(dp), intent(inout) :: out2D(:,:)
516
! Local variables for copying
517
integer :: i1D, i2D, j2D
521
do i1D = from_1D, to_1D
522
out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
524
if ( i2D > to_2D(1) ) then
530
if ( i2D /= from_2D(1) ) &
531
call die("double: 1D+>2D failed (i)")
532
if ( j2D <= to_2D(2) ) &
533
call die("double: 1D+>2D failed (j)")
535
end subroutine aa_1d_2d_dp
537
! Adds a 1D array to a 3D array
538
subroutine aa_1d_3d_ip(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
539
integer, intent(in) :: from_1D, to_1D
540
integer, intent(in) :: a1D(:)
541
integer, intent(in) :: from_3D(3), to_3D(3)
542
integer, intent(inout) :: out3D(:,:,:)
544
! Local variables for copying
545
integer :: i1D, i3D, j3D, k3D
550
do i1D = from_1D, to_1D
551
out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
553
if ( i3D > to_3D(1) ) then
557
if ( j3D > to_3D(2) ) then
563
if ( i3D /= from_3D(1) ) &
564
call die("integer: 1D+>3D failed (i)")
565
if ( j3D /= from_3D(2) ) &
566
call die("integer: 1D+>3D failed (j)")
567
if ( k3D <= to_3D(3) ) &
568
call die("integer: 1D+>3D failed (k)")
570
end subroutine aa_1d_3d_ip
571
subroutine aa_1d_3d_sp(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
572
integer, intent(in) :: from_1D, to_1D
573
real(sp), intent(in) :: a1D(:)
574
integer, intent(in) :: from_3D(3), to_3D(3)
575
real(sp), intent(inout) :: out3D(:,:,:)
577
! Local variables for copying
578
integer :: i1D, i3D, j3D, k3D
583
do i1D = from_1D, to_1D
584
out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
586
if ( i3D > to_3D(1) ) then
590
if ( j3D > to_3D(2) ) then
596
if ( i3D /= from_3D(1) ) &
597
call die("real: 1D+>3D failed (i)")
598
if ( j3D /= from_3D(2) ) &
599
call die("real: 1D+>3D failed (j)")
600
if ( k3D <= to_3D(3) ) &
601
call die("real: 1D+>3D failed (k)")
603
end subroutine aa_1d_3d_sp
604
subroutine aa_1d_3d_dp(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
605
integer, intent(in) :: from_1D, to_1D
606
real(dp), intent(in) :: a1D(:)
607
integer, intent(in) :: from_3D(3), to_3D(3)
608
real(dp), intent(inout) :: out3D(:,:,:)
610
! Local variables for copying
611
integer :: i1D, i3D, j3D, k3D
616
do i1D = from_1D, to_1D
617
out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
619
if ( i3D > to_3D(1) ) then
623
if ( j3D > to_3D(2) ) then
629
if ( i3D /= from_3D(1) ) &
630
call die("double: 1D+>3D failed (i)")
631
if ( j3D /= from_3D(2) ) &
632
call die("double: 1D+>3D failed (j)")
633
if ( k3D <= to_3D(3) ) &
634
call die("double: 1D+>3D failed (k)")
636
end subroutine aa_1d_3d_dp
638
! Adds a 1D array to a 4D array
639
subroutine aa_1d_4d_ip(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
640
integer, intent(in) :: from_1D, to_1D
641
integer, intent(in) :: a1D(:)
642
integer, intent(in) :: from_4D(4), to_4D(4)
643
integer, intent(inout) :: out4D(:,:,:,:)
645
! Local variables for copying
646
integer :: i1D, i4D, j4D, k4D, m4D
652
do i1D = from_1D, to_1D
653
out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
655
if ( i4D > to_4D(1) ) then
659
if ( j4D > to_4D(2) ) then
663
if ( k4D > to_4D(3) ) then
669
if ( i4D /= from_4D(1) ) &
670
call die("integer: 1D+>4D failed (i)")
671
if ( j4D /= from_4D(2) ) &
672
call die("integer: 1D+>4D failed (j)")
673
if ( k4D /= from_4D(3) ) &
674
call die("integer: 1D+>4D failed (k)")
675
if ( m4D <= to_4D(4) ) &
676
call die("integer: 1D+>4D failed (m)")
678
end subroutine aa_1d_4d_ip
679
subroutine aa_1d_4d_sp(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
680
integer, intent(in) :: from_1D, to_1D
681
real(sp), intent(in) :: a1D(:)
682
integer, intent(in) :: from_4D(4), to_4D(4)
683
real(sp), intent(inout) :: out4D(:,:,:,:)
685
! Local variables for copying
686
integer :: i1D, i4D, j4D, k4D, m4D
692
do i1D = from_1D, to_1D
693
out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
695
if ( i4D > to_4D(1) ) then
699
if ( j4D > to_4D(2) ) then
703
if ( k4D > to_4D(3) ) then
709
if ( i4D /= from_4D(1) ) &
710
call die("real: 1D+>4D failed (i)")
711
if ( j4D /= from_4D(2) ) &
712
call die("real: 1D+>4D failed (j)")
713
if ( k4D /= from_4D(3) ) &
714
call die("real: 1D+>4D failed (k)")
715
if ( m4D <= to_4D(4) ) &
716
call die("real: 1D+>4D failed (m)")
718
end subroutine aa_1d_4d_sp
719
subroutine aa_1d_4d_dp(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
720
integer, intent(in) :: from_1D, to_1D
721
real(dp), intent(in) :: a1D(:)
722
integer, intent(in) :: from_4D(4), to_4D(4)
723
real(dp), intent(inout) :: out4D(:,:,:,:)
725
! Local variables for copying
726
integer :: i1D, i4D, j4D, k4D, m4D
732
do i1D = from_1D, to_1D
733
out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
735
if ( i4D > to_4D(1) ) then
739
if ( j4D > to_4D(2) ) then
743
if ( k4D > to_4D(3) ) then
749
if ( i4D /= from_4D(1) ) &
750
call die("double: 1D+>4D failed (i)")
751
if ( j4D /= from_4D(2) ) &
752
call die("double: 1D+>4D failed (j)")
753
if ( k4D /= from_4D(3) ) &
754
call die("double: 1D+>4D failed (k)")
755
if ( m4D <= to_4D(4) ) &
756
call die("double: 1D+>4D failed (m)")
758
end subroutine aa_1d_4d_dp
760
! Adds a 2D array to a 1D array
761
subroutine aa_2d_1d_ip(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
762
integer, intent(in) :: from_2D(2), to_2D(2)
763
integer, intent(in) :: in2D(:,:)
764
integer, intent(in) :: from_1D, to_1D
765
integer, intent(inout) :: out1D(:)
767
! Local variables for copying
768
integer :: i2D, j2D, i1D
771
do j2D = from_2D(2), to_2D(2)
772
do i2D = from_2D(1), to_2D(1)
773
out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
778
if ( i1D <= to_1D ) &
779
call die("integer: 2D+>1D failed")
781
end subroutine aa_2d_1d_ip
782
subroutine aa_2d_1d_sp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
783
integer, intent(in) :: from_2D(2), to_2D(2)
784
real(sp), intent(in) :: in2D(:,:)
785
integer, intent(in) :: from_1D, to_1D
786
real(sp), intent(inout) :: out1D(:)
788
! Local variables for copying
789
integer :: i2D, j2D, i1D
792
do j2D = from_2D(2), to_2D(2)
793
do i2D = from_2D(1), to_2D(1)
794
out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
799
if ( i1D <= to_1D ) &
800
call die("real: 2D+>1D failed")
802
end subroutine aa_2d_1d_sp
803
subroutine aa_2d_1d_dp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
804
integer, intent(in) :: from_2D(2), to_2D(2)
805
real(dp), intent(in) :: in2D(:,:)
806
integer, intent(in) :: from_1D, to_1D
807
real(dp), intent(inout) :: out1D(:)
809
! Local variables for copying
810
integer :: i2D, j2D, i1D
813
do j2D = from_2D(2), to_2D(2)
814
do i2D = from_2D(1), to_2D(1)
815
out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
820
if ( i1D <= to_1D ) &
821
call die("double: 2D+>1D failed")
823
end subroutine aa_2d_1d_dp
825
! Adds a 3D array to a 1D array
826
subroutine aa_3d_1d_ip(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
827
integer, intent(in) :: from_3D(3), to_3D(3)
828
integer, intent(in) :: in3D(:,:,:)
829
integer, intent(in) :: from_1D, to_1D
830
integer, intent(inout) :: out1D(:)
832
! Local variables for copying
833
integer :: i3D, j3D, k3D, i1D
836
do k3D = from_3D(3), to_3D(3)
837
do j3D = from_3D(2), to_3D(2)
838
do i3D = from_3D(1), to_3D(1)
839
out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
845
if ( i1D <= to_1D ) &
846
call die("integer: 3D+>1D failed")
848
end subroutine aa_3d_1d_ip
849
subroutine aa_3d_1d_sp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
850
integer, intent(in) :: from_3D(3), to_3D(3)
851
real(sp), intent(in) :: in3D(:,:,:)
852
integer, intent(in) :: from_1D, to_1D
853
real(sp), intent(inout) :: out1D(:)
855
! Local variables for copying
856
integer :: i3D, j3D, k3D, i1D
859
do k3D = from_3D(3), to_3D(3)
860
do j3D = from_3D(2), to_3D(2)
861
do i3D = from_3D(1), to_3D(1)
862
out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
868
if ( i1D <= to_1D ) &
869
call die("real: 3D+>1D failed")
871
end subroutine aa_3d_1d_sp
872
subroutine aa_3d_1d_dp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
873
integer, intent(in) :: from_3D(3), to_3D(3)
874
real(dp), intent(in) :: in3D(:,:,:)
875
integer, intent(in) :: from_1D, to_1D
876
real(dp), intent(inout) :: out1D(:)
878
! Local variables for copying
879
integer :: i3D, j3D, k3D, i1D
882
do k3D = from_3D(3), to_3D(3)
883
do j3D = from_3D(2), to_3D(2)
884
do i3D = from_3D(1), to_3D(1)
885
out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
891
if ( i1D <= to_1D ) &
892
call die("double: 3D+>1D failed")
894
end subroutine aa_3d_1d_dp
896
! Adds a 4D array to a 1D array
897
subroutine aa_4d_1d_ip(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
898
integer, intent(in) :: from_4D(4), to_4D(4)
899
integer, intent(in) :: in4D(:,:,:,:)
900
integer, intent(in) :: from_1D, to_1D
901
integer, intent(inout) :: out1D(:)
903
! Local variables for copying
904
integer :: i4D, j4D, k4D, m4D, i1D
907
do m4D = from_4D(4), to_4D(4)
908
do k4D = from_4D(3), to_4D(3)
909
do j4D = from_4D(2), to_4D(2)
910
do i4D = from_4D(1), to_4D(1)
911
out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
918
if ( i1D <= to_1D ) &
919
call die("integer: 4D+>1D failed")
921
end subroutine aa_4d_1d_ip
922
subroutine aa_4d_1d_sp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
923
integer, intent(in) :: from_4D(4), to_4D(4)
924
real(sp), intent(in) :: in4D(:,:,:,:)
925
integer, intent(in) :: from_1D, to_1D
926
real(sp), intent(inout) :: out1D(:)
928
! Local variables for copying
929
integer :: i4D, j4D, k4D, m4D, i1D
932
do m4D = from_4D(4), to_4D(4)
933
do k4D = from_4D(3), to_4D(3)
934
do j4D = from_4D(2), to_4D(2)
935
do i4D = from_4D(1), to_4D(1)
936
out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
943
if ( i1D <= to_1D ) &
944
call die("real: 4D+>1D failed")
946
end subroutine aa_4d_1d_sp
947
subroutine aa_4d_1d_dp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
948
integer, intent(in) :: from_4D(4), to_4D(4)
949
real(dp), intent(in) :: in4D(:,:,:,:)
950
integer, intent(in) :: from_1D, to_1D
951
real(dp), intent(inout) :: out1D(:)
953
! Local variables for copying
954
integer :: i4D, j4D, k4D, m4D, i1D
957
do m4D = from_4D(4), to_4D(4)
958
do k4D = from_4D(3), to_4D(3)
959
do j4D = from_4D(2), to_4D(2)
960
do i4D = from_4D(1), to_4D(1)
961
out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
968
if ( i1D <= to_1D ) &
969
call die("double: 4D+>1D failed")
971
end subroutine aa_4d_1d_dp