Repository navigation
Expand file tree
/
Copy pathpplib2.f90
More file actions
676 lines (676 loc) · 22.7 KB
/
Copy pathpplib2.f90
File metadata and controls
676 lines (676 loc) · 22.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
!-----------------------------------------------------------------------
! Basic parallel PIC library for MPI communications
! pplib2.f90 contains basic communications procedures for 1d partitions
! PPINIT2 initializes parallel processing for Fortran90, returns
! number of processors and processor id.
! PPEXIT terminates parallel processing.
! PPABORT aborts parallel processing.
! PWTIMERA performs parallel local wall clock timing.
! PPSUM performs parallel sum of a real vector.
! PPDSUM performs parallel sum of a double precision vector.
! PPMAX performs parallel maximum of a real vector.
! PPIMAX performs parallel maximum of an integer vector.
! PPDMAX performs parallel maximum of a double precision vector.
! PPDSCAN performs parallel prefix reduction of a double precision
! vector
! PPBICAST broadcasts integer data from node 0
! PPBDCAST broadcasts double precision data from node 0
!
! for non-periodic field boundary condtions
! PPNLCGUARD2L copies data to interior guard cells in y for scalar data,
! linear interpolation, and distributed data with
! non-uniform partition.
! PPNLAGUARD2L adds interior guard cells in y for scalar array, linear
! interpolation, and distributed data with non-uniform
! partition.
!
! PPWRVNDATA2 collects distributed real 2d vector non-uniform data f and
! writes to a fortran unformatted file
!
! written by viktor k. decyk, ucla
! copyright 1995, regents of the university of california
module pplib2
use mpi
implicit none
!
! common data for parallel processing
! lstat = length of status array
integer, parameter :: lstat = MPI_STATUS_SIZE
! nproc = number of real or virtual processors obtained
! lgrp = current communicator
! mreal = default datatype for reals
! mint = default datatype for integers
! mcplx = default datatype for complex type
! mdouble = default double precision type
! lworld = MPI_COMM_WORLD communicator
integer :: nproc, lgrp, mreal, mint, mcplx, mdouble, lworld
! msum = MPI_SUM
! mmax = MPI_MAX
integer :: msum, mmax
save
!
private
public :: lstat, nproc, lgrp, mreal, mint, mcplx, mdouble, lworld
public :: PPINIT2, PPEXIT, PPABORT, PWTIMERA
public :: PPSUM, PPDSUM, PPMAX, PPIMAX, PPDMAX, PPDSCAN
public :: PPBICAST, PPBDCAST
public :: PPNLCGUARD2L, PPNLAGUARD2L
public :: PPWRVNDATA2
!
contains
!
!-----------------------------------------------------------------------
subroutine PPINIT2(idproc,nvp)
! this subroutine initializes parallel processing
! lgrp communicator = MPI_COMM_WORLD
! output: idproc, nvp
! idproc = processor id in lgrp communicator
! nvp = number of real or virtual processors obtained
implicit none
integer, intent(inout) :: idproc, nvp
! nproc = number of real or virtual processors obtained
! lgrp = current communicator
! mreal = default datatype for reals
! mint = default datatype for integers
! mcplx = default datatype for complex type
! mdouble = default double precision type
! lworld = MPI_COMM_WORLD communicator
! msum = MPI_SUM
! mmax = MPI_MAX
! local data
integer :: ierror, ndprec, idprec
integer :: iprec
logical :: flag
real :: prec
! ndprec = (0,1) = (no,yes) use (normal,autodouble) precision
if (digits(prec) > 24) then
ndprec = 1
else
ndprec = 0
endif
! idprec = (0,1) = (no,yes) use (normal,autodouble) integer precision
if (digits(iprec) > 31) then
idprec = 1
else
idprec = 0
endif
! this segment is used for mpi computers
! indicate whether MPI_INIT has been called
call MPI_INITIALIZED(flag,ierror)
if (.not.flag) then
! initialize the MPI execution environment
call MPI_INIT(ierror)
if (ierror /= 0) stop
endif
lworld = MPI_COMM_WORLD
lgrp = lworld
! determine the rank of the calling process in the communicator
call MPI_COMM_RANK(lgrp,idproc,ierror)
! determine the size of the group associated with a communicator
call MPI_COMM_SIZE(lgrp,nproc,ierror)
! set default datatypes
mint = MPI_INTEGER
mdouble = MPI_DOUBLE_PRECISION
! single precision real
if (ndprec==0) then
mreal = MPI_REAL
mcplx = MPI_COMPLEX
! double precision real
else
mreal = MPI_DOUBLE_PRECISION
mcplx = MPI_DOUBLE_COMPLEX
endif
! single precision integer
! if (idprec==0) then
! mint = MPI_INTEGER
! double precision integer
! else
! mint = MPI_INTEGER8
! endif
! operators
msum = MPI_SUM
mmax = MPI_MAX
nvp = nproc
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPEXIT()
! this subroutine terminates parallel processing
implicit none
! lworld = MPI_COMM_WORLD communicator
! local data
integer :: ierror
logical :: flag
! indicate whether MPI_INIT has been called
call MPI_INITIALIZED(flag,ierror)
if (flag) then
! synchronize processes
call MPI_BARRIER(lworld,ierror)
! terminate MPI execution environment
call MPI_FINALIZE(ierror)
endif
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPABORT()
! this subroutine aborts parallel processing
implicit none
! lworld = MPI_COMM_WORLD communicator
! local data
integer :: errorcode, ierror
logical :: flag
! indicate whether MPI_INIT has been called
call MPI_INITIALIZED(flag,ierror)
if (flag) then
errorcode = 1
! terminate MPI execution environment
call MPI_ABORT(lworld,errorcode,ierror)
endif
end subroutine
!
!-----------------------------------------------------------------------
subroutine PWTIMERA(icntrl,time,dtime)
! this subroutine performs local wall clock timing
! input: icntrl, dtime
! icntrl = (-1,0,1) = (initialize,ignore,read) clock
! clock should be initialized before it is read!
! time = elapsed time in seconds
! dtime = current time
! written for mpi
implicit none
integer, intent(in) :: icntrl
real, intent(inout) :: time
double precision, intent(inout) :: dtime
! local data
double precision :: jclock
! initialize clock
if (icntrl==(-1)) then
dtime = MPI_WTIME()
! read clock and write time difference from last clock initialization
else if (icntrl==1) then
jclock = dtime
dtime = MPI_WTIME()
time = real(dtime - jclock)
endif
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPSUM(f,g,nxp)
! this subroutine performs a parallel sum of a vector, that is:
! f(j,k) = sum over k of f(j,k)
! at the end, all processors contain the same summation.
! f = input and output real data
! g = scratch real array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
real, dimension(nxp), intent(inout) :: f, g
! lgrp = current communicator
! mreal = default datatype for reals
! msum = MPI_SUM
! local data
integer :: j, ierr
! return if only one processor
if (nproc==1) return
! perform sum
call MPI_ALLREDUCE(f,g,nxp,mreal,msum,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
f(j) = g(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDSUM(f,g,nxp)
! this subroutine performs a parallel sum of a vector, that is:
! f(j,k) = sum over k of f(j,k)
! at the end, all processors contain the same summation.
! f = input and output double precision data
! g = scratch double precision array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
! lgrp = current communicator
! mdouble = default double precision type
! msum = MPI_SUM
! local data
integer :: j, ierr
! return if only one processor
if (nproc==1) return
! perform sum
call MPI_ALLREDUCE(f,g,nxp,mdouble,msum,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
f(j) = g(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPMAX(f,g,nxp)
! this subroutine finds parallel maximum for each element of a vector
! that is, f(j,k) = maximum as a function of k of f(j,k)
! at the end, all processors contain the same maximum.
! f = input and output real data
! g = scratch real array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
real, dimension(nxp), intent(inout) :: f, g
! lgrp = current communicator
! mreal = default datatype for reals
! mmax = MPI_MAX
! local data
integer j, ierr
! return if only one processor
if (nproc==1) return
! find maximum
call MPI_ALLREDUCE(f,g,nxp,mreal,mmax,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
f(j) = g(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPIMAX(if,ig,nxp)
! this subroutine finds parallel maximum for each element of a vector
! that is, if(j,k) = maximum as a function of k of if(j,k)
! at the end, all processors contain the same maximum.
! if = input and output integer data
! ig = scratch integer array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
integer, dimension(nxp), intent(inout) :: if, ig
! nproc = number of real or virtual processors obtained
! lgrp = current communicator
! mint = default datatype for integers
! mmax = MPI_MAX
! local data
integer :: j, ierr
! return if only one processor
if (nproc==1) return
! find maximum
call MPI_ALLREDUCE(if,ig,nxp,mint,mmax,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
if(j) = ig(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDMAX(f,g,nxp)
! this subroutine finds parallel maximum for each element of a vector
! that is, f(j,k) = maximum as a function of k of f(j,k)
! at the end, all processors contain the same maximum.
! f = input and output double precision data
! g = scratch double precision array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
! lgrp = current communicator
! mdouble = default double precision type
! mmax = MPI_MAX
! local data
integer j, ierr
! return if only one processor
if (nproc==1) return
! find maximum
call MPI_ALLREDUCE(f,g,nxp,mdouble,mmax,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
f(j) = g(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDSCAN(f,g,nxp)
! this subroutine performs a parallel prefix reduction of a vector,
! that is: f(j,k) = sum over k of f(j,k), where the sum is over k values
! less than idproc.
! f = input and output double precision data
! g = scratch double precision array
! nxp = number of data values in vector
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
! lgrp = current communicator
! mdouble = default double precision type
! msum = MPI_SUM
! local data
integer :: j, ierr
! return if only one processor
if (nproc==1) return
! performs a parallel prefixm sum
call MPI_SCAN(f,g,nxp,mdouble,msum,lgrp,ierr)
! copy output from scratch array
do j = 1, nxp
f(j) = g(j)
enddo
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPBICAST(if,nxp)
! this subroutine broadcasts integer data from node 0
! if = input and output integer data
! nxp = number of data values
implicit none
integer, intent(in) :: nxp
integer, dimension(nxp), intent(inout) :: if
! nproc = number of real or virtual processors obtained
! lgrp = current communicator
! mint = default datatype for integers
! local data
integer :: ierr
! return if only one processor
if (nproc==1) return
! broadcast integer
call MPI_BCAST(if,nxp,mint,0,lgrp,ierr)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPBDCAST(f,nxp)
! this subroutine broadcasts double precision data from node 0
! f = input and output double precision data
! nxp = number of data values
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f
! nproc = number of real or virtual processors obtained
! lgrp = current communicator
! mdouble = default double precision type
! local data
integer :: ierr
! return if only one processor
if (nproc==1) return
! broadcast integer
call MPI_BCAST(f,nxp,mdouble,0,lgrp,ierr)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPNLCGUARD2L(f,nyp,kstrt,nvp,nxv,nypmx)
! this subroutine copies data to guard cells in non-uniform partitions
! guard cell on last processor is presumed already set.
! f(j,k) = real data for grid j,k in particle partition.
! the grid is non-uniform and includes one extra guard cell.
! output: f
! nyp = number of primary gridpoints in field partition
! it is assumed the nyp > 0.
! kstrt = starting data block number
! nvp = number of real or virtual processors
! nxv = first dimension of f, must be >= nx
! nypmx = maximum size of field partition, including guard cell.
! linear interpolation, for distributed data
implicit none
integer, intent(in) :: nyp, kstrt, nvp, nxv, nypmx
real, dimension(nxv,nypmx), intent(inout) :: f
! lgrp = current communicator
! mreal = default datatype for reals
! local data
integer :: ks, moff, kl, kr
integer :: msid, ierr
integer, dimension(lstat) :: istatus
! special case for one processor
if (nvp==1) return
ks = kstrt - 1
moff = nypmx*nvp + 2
! copy to guard cells
kr = ks + 1
kl = ks - 1
ks = nyp + 1
! this segment is used for mpi computers
if (kr < nvp) then
call MPI_IRECV(f(1,ks),nxv,mreal,kr,moff,lgrp,msid,ierr)
endif
if (kl >= 0) then
call MPI_SEND(f,nxv,mreal,kl,moff,lgrp,ierr)
endif
if (kr < nvp) then
call MPI_WAIT(msid,istatus,ierr)
endif
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPNLAGUARD2L(f,scr,nyp,nx,kstrt,nvp,nxv,nypmx)
! this subroutine adds data from guard cells in non-uniform partitions
! for scalar data. no copying is done at the boundary edges.
! f(j,k) = real data for grid j,k in particle partition.
! the grid is non-uniform and includes one extra guard cell.
! output: f, scr
! scr(j) = scratch array for particle partition
! nyp = number of primary gridpoints in particle partition
! it is assumed the nyp > 0.
! kstrt = starting data block number
! nvp = number of real or virtual processors
! nx = system length in x direction
! nxv = first dimension of f, must be >= nx
! nypmx = maximum size of field partition, including guard cells.
! linear interpolation, for distributed data
implicit none
integer, intent(in) :: nyp, kstrt, nvp, nx, nxv, nypmx
real, dimension(nxv,nypmx), intent(inout) :: f
real, dimension(nxv), intent(inout) :: scr
! lgrp = current communicator
! mreal = default datatype for reals
! local data
integer :: j, nx1, ks, moff, kl, kr
integer :: msid, ierr
integer, dimension(lstat) :: istatus
nx1 = nx + 1
! special case for one processor
if (nvp==1) return
ks = kstrt - 1
moff = nypmx*nvp + 1
! add guard cells
kr = ks + 1
kl = ks - 1
ks = nyp + 1
! this segment is used for mpi computers
if (kl >= 0) then
call MPI_IRECV(scr,nxv,mreal,kl,moff,lgrp,msid,ierr)
endif
if (kr < nvp) then
call MPI_SEND(f(1,ks),nxv,mreal,kr,moff,lgrp,ierr)
do j = 1, nx1
f(j,ks) = 0.0
enddo
endif
if (kl >= 0) then
call MPI_WAIT(msid,istatus,ierr)
! add up the guard cells
do j = 1, nx1
f(j,1) = f(j,1) + scr(j)
enddo
endif
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPWRVNDATA2(f,g,ndim,nxv,nyp,nypmx,iunit)
! this subroutine collects distributed periodic real 2d vector
! non-uniform data f and writes to a fortran unformatted file
! f = input data to be written
! g = scratch data
! ndim = first dimension of data array f
! nyp = actual data written for third dimension
! nxv = second dimension of data array f
! nypmx = third dimension of data array f
! iunit = fortran unit number
! input: all
implicit none
integer, intent(in) :: ndim, nxv, nyp, nypmx, iunit
real, intent(in), dimension(ndim,nxv,nyp) :: f
real, intent(inout), dimension(ndim,nxv,nypmx) :: g
! lgrp = current communicator
! mint = default datatype for integers
! mreal = default datatype for reals
! local data
integer :: nvp, idproc, nps, nnxv, nnyp, nnypx, id, i, j, k, n
integer :: msid, ierr
integer, dimension(lstat) :: istatus
nnxv = ndim*nxv
nnyp = nnxv*nyp
nnypx = nnxv*nypmx
! this segment is used for shared memory computers
! write (unit=iunit) (((f(n,j,k),n=1,ndim),j=1,nxv),k=1,nyp)
! this segment is used for mpi computers
! determine the rank of the calling process in the communicator
call MPI_COMM_RANK(lgrp,idproc,ierr)
! determine the size of the group associated with a communicator
call MPI_COMM_SIZE(lgrp,nvp,ierr)
! node 0 receives messages from other nodes
if (idproc==0) then
! first write data for node 0
write (unit=iunit) (((f(n,j,k),n=1,ndim),j=1,nxv),k=1,nyp)
! then write data from remaining nodes
do i = 2, nvp
id = i - 1
call MPI_IRECV(g,nnypx,mreal,id,99,lgrp,msid,ierr)
call MPI_WAIT(msid,istatus,ierr)
call MPI_GET_COUNT(istatus,mreal,nps,ierr)
nps = nps/nnxv
write (unit=iunit) (((g(n,j,k),n=1,ndim),j=1,nxv),k=1,nps)
enddo
! other nodes send data to node 0
else
call MPI_SEND(f,nnyp,mreal,0,99,lgrp,ierr)
endif
end subroutine
!
end module
!
! Make functions callable by Fortran77
!
!-----------------------------------------------------------------------
subroutine PPINIT2(idproc,nvp)
use pplib2, only: SUB => PPINIT2
implicit none
integer, intent(inout) :: idproc, nvp
call SUB(idproc,nvp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPEXIT
use pplib2, only: SUB => PPEXIT
implicit none
call SUB()
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPABORT
use pplib2, only: SUB => PPABORT
implicit none
call SUB()
end subroutine
!
!-----------------------------------------------------------------------
subroutine PWTIMERA(icntrl,time,dtime)
use pplib2, only: SUB => PWTIMERA
implicit none
integer, intent(in) :: icntrl
real, intent(inout) :: time
double precision, intent(inout) :: dtime
call SUB(icntrl,time,dtime)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPSUM(f,g,nxp)
use pplib2, only: SUB => PPSUM
implicit none
integer, intent(in) :: nxp
real, dimension(nxp), intent(inout) :: f, g
call SUB(f,g,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDSUM(f,g,nxp)
use pplib2, only: SUB => PPDSUM
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
call SUB(f,g,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPMAX(f,g,nxp)
use pplib2, only: SUB => PPMAX
implicit none
integer, intent(in) :: nxp
real, dimension(nxp), intent(inout) :: f, g
call SUB(f,g,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPIMAX(if,ig,nxp)
use pplib2, only: SUB => PPIMAX
implicit none
integer, intent(in) :: nxp
integer, dimension(nxp), intent(inout) :: if, ig
call SUB(if,ig,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDMAX(f,g,nxp)
use pplib2, only: SUB => PPDMAX
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
call SUB(f,g,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPDSCAN(f,g,nxp)
use pplib2, only: SUB => PPDSCAN
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f, g
call SUB(f,g,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPBICAST(if,nxp)
use pplib2, only: SUB => PPBICAST
implicit none
integer, intent(in) :: nxp
integer, dimension(nxp), intent(inout) :: if
call SUB(if,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPBDCAST(f,nxp)
use pplib2, only: SUB => PPBDCAST
implicit none
integer, intent(in) :: nxp
double precision, dimension(nxp), intent(inout) :: f
call SUB(f,nxp)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPNLCGUARD2L(f,nyp,kstrt,nvp,nxv,nypmx)
use pplib2, only: SUB => PPNLCGUARD2L
implicit none
integer, intent(in) :: nyp, kstrt, nvp, nxv, nypmx
real, dimension(nxv,nypmx), intent(inout) :: f
call SUB(f,nyp,kstrt,nvp,nxv,nypmx)
end subroutine
!
subroutine PPNLAGUARD2L(f,scr,nyp,nx,kstrt,nvp,nxv,nypmx)
use pplib2, only: SUB => PPNLAGUARD2L
implicit none
integer, intent(in) :: nyp, kstrt, nvp, nx, nxv, nypmx
real, dimension(nxv,nypmx), intent(inout) :: f
real, dimension(nxv), intent(inout) :: scr
call SUB(f,scr,nyp,nx,kstrt,nvp,nxv,nypmx)
end subroutine
!
!-----------------------------------------------------------------------
subroutine PPWRVNDATA2(f,g,ndim,nxv,nyp,nypmx,iunit)
use pplib2, only: SUB => PPWRVNDATA2
implicit none
integer, intent(in) :: ndim, nxv, nyp, nypmx, iunit
real, intent(in), dimension(ndim,nxv,nyp) :: f
real, intent(inout), dimension(ndim,nxv,nypmx) :: g
call SUB(f,g,ndim,nxv,nyp,nypmx,iunit)
end subroutine
!