*IF DEF,C84_1A STZONM1A.2
C ******************************COPYRIGHT****************************** GTS2F400.9811
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.9812
C GTS2F400.9813
C Use, duplication or disclosure of this code is subject to the GTS2F400.9814
C restrictions as set forth in the contract. GTS2F400.9815
C GTS2F400.9816
C Meteorological Office GTS2F400.9817
C London Road GTS2F400.9818
C BRACKNELL GTS2F400.9819
C Berkshire UK GTS2F400.9820
C RG12 2SZ GTS2F400.9821
C GTS2F400.9822
C If no contract has been raised with this copy of the code, the use, GTS2F400.9823
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.9824
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.9825
C Modelling at the above address. GTS2F400.9826
C ******************************COPYRIGHT****************************** GTS2F400.9827
C GTS2F400.9828
CLL Routine: STZONM --------------------------------------------------- STZONM1A.3
CLL STZONM1A.4
CLL Purpose: Calculate weighted zonal mean within a region specified STZONM1A.5
CLL by a lower left hand and upper right hand corner. STZONM1A.6
CLL (STASH service routine). STZONM1A.7
CLL STZONM1A.8
CLL Tested under compiler: cft77 STZONM1A.9
CLL Tested under OS version: UNICOS 5.1 STZONM1A.10
CLL STZONM1A.11
CLL Author: T.Johns/S.Tett STZONM1A.12
CLL STZONM1A.13
CLL Model Modification history from model version 3.0: STZONM1A.14
CLL version date STZONM1A.15
CLL 3.3 16/09/93 Allow level-by-level mass-weighting if mass-weights TJ170993.152
CLL are so defined, otherwise use P*. TJ170993.153
!LL 4.3 15/01/97 Moved weighting and masking calculations up to GPB0F403.2172
!LL SPATIAL. GPB0F403.2173
!LL Significantly rewritten for MPP mode - zonal GPB0F403.2174
!LL data must be gathered to a processor for GPB0F403.2175
!LL reproducible sums to be calculated. P.Burton GPB0F403.2176
!LL 4.4 13/06/97 MPP: Set fieldout to zero for processors in GPB0F404.301
!LL subdomain area which will not otherwise GPB0F404.302
!LL receive the result of the zonal mean. P.Burton GPB0F404.303
!LL 4.5 12/01/98 Replaced usage of shmem common block by a GPB2F405.293
!LL dynamic array. P.Burton GPB2F405.294
CLL STZONM1A.16
CLL Programming standard: UM Doc Paper 3, version 2 (7/9/90) STZONM1A.17
CLL STZONM1A.18
CLL Logical components covered: D713 STZONM1A.19
CLL STZONM1A.20
CLL Project task: D7 STZONM1A.21
CLL STZONM1A.22
CLL External documentation: STZONM1A.23
CLL Unified Model Doc Paper C4 - Storage handling and diagnostic STZONM1A.24
CLL system (STASH) STZONM1A.25
CLL STZONM1A.26
C*L Interface and arguments: ------------------------------------------ STZONM1A.27
C STZONM1A.28
SUBROUTINE STZONM(fieldin,vx,vy,st_grid,gr,lwrap,lmasswt, 1,6GPB0F403.2177
& xstart,ystart,xend,yend, STZONM1A.30
*IF DEF,MPP GPB0F403.2178
& global_xstart,global_ystart, GPB0F403.2179
& global_xend,global_yend, GPB0F403.2180
*ENDIF GPB0F403.2181
& fieldout, STZONM1A.31
& pstar_weight,delta_ak,delta_bk, GPB0F403.2182
& area_weight,mask, GPB0F403.2183
& row_length,p_rows, GPB0F403.2184
& level_code,mask_code,weight_code,rmdi, STZONM1A.35
& icode,cmessage) STZONM1A.36
C STZONM1A.37
IMPLICIT NONE STZONM1A.38
C STZONM1A.39
INTEGER STZONM1A.40
& vx,vy, ! IN input field size STZONM1A.41
& st_grid, ! IN STASH grdtype code STZONM1A.42
& gr, ! IN input fld grid GPB0F403.2185
& xstart,ystart, ! IN lower LH corner STZONM1A.43
& xend,yend, ! IN upper RH corner STZONM1A.44
*IF DEF,MPP GPB0F403.2186
& global_xstart,global_ystart, ! IN global versions of GPB0F403.2187
& global_xend, global_yend, ! IN xstart etc. GPB0F403.2188
*ENDIF GPB0F403.2189
& row_length,p_rows, ! IN primary dimensions GPB0F403.2190
& level_code, ! IN input level code STZONM1A.46
& mask_code, ! IN masking code STZONM1A.47
& weight_code, ! IN weighting code STZONM1A.48
& icode ! OUT error return code STZONM1A.49
CHARACTER*(*) STZONM1A.50
& cmessage ! OUT error return msg STZONM1A.51
LOGICAL STZONM1A.52
& lwrap, ! IN TRUE if wraparound STZONM1A.53
& lmasswt, ! IN TRUE if masswts OK TJ170993.155
& mask(row_length,p_rows) ! IN mask array GPB0F403.2191
REAL STZONM1A.55
& fieldin(vx,vy), ! IN input field STZONM1A.56
& fieldout(ystart:yend), ! OUT output field STZONM1A.57
& pstar_weight(row_length,p_rows), ! IN pstar mass weight GPB0F403.2192
& delta_ak, ! IN hybrid coordinates STZONM1A.60
& delta_bk, ! IN hybrid coordinates STZONM1A.61
& area_weight(row_length,p_rows), ! IN area weighting GPB0F403.2193
! (already interpolated to the correct grid and GPB0F403.2194
! set to 1.0 where no area weighting is required) GPB0F403.2195
& rmdi ! IN missing data indic STZONM1A.64
C*---------------------------------------------------------------------- STZONM1A.65
C STZONM1A.66
C External subroutines called STZONM1A.67
C STZONM1A.68
C STZONM1A.70
*CALL STPARAM
STZONM1A.71
*CALL STERR
STZONM1A.72
C STZONM1A.73
C Local variables STZONM1A.74
C STZONM1A.75
INTEGER i,ii,j ! ARRAY INDICES FOR VARIABLE STZONM1A.76
STZONM1A.77
*IF DEF,MPP GPB0F403.2196
GPB0F403.2197
*CALL PARVARS
GPB0F403.2198
GPB0F403.2199
INTEGER GPB0F403.2200
GPB0F403.2201
*IF DEF,REPROD GPB0F403.2202
! Processor co-ordinates of processors at the corners of the GPB0F403.2203
! processed subdomain GPB0F403.2204
& proc_top_left_x,proc_top_left_y GPB0F403.2205
&, proc_bot_right_x,proc_bot_right_y GPB0F403.2206
GPB0F403.2207
! size of the full subarea in GPB0F403.2208
&, zonal_sum_global_len_x GPB0F403.2209
GPB0F403.2210
! loop variables for loops over processors in subdomain GPB0F403.2211
&, proc_x,proc_y GPB0F403.2212
GPB0F403.2213
! real processor x co-ordinate - when proc_x > nproc_x is just GPB0F403.2214
! proc_x-nproc_x GPB0F403.2215
&, eff_proc_x GPB0F403.2216
GPB0F403.2217
! processor id of processor (proc_x,proc_y) GPB0F403.2218
&, proc_id GPB0F403.2219
GPB0F403.2220
! definition of the extracted subarea array on processor proc_id GPB0F403.2221
&, local_array_top_left_x,local_array_top_left_y GPB0F403.2222
&, local_array_bot_right_x,local_array_bot_right_y GPB0F403.2223
GPB0F403.2224
! definition of the real data contained within the extracted GPB0F403.2225
! subarea on processor proc_id (ie. not including halos) GPB0F403.2226
&, local_data_top_left_x,local_data_top_left_y GPB0F403.2227
&, local_data_bot_right_x,local_data_bot_right_y GPB0F403.2228
GPB0F403.2229
! size in the x dimension of the subarea array on proc_id GPB0F403.2230
&, local_array_size_x GPB0F403.2231
GPB0F403.2232
! length of (partial) local zonal data to be sent GPB0F403.2233
&, local_send_size_x GPB0F403.2234
GPB0F403.2235
! offset of data to be sent from start of local row GPB0F403.2236
&, local_send_off_x GPB0F403.2237
GPB0F403.2238
! position in the full zonal row of (partial) data to be sent GPB0F403.2239
&, pos_in_zonal_array GPB0F403.2240
GPB0F403.2241
! number of (partial) zonal mean rows on processor proc_id GPB0F403.2242
&, local_n_rows_to_send GPB0F403.2243
GPB0F403.2244
! the first (partial) zonal mean row to be sent from proc_id GPB0F403.2245
&, local_send_off_y GPB0F403.2246
GPB0F403.2247
! the global zonal mean number of the first local (partial) zonal GPB0F403.2248
! mean row to be sent from proc_id GPB0F403.2249
&, global_zonal_row_number_start GPB0F403.2250
GPB0F403.2251
! loop counter for loop over rows to send GPB0F403.2252
&, row GPB0F403.2253
GPB0F403.2254
! index of row in proc_id's array of local data GPB0F403.2255
&, local_row GPB0F403.2256
GPB0F403.2257
! global zonal row number of a row GPB0F403.2258
&, global_zonal_row_id GPB0F403.2259
GPB0F403.2260
! processor which this zonal mean row will be sent to GPB0F403.2261
&, dest_proc GPB0F403.2262
GPB0F403.2263
! row number on the destination processor GPB0F403.2264
&, work_dest_row_id GPB0F403.2265
GPB0F403.2266
! number of items of zonal data to send and receive GPB0F403.2267
&, n_send_data , n_rec_data GPB0F403.2268
GPB0F403.2269
! number of final zonal means to send and receive GPB0F403.2270
&, n_send_means , n_rec_means GPB0F403.2271
GPB0F403.2272
! number of rows of (full) zonal data on this processor GPB0F403.2273
&, n_rows_full_zonal_data GPB0F403.2274
GPB0F403.2275
! size of local_sum_arrays and global_sum_arrays GPB0F403.2276
&, local_sum_array_len GPB0F403.2277
&, global_sum_array_len GPB0F403.2278
GPB0F403.2279
! field type (P or U) of input field GPB0F403.2280
&, fld_type GPB0F403.2281
GPB0F403.2282
! arguments for GCOM routines GPB0F403.2283
&, flag , info GPB0F403.2284
GPB0F403.2285
! dummy variables (unused return values from subroutine calls) GPB0F403.2286
&, dummy1,dummy2 GPB0F403.2287
*ELSE GPB0F403.2288
! size of subarea on this processor, not including halo areas GPB0F403.2289
& local_sum_xstart,local_sum_xend GPB0F403.2290
&, local_sum_ystart,local_sum_yend GPB0F403.2291
GPB0F403.2292
! number of rows of zonal data to sum on this processor GPB0F403.2293
! (yend-ystart+1) GPB0F403.2294
&, partial_sum_data_sizey GPB0F403.2295
GPB0F403.2296
! return code from GCOM routines GPB0F403.2297
&, info GPB0F403.2298
*ENDIF GPB0F403.2299
GPB0F403.2300
GPB0F403.2302
*IF DEF,REPROD GPB0F403.2303
LOGICAL GPB0F403.2304
GPB0F403.2305
! indicates if the subarea requested for zonal meaning wraps over GPB0F403.2306
! zero longitude GPB0F403.2307
& lwrap_zonal_mean GPB0F403.2308
GPB0F403.2309
! indicates if the subdomain contains processors which hold both GPB0F403.2310
! the start and end of the subdomain, which wraps over zero GPB0F403.2311
! longitude GPB0F403.2312
&, lwrap_proc GPB0F403.2313
GPB0F403.2314
! indicates that a full field is being zonal meaned GPB0F403.2315
&, fullfield GPB0F403.2316
GPB0F403.2317
REAL GPB0F403.2318
! temporary variables used in calculation of zonal means GPB0F403.2319
& zonal_sum_top,zonal_sum_bot GPB0F403.2320
GPB0F403.2321
INTEGER GPB0F403.2322
GPB0F403.2323
! Send/receive maps for zonal data arrays to be summed GPB0F403.2324
& send_data_map(7,2*(yend-ystart+1)) GPB0F403.2325
&, rec_data_map(7,2*(global_yend-global_ystart+1)*nproc) GPB2F405.295
GPB0F403.2327
! send/receive maps for zonal means GPB0F403.2328
&, send_means_map(7,2*(global_yend-global_ystart+1)) GPB0F403.2329
&, rec_means_map(7,2*(yend-ystart+1)) GPB0F403.2330
GPB0F403.2331
! Weighted version of fieldin GPB0F403.2332
REAL local_sum_array_top(xstart:xend,ystart:yend) GPB0F403.2333
! Weights applied to fieldin GPB0F403.2334
REAL local_sum_array_bot(xstart:xend,ystart:yend) GPB0F403.2335
*ENDIF GPB0F403.2336
GPB0F403.2337
GPB0F403.2339
*IF DEF,REPROD GPB0F403.2340
INTEGER GPB0F403.2341
! Sizes of the global_sum_arrays defined below GPB2F405.296
& global_sum_array_sizex,global_sum_array_sizey GPB0F403.2345
GPB0F403.2346
REAL GPB0F403.2355
! Collected versions of fieldin and the weights containing GPB0F403.2356
! whole (subarea) rows of zonal data GPB0F403.2357
& global_sum_array_top(global_xstart:global_xend, GPB2F405.297
& global_yend-global_ystart+1) GPB2F405.298
&, global_sum_array_bot(global_xstart:global_xend, GPB2F405.299
& global_yend-global_ystart+1) GPB2F405.300
GPB0F403.2362
! Calculated zonal means on the calculating processor GPB0F403.2363
&, zonal_mean_array(global_yend-global_ystart+1) GPB2F405.301
GPB0F403.2365
*ELSE GPB0F403.2378
INTEGER GPB0F403.2379
! Size of local partial sum arrays defined below GPB2F405.302
& partial_sum_array_sizey GPB0F403.2383
GPB0F403.2384
REAL GPB0F403.2391
! Partial zonal sums of subarea rows GPB0F403.2392
& partial_SUMZTOP(vy*2) GPB2F405.303
&, partial_SUMZBOT(vy*2) GPB2F405.304
GPB0F403.2395
*ENDIF GPB0F403.2406
GPB0F403.2407
*IF DEF,REPROD GPB0F403.2408
GPB0F403.2409
! Integer function used for obtaining field type GPB0F403.2410
INTEGER GET_FLD_TYPE GPB0F403.2411
GPB0F403.2412
*ENDIF GPB0F403.2413
GPB0F403.2414
*CALL GCCOM
GPB0F403.2415
GPB0F403.2416
*ENDIF GPB0F403.2417
REAL SUMZTOP(ystart:yend) STZONM1A.80
REAL SUMZBOT(ystart:yend) STZONM1A.81
STZONM1A.82
CL---------------------------------------------------------------------- STZONM1A.83
CL 0. Initialise sums STZONM1A.84
CL STZONM1A.85
CFPP$ NOINNER R STZONM1A.86
DO j=ystart,yend STZONM1A.87
SUMZTOP(j)=0.0 STZONM1A.88
SUMZBOT(j)=0.0 STZONM1A.89
ENDDO STZONM1A.90
CL---------------------------------------------------------------------- STZONM1A.91
GPB0F403.2418
! pstar_weight and area_weight arrays contain appropriate GPB0F403.2419
! weighting factors, interpolated to the correct grid, for GPB0F403.2420
! mass weighting and area weighting respectively. If either type GPB0F403.2421
! of weighting is not required, the relevant array is set to 1.0 GPB0F403.2422
! The mask array contains appropriate masking GPB0F403.2423
GPB0F403.2424
*IF -DEF,MPP,OR,DEF,REPROD GPB0F403.2425
*IF -DEF,MPP GPB0F403.2426
! Sum up weighted versions of fieldin array GPB0F403.2427
*ELSE GPB0F403.2428
! Create arrays of weighted data suitable to be summed GPB0F403.2429
*ENDIF GPB0F403.2430
GPB0F403.2431
*IF DEF,MPP GPB0F403.2432
! Only do the calculations if some of the subarea is contained GPB0F403.2433
! within this processor GPB0F403.2434
IF ((xstart .NE. st_no_data) .AND. (xend .NE. st_no_data) .AND. GPB0F403.2435
& (ystart .NE. st_no_data) .AND. (yend .NE. st_no_data)) THEN GPB0F403.2436
GPB0F403.2437
*ENDIF GPB0F403.2438
DO i=xstart,xend GPB0F403.2439
*IF -DEF,MPP GPB0F403.2440
IF (lwrap) THEN GPB0F403.2441
ii=1+MOD(i-1,vx) GPB0F403.2442
ELSE GPB0F403.2443
ii=i GPB0F403.2444
ENDIF GPB0F403.2445
*ELSE GPB0F403.2446
IF ( lwrap .AND. (i .GT. (lasize(1)-Offx))) THEN GPB0F403.2447
ii=i-lasize(1)+2*Offx ! miss halos on wrap around GPB0F403.2448
ELSE GPB0F403.2449
ii=i GPB0F403.2450
ENDIF GPB0F403.2451
*ENDIF GPB0F403.2452
DO j=ystart,yend GPB0F403.2453
IF (mask(ii,j)) THEN GPB0F403.2454
IF (.NOT. lmasswt) THEN GPB0F403.2455
*IF -DEF,MPP GPB0F403.2456
SUMZBOT(j)=SUMZBOT(j)+ GPB0F403.2457
& pstar_weight(ii,j) GPB0F403.2458
SUMZTOP(j)=SUMZTOP(j)+ GPB0F403.2459
& fieldin(ii,j)*pstar_weight(ii,j) GPB0F403.2460
*ELSE GPB0F403.2461
local_sum_array_bot(i,j)= GPB0F403.2462
& pstar_weight(ii,j) GPB0F403.2463
local_sum_array_top(i,j)= GPB0F403.2464
& fieldin(ii,j)*pstar_weight(ii,j) GPB0F403.2465
*ENDIF GPB0F403.2466
ELSE GPB0F403.2467
*IF -DEF,MPP GPB0F403.2468
SUMZBOT(j)=SUMZBOT(j)- GPB0F403.2469
& (delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2470
SUMZTOP(j)=SUMZTOP(j)-fieldin(ii,j)* GPB0F403.2471
& (delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2472
*ELSE GPB0F403.2473
local_sum_array_bot(i,j)= GPB0F403.2474
& -1.0*(delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2475
local_sum_array_top(i,j)= GPB0F403.2476
& -1.0*fieldin(ii,j)* GPB0F403.2477
& (delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2478
*ENDIF GPB0F403.2479
ENDIF GPB0F403.2480
*IF -DEF,MPP GPB0F403.2481
ENDIF GPB0F403.2482
*ELSE GPB0F403.2483
ELSE STZONM1A.102
local_sum_array_bot(i,j)=0.0 GPB0F403.2484
local_sum_array_top(i,j)=0.0 GPB0F403.2485
ENDIF STZONM1A.104
*ENDIF GPB0F403.2486
ENDDO GPB0F403.2487
ENDDO GPB0F403.2488
GPB0F403.2489
*IF DEF,MPP GPB0F403.2490
ENDIF ! if this processor contains any of the subarea GPB0F403.2491
*ENDIF GPB0F403.2492
GPB0F403.2493
*IF -DEF,MPP GPB0F403.2494
GPB0F403.2495
DO j=ystart,yend STZONM1A.443
IF (SUMZBOT(j) .EQ. 0.0) THEN GPB0F403.2496
fieldout(j)=rmdi STZONM1A.445
ELSE STZONM1A.446
fieldout(j)=SUMZTOP(j)/SUMZBOT(j) STZONM1A.447
ENDIF STZONM1A.448
ENDDO STZONM1A.449
GPB0F403.2497
*ELSE GPB0F403.2498
GPB0F404.304
! Initialise fieldout array - so all PE's have valid data GPB0F404.305
! (Only PEs on left of subdomain get the zonal means) GPB0F404.306
DO i=ystart,yend GPB0F404.307
fieldout(i)=0.0 GPB0F404.308
ENDDO GPB0F404.309
GPB0F403.2499
! The local_sum_arrays must be distributed so that complete GPB0F403.2500
! sub-area rows exist on processors, so that a reproducible sum GPB0F403.2501
! can be carried out. GPB0F403.2502
! The following code calculates where the local_sum_array data GPB0F403.2503
! must be sent to, and where the final answers must be sent back to GPB0F403.2504
GPB0F403.2505
! 0.0 : Initialise variables defining the size of the arrays GPB0F403.2506
! global_sum_arrays GPB0F403.2507
GPB0F403.2508
global_sum_array_sizex=global_xend-global_xstart+1 GPB2F405.305
global_sum_array_sizey=global_yend-global_ystart+1 GPB2F405.306
GPB0F403.2512
local_sum_array_len=((xend-xstart)+1)*((yend-ystart)+1) GPB0F403.2513
global_sum_array_len=global_sum_array_sizex* GPB0F403.2514
& global_sum_array_sizey GPB0F403.2515
GPB0F403.2516
! Set a logicial indicating if the area being meaned is the GPB0F403.2517
! full field GPB0F403.2518
GPB0F403.2519
fld_type=GET_FLD_TYPE
(gr) GPB0F403.2520
GPB0F403.2521
fullfield= ((( global_xstart .EQ. 1) .AND. GPB0F403.2522
& ( global_xend) .EQ. glsize(1)) .AND. GPB0F403.2523
& ( global_ystart .EQ. 1) .AND. GPB0F403.2524
& (((fld_type .EQ. fld_type_p) .AND. GPB0F403.2525
& (global_yend .EQ. glsize(2))) .OR. GPB0F403.2526
& ((fld_type .EQ. fld_type_u) .AND. GPB0F403.2527
& (global_yend .EQ. glsize(2)-1)))) GPB0F403.2528
GPB0F403.2529
! Calculate the length of the full zonal subarea GPB0F403.2530
GPB0F403.2531
zonal_sum_global_len_x=global_xend-global_xstart+1 GPB0F403.2532
GPB0F403.2533
! 1.0 Find the set of processors covering the requested sub-area GPB0F403.2534
GPB0F403.2535
CALL GLOBAL_TO_LOCAL_RC
(gr, GPB0F403.2536
& global_xstart , global_ystart, GPB0F403.2537
& proc_top_left_x, proc_top_left_y, GPB0F403.2538
& dummy1,dummy2) GPB0F403.2539
GPB0F403.2540
CALL GLOBAL_TO_LOCAL_RC
(gr, GPB0F403.2541
& global_xend,global_yend, GPB0F403.2542
& proc_bot_right_x, proc_bot_right_y, GPB0F403.2543
& dummy1,dummy2) GPB0F403.2544
GPB0F403.2545
! Set a logical to indicate if the zonal mean area required GPB0F403.2546
! wraps over zero longitude GPB0F403.2547
GPB0F403.2548
lwrap_zonal_mean= GPB0F403.2549
& ((global_xend .GT. glsize(1)) .OR. GPB0F403.2550
& (global_xend .LT. global_xstart)) GPB0F403.2551
GPB0F403.2552
! If there is a wrap around over 0 longitude, ensure that GPB0F403.2553
! proc_bot_right_x > proc_top_left_x GPB0F403.2554
GPB0F403.2555
IF (lwrap_zonal_mean) GPB0F403.2556
& proc_bot_right_x=proc_bot_right_x+nproc_x GPB0F403.2557
GPB0F403.2558
! Set up a logical to indicate if a processor in the subdomain GPB0F403.2559
! contains both the start and end of a zonal mean which wraps over GPB0F403.2560
! zero longitude. If TRUE, some extra work is required at this GPB0F403.2561
! processor as it contains data for two non-contiguous parts GPB0F403.2562
! of the zonal mean GPB0F403.2563
GPB0F403.2564
lwrap_proc=(proc_bot_right_x .EQ. proc_top_left_x+nproc_x) GPB0F403.2565
GPB0F403.2566
! 2.0 Loop over all the processors in the subdomain, and set GPB0F403.2567
! up the send/receive maps defining the redistribution GPB0F403.2568
! of data GPB0F403.2569
GPB0F403.2570
n_send_data=0 ! number of items of data to send GPB0F403.2571
n_rec_data=0 ! number of items of data to receive GPB0F403.2572
n_send_means=0 ! number of zonal means I will send GPB0F403.2573
n_rec_means=0 ! number of zonal means I will receive GPB0F403.2574
n_rows_full_zonal_data=0 ! number of rows of data I will mean GPB0F403.2575
GPB0F403.2576
DO proc_y=proc_top_left_y , proc_bot_right_y GPB0F403.2577
GPB0F403.2578
DO proc_x=proc_top_left_x , proc_bot_right_x GPB0F403.2579
GPB0F403.2580
eff_proc_x=MOD(proc_x,nproc_x) GPB0F403.2581
proc_id=eff_proc_x+proc_y*nproc_x GPB0F403.2582
GPB0F403.2583
! 2.1 Find the size of the array containing the zonal arrays on GPB0F403.2584
! processor proc_id GPB0F403.2585
GPB0F403.2586
CALL GLOBAL_TO_LOCAL_SUBDOMAIN
(.TRUE.,.TRUE., GPB0F403.2587
& gr,proc_id, GPB0F403.2588
& global_ystart,global_xend, GPB0F403.2589
& global_yend,global_xstart, GPB0F403.2590
& local_array_top_left_y,local_array_bot_right_x, GPB0F403.2591
& local_array_bot_right_y,local_array_top_left_x) GPB0F403.2592
GPB0F403.2593
! 2.2 Using this information, calculate the size of this array in GPB0F403.2594
! the x dimension. If the data is wrapped round, the calculation GPB0F403.2595
! is done differently: GPB0F403.2596
GPB0F403.2597
IF (local_array_top_left_x .LE. local_array_bot_right_x) GPB0F403.2598
& THEN GPB0F403.2599
local_array_size_x= GPB0F403.2600
& local_array_bot_right_x-local_array_top_left_x+1 GPB0F403.2601
ELSE ! wrap around GPB0F403.2602
local_array_size_x= GPB0F403.2603
& local_array_bot_right_x-local_array_top_left_x+1+ GPB0F403.2604
& g_lasize(1,proc_id)-2*Offx GPB0F403.2605
ENDIF GPB0F403.2606
GPB0F403.2607
! 2.3 Find out the size of the actual zonal mean data within the GPB0F403.2608
! subarea array on processor proc_id GPB0F403.2609
GPB0F403.2610
CALL GLOBAL_TO_LOCAL_SUBDOMAIN
(.FALSE.,.FALSE., GPB0F403.2611
& gr,proc_id, GPB0F403.2612
& global_ystart,global_xend, GPB0F403.2613
& global_yend,global_xstart, GPB0F403.2614
& local_data_top_left_y,local_data_bot_right_x, GPB0F403.2615
& local_data_bot_right_y,local_data_top_left_x) GPB0F403.2616
GPB0F403.2617
! 2.4 Calculate various quantities, which require different GPB0F403.2618
! calculations depending on if LWRAP_PROC is .TRUE., GPB0F403.2619
! and if so, if this processor contains both start and GPB0F403.2620
! end of the zonal data GPB0F403.2621
! local_send_size_x : the length of data to be sent GPB0F403.2622
! local_send_off_x : the offset of this data from the GPB0F403.2623
! start of row GPB0F403.2624
! pos_in_zonal_array : position of this data in the full GPB0F403.2625
! zonal array GPB0F403.2626
GPB0F403.2627
IF ((LWRAP_PROC) .AND. (proc_x .EQ. proc_top_left_x)) THEN GPB0F403.2628
! Processor containing start and end of zonal mean - but here GPB0F403.2629
! we're interested only in the start segment GPB0F403.2630
GPB0F403.2631
local_send_size_x= GPB0F403.2632
& g_lasize(1,proc_id)-local_data_top_left_x-Offx+1 GPB0F403.2633
local_send_off_x= GPB0F403.2634
& local_data_top_left_x-local_array_top_left_x GPB0F403.2635
pos_in_zonal_array= GPB0F403.2636
& g_datastart(1,proc_id)+local_data_top_left_x-Offx- GPB0F403.2637
& global_xstart GPB0F403.2638
GPB0F403.2639
ELSEIF ((LWRAP_PROC) .AND. GPB0F403.2640
& (proc_x .EQ. proc_bot_right_x)) THEN GPB0F403.2641
! Processor containing start and end of zonal mean - but here GPB0F403.2642
! we're interested only in the end segment GPB0F403.2643
GPB0F403.2644
local_send_size_x=local_data_bot_right_x-Offx GPB0F403.2645
local_send_off_x=local_array_size_x-local_send_size_x GPB0F403.2646
pos_in_zonal_array= GPB0F403.2647
& zonal_sum_global_len_x-local_send_size_x+1 GPB0F403.2648
GPB0F403.2649
ELSE GPB0F403.2650
! all other processors GPB0F403.2651
GPB0F403.2652
local_send_size_x= GPB0F403.2653
& local_data_bot_right_x-local_data_top_left_x+1 GPB0F403.2654
local_send_off_x= GPB0F403.2655
& local_data_top_left_x-local_array_top_left_x GPB0F403.2656
pos_in_zonal_array= GPB0F403.2657
& g_datastart(1,proc_id)+local_data_top_left_x-Offx- GPB0F403.2658
& global_xstart GPB0F403.2659
GPB0F403.2660
ENDIF GPB0F403.2661
GPB0F403.2662
IF (pos_in_zonal_array .LT. 1) THEN GPB0F403.2663
! This means the sub-area wraps over zero longitude - so to get GPB0F403.2664
! the correct position in the array we add the global row length GPB0F403.2665
pos_in_zonal_array=pos_in_zonal_array+glsize(1) GPB0F403.2666
ENDIF GPB0F403.2667
GPB0F403.2668
! 2.5 Find the number of zonal mean rows to be sent from this GPB0F403.2669
! processor GPB0F403.2670
GPB0F403.2671
local_n_rows_to_send= GPB0F403.2672
& local_data_bot_right_y-local_data_top_left_y+1 GPB0F403.2673
GPB0F403.2674
! 2.6 and the first row to be sent from this processor GPB0F403.2675
GPB0F403.2676
local_send_off_y= GPB0F403.2677
& local_data_top_left_y-local_array_top_left_y GPB0F403.2678
GPB0F403.2679
! 2.7 Calculate which global zonal mean is the first one to GPB0F403.2680
! send from this processor GPB0F403.2681
GPB0F403.2682
global_zonal_row_number_start= GPB0F403.2683
& g_datastart(2,proc_id)+local_data_top_left_y-Offy- GPB0F403.2684
& global_ystart GPB0F403.2685
GPB0F403.2686
! 2.8 Loop over rows and construct send/receive maps GPB0F403.2687
GPB0F403.2688
DO row=1,local_n_rows_to_send GPB0F403.2689
GPB0F403.2690
! 2.8.1 Find the local_row index on proc_id, and the global zonal GPB0F403.2691
! row index of this row GPB0F403.2692
GPB0F403.2693
local_row=row+local_send_off_y GPB0F403.2694
global_zonal_row_id=global_zonal_row_number_start+row-1 GPB0F403.2695
GPB0F403.2696
! 2.8.2 and find the destination processor of this row, and GPB0F403.2697
! where on this processor it will be sent to GPB0F403.2698
GPB0F403.2699
dest_proc=MOD(global_zonal_row_id-1,nproc) GPB0F403.2700
work_dest_row_id=((global_zonal_row_id-1)/nproc)+1 GPB0F403.2701
GPB0F403.2702
! 2.8.3 If this processor is proc_id construct a send_data_map GPB0F403.2703
! entry for this row of data GPB0F403.2704
GPB0F403.2705
IF (mype .EQ. proc_id) THEN GPB0F403.2706
GPB0F403.2707
n_send_data = n_send_data+1 GPB0F403.2708
GPB0F403.2709
send_data_map(S_DESTINATION_PE,n_send_data)= GPB0F403.2710
& dest_proc GPB0F403.2711
send_data_map(S_BASE_ADDRESS_IN_SEND_ARRAY, GPB0F403.2712
& n_send_data)= GPB0F403.2713
& (local_row-1)*local_array_size_x + GPB0F403.2714
& local_send_off_x+1 GPB0F403.2715
send_data_map(S_NUMBER_OF_ELEMENTS_IN_ITEM, GPB0F403.2716
& n_send_data)=1 GPB0F403.2717
send_data_map(S_STRIDE_IN_SEND_ARRAY,n_send_data)=1 GPB0F403.2718
send_data_map(S_ELEMENT_LENGTH,n_send_data)= GPB0F403.2719
& local_send_size_x GPB0F403.2720
send_data_map(S_BASE_ADDRESS_IN_RECV_ARRAY, GPB0F403.2721
& n_send_data)= GPB0F403.2722
& (work_dest_row_id-1)*global_sum_array_sizex + GPB0F403.2723
& pos_in_zonal_array GPB0F403.2724
send_data_map(S_STRIDE_IN_RECV_ARRAY,n_send_data)=1 GPB0F403.2725
GPB0F403.2726
! 2.8.3.1 If this processor is on LHS of the subarea, then it is GPB0F403.2727
! responsible for holding the final zonal mean values. GPB0F403.2728
! So we must set up a rec_means_map entry to allow the GPB0F403.2729
! zonal mean value for this row to be returned. GPB0F403.2730
GPB0F403.2731
IF (proc_x .EQ. proc_top_left_x) THEN GPB0F403.2732
GPB0F403.2733
n_rec_means = n_rec_means+1 GPB0F403.2734
GPB0F403.2735
rec_means_map(R_SOURCE_PE,n_rec_means)=dest_proc GPB0F403.2736
IF (fullfield) THEN ! We don't want halos GPB0F403.2737
rec_means_map(R_BASE_ADDRESS_IN_RECV_ARRAY, GPB0F403.2738
& n_rec_means)= GPB0F403.2739
& local_row-Offy GPB0F403.2740
ELSE ! halos are automatically removed GPB0F403.2741
rec_means_map(R_BASE_ADDRESS_IN_RECV_ARRAY, GPB0F403.2742
& n_rec_means)= GPB0F403.2743
& local_row GPB0F403.2744
ENDIF GPB0F403.2745
rec_means_map(R_NUMBER_OF_ELEMENTS_IN_ITEM, GPB0F403.2746
& n_rec_means)= 1 GPB0F403.2747
rec_means_map(R_STRIDE_IN_RECV_ARRAY, GPB0F403.2748
& n_rec_means)= 1 GPB0F403.2749
rec_means_map(R_ELEMENT_LENGTH,n_rec_means)=1 GPB0F403.2750
rec_means_map(R_BASE_ADDRESS_IN_SEND_ARRAY, GPB0F403.2751
& n_rec_means)= GPB0F403.2752
& work_dest_row_id GPB0F403.2753
rec_means_map(R_STRIDE_IN_SEND_ARRAY, GPB0F403.2754
& n_rec_means)=1 GPB0F403.2755
ENDIF GPB0F403.2756
GPB0F403.2757
ENDIF GPB0F403.2758
GPB0F403.2759
! 2.8.4 If this processor is dest_proc construct a rec_data_map GPB0F403.2760
! entry for this row of data GPB0F403.2761
GPB0F403.2762
IF (mype .EQ. dest_proc) THEN GPB0F403.2763
GPB0F403.2764
IF (proc_x .EQ. proc_top_left_x) GPB0F403.2765
! increment counter of full zonal rows on this processor GPB0F403.2766
& n_rows_full_zonal_data=n_rows_full_zonal_data+1 GPB0F403.2767
GPB0F403.2768
n_rec_data = n_rec_data+1 GPB0F403.2769
GPB0F403.2770
rec_data_map(R_SOURCE_PE,n_rec_data)= GPB0F403.2771
& proc_id GPB0F403.2772
rec_data_map(R_BASE_ADDRESS_IN_RECV_ARRAY,n_rec_data)= GPB0F403.2773
& (work_dest_row_id-1)*global_sum_array_sizex + GPB0F403.2774
& pos_in_zonal_array GPB0F403.2775
rec_data_map(R_NUMBER_OF_ELEMENTS_IN_ITEM,n_rec_data)= GPB0F403.2776
& 1 GPB0F403.2777
rec_data_map(R_STRIDE_IN_RECV_ARRAY,n_rec_data)=1 GPB0F403.2778
rec_data_map(R_ELEMENT_LENGTH,n_rec_data)= GPB0F403.2779
& local_send_size_x GPB0F403.2780
rec_data_map(R_BASE_ADDRESS_IN_SEND_ARRAY,n_rec_data)= GPB0F403.2781
& (local_row-1)*local_array_size_x + GPB0F403.2782
& local_send_off_x+1 GPB0F403.2783
rec_data_map(R_STRIDE_IN_SEND_ARRAY,n_rec_data)=1 GPB0F403.2784
GPB0F403.2785
! 2.8.4.1 Set up the send_means_map entry for sending the GPB0F403.2786
! resulting zonal mean of this row back to GPB0F403.2787
! the processor at the LHS of the subarea. GPB0F403.2788
! We only need to do this once per row (not for GPB0F403.2789
! each value of proc_x). GPB0F403.2790
GPB0F403.2791
IF (proc_x .EQ. proc_top_left_x) THEN GPB0F403.2792
GPB0F403.2793
n_send_means = n_send_means+1 GPB0F403.2794
GPB0F403.2795
send_means_map(S_DESTINATION_PE,n_send_means)= GPB0F403.2796
& proc_id GPB0F403.2797
send_means_map(S_BASE_ADDRESS_IN_SEND_ARRAY, GPB0F403.2798
& n_send_means)=work_dest_row_id GPB0F403.2799
send_means_map(S_NUMBER_OF_ELEMENTS_IN_ITEM, GPB0F403.2800
& n_send_means)=1 GPB0F403.2801
send_means_map(S_STRIDE_IN_SEND_ARRAY, GPB0F403.2802
& n_send_means)=1 GPB0F403.2803
send_means_map(S_ELEMENT_LENGTH,n_send_means)=1 GPB0F403.2804
IF (fullfield) THEN ! we don't want halos GPB0F403.2805
send_means_map(S_BASE_ADDRESS_IN_RECV_ARRAY, GPB0F403.2806
& n_send_means)=local_row-Offy GPB0F403.2807
ELSE ! halos are automatically removed GPB0F403.2808
send_means_map(S_BASE_ADDRESS_IN_RECV_ARRAY, GPB0F403.2809
& n_send_means)=local_row GPB0F403.2810
ENDIF GPB0F403.2811
send_means_map(S_STRIDE_IN_RECV_ARRAY, GPB0F403.2812
& n_send_means)=1 GPB0F403.2813
GPB0F403.2814
ENDIF ! if at LHS of subarea GPB0F403.2815
GPB0F403.2816
ENDIF ! if mype .eq. dest_proc GPB0F403.2817
GPB0F403.2818
ENDDO ! row : loop over local rows on proc_id GPB0F403.2819
ENDDO ! proc_x : loop over processors in x dimension GPB0F403.2820
ENDDO ! proc_y : loop over processors in y dimension GPB0F403.2821
GPB0F403.2822
! 3.0 Now the send and receive maps are set up, use GPB0F403.2823
! GCG_RALLTOALLE to redistribute the data GPB0F403.2824
! from the local_sum_arrays to the global_sum_arrays GPB0F403.2825
GPB0F403.2826
flag=GC_NONE ! flag argument is currently ignored by GCOM GPB0F403.2827
GPB0F403.2828
! We do a SHM_PUT operation, because the send arrays are non- GPB0F403.2829
! memory aligned, and the receiving arrays are. GPB0F403.2830
CALL GC_SETOPT(
GC_SHM_DIR,GC_SHM_PUT,info) GPB0F403.2831
info=GC_NONE GPB0F403.2832
GPB0F403.2833
CALL GCG_RALLTOALLE(
GPB0F403.2834
& local_sum_array_top , send_data_map , n_send_data , GPB0F403.2835
& local_sum_array_len , GPB0F403.2836
& global_sum_array_top , rec_data_map , n_rec_data , GPB0F403.2837
& global_sum_array_len , GPB0F403.2838
& gc_all_proc_group , flag , info) GPB0F403.2839
GPB0F403.2840
CALL GC_SETOPT(
GC_SHM_DIR,GC_SHM_PUT,info) GPB0F403.2841
info=GC_NONE GPB0F403.2842
GPB0F403.2843
CALL GCG_RALLTOALLE(
GPB0F403.2844
& local_sum_array_bot , send_data_map , n_send_data , GPB0F403.2845
& local_sum_array_len , GPB0F403.2846
& global_sum_array_bot , rec_data_map , n_rec_data , GPB0F403.2847
& global_sum_array_len , GPB0F403.2848
& gc_all_proc_group , flag , info) GPB0F403.2849
GPB0F403.2850
! 4.0 Calculate mean of any zonal data on this processor GPB0F403.2851
GPB0F403.2852
DO j=1,n_rows_full_zonal_data GPB0F403.2853
GPB0F403.2854
zonal_sum_top=0.0 GPB0F403.2855
zonal_sum_bot=0.0 GPB0F403.2856
GPB0F403.2857
DO i=global_xstart,global_xend GPB2F405.307
GPB0F403.2859
zonal_sum_top=zonal_sum_top+ GPB0F403.2860
& global_sum_array_top(i,j) GPB0F403.2861
zonal_sum_bot=zonal_sum_bot+ GPB0F403.2862
& global_sum_array_bot(i,j) GPB0F403.2863
ENDDO GPB0F403.2864
GPB0F403.2865
IF (zonal_sum_bot .EQ. 0.0) THEN GPB0F403.2866
zonal_mean_array(j)=rmdi GPB0F403.2867
ELSE GPB0F403.2868
zonal_mean_array(j)=zonal_sum_top/zonal_sum_bot GPB0F403.2869
ENDIF GPB0F403.2870
GPB0F403.2871
ENDDO GPB0F403.2872
GPB0F403.2873
! 5.0 Send the calculated means back to the processors on the GPB0F403.2874
! LHS of the subarea, into the fieldout array GPB0F403.2875
GPB0F403.2876
flag=GC_NONE ! flag argument is currently ignored by GCOM GPB0F403.2877
GPB0F403.2878
! We do a SHM_GET operation, because the send arrays are memory GPB0F403.2879
! aligned, but the receiving arrays are not. GPB0F403.2880
CALL GC_SETOPT(
GC_SHM_DIR,GC_SHM_PUT,info) GPB0F403.2881
info=GC_NONE GPB0F403.2882
GPB0F403.2883
CALL GCG_RALLTOALLE(
GPB0F403.2884
& zonal_mean_array , send_means_map , n_send_means , GPB0F403.2885
& global_sum_array_sizey, GPB0F403.2886
& fieldout , rec_means_map , n_rec_means, GPB0F403.2887
& (yend-ystart)+1, GPB0F403.2888
& gc_all_proc_group , flag , info) GPB0F403.2889
GPB0F403.2890
*ENDIF GPB0F403.2891
*ELSE GPB0F403.2892
GPB0F403.2893
! 0.0 : Initialise variables defining the size of the arrays GPB0F403.2894
! partial_sum_arrays GPB0F403.2895
partial_sum_array_sizey=vy*2 GPB2F405.308
GPB0F403.2898
GPB0F403.2899
! 1.0 Find the bounds of the actual data required in the summation GPB0F403.2900
! (ie. excluding the halos, contained within GPB0F403.2901
! xstart,xend,ystart,yend. GPB0F403.2902
GPB0F403.2903
CALL GLOBAL_TO_LOCAL_SUBDOMAIN
(.FALSE.,.FALSE., GPB0F403.2904
& gr,mype, GPB0F403.2905
& global_ystart,global_xend, GPB0F403.2906
& global_yend,global_xstart, GPB0F403.2907
& local_sum_ystart,local_sum_xend, GPB0F403.2908
& local_sum_yend,local_sum_xstart) GPB0F403.2909
GPB0F403.2910
! 1.1 And the number of partial sums on this processor GPB0F403.2911
GPB0F403.2912
IF (local_sum_xstart .GT. local_sum_xend) GPB0F403.2913
& local_sum_xend=local_sum_xend+ROW_LENGTH-2*Offx GPB0F403.2914
GPB0F403.2915
partial_sum_data_sizey=local_sum_yend-local_sum_ystart+1 GPB0F403.2916
GPB0F403.2917
GPB0F403.2918
! 1.2 Initialise the sum arrays GPB0F403.2919
GPB0F403.2920
IF ((local_sum_ystart .NE. st_no_data) .AND. GPB0F403.2921
& (local_sum_yend .NE. st_no_data)) THEN GPB0F403.2922
GPB0F403.2923
DO j=ystart,yend GPB0F403.2924
partial_SUMZBOT(j)=0.0 GPB0F403.2925
partial_SUMZTOP(j)=0.0 GPB0F403.2926
ENDDO GPB0F403.2927
GPB0F403.2928
ENDIF GPB0F403.2929
GPB0F403.2930
! 2.0 Calculate the partial sums GPB0F403.2931
GPB0F403.2932
! Only do calculations if some of the subdomain exists on this GPB0F403.2933
! processor GPB0F403.2934
IF ( (local_sum_xstart .NE. st_no_data) .AND. GPB0F403.2935
& (local_sum_xend .NE. st_no_data) .AND. GPB0F403.2936
& (local_sum_ystart .NE. st_no_data) .AND. GPB0F403.2937
& (local_sum_yend .NE. st_no_data)) THEN GPB0F403.2938
GPB0F403.2939
! 2.2 Add do the actual sum GPB0F403.2940
GPB0F403.2941
DO i=local_sum_xstart,local_sum_xend GPB0F403.2942
GPB0F403.2943
IF ( lwrap .AND. (i .GT. (lasize(1)-Offx))) THEN GPB0F403.2944
ii=i-lasize(1)+2*Offx ! miss halos on wrap around GPB0F403.2945
ELSE GPB0F403.2946
ii=i GPB0F403.2947
ENDIF GPB0F403.2948
GPB0F403.2949
! Only do the sum if this is not a halo point GPB0F403.2950
GPB0F403.2951
DO j=local_sum_ystart,local_sum_yend GPB0F403.2952
IF (mask(ii,j)) THEN GPB0F403.2953
IF (.NOT. lmasswt) THEN GPB0F403.2954
GPB0F403.2955
partial_SUMZBOT(j)=partial_SUMZBOT(j)+ GPB0F403.2956
& pstar_weight(ii,j) GPB0F403.2957
partial_SUMZTOP(j)=partial_SUMZTOP(j)+ GPB0F403.2958
& fieldin(ii,j)*pstar_weight(ii,j) GPB0F403.2959
ELSE GPB0F403.2960
partial_SUMZBOT(j)=partial_SUMZBOT(j)- GPB0F403.2961
& (delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2962
partial_SUMZTOP(j)=partial_SUMZTOP(j)-fieldin(ii,j)* GPB0F403.2963
& (delta_ak+delta_bk*pstar_weight(ii,j)) GPB0F403.2964
ENDIF ! if (.NOT. lmasswt) GPB0F403.2965
ENDIF ! if this point is to be processed GPB0F403.2966
ENDDO ! j : loop over rows GPB0F403.2967
ENDDO ! i : loop over columns GPB0F403.2968
ENDIF ! if subdomain covers this processor GPB0F403.2969
GPB0F403.2970
! 3.0 Sums up the partial sums along each row to make a full sum GPB0F403.2971
GPB0F403.2972
! So a sum along the processor row if the subdomain covers any GPB0F403.2973
! processor(s) along the row GPB0F403.2974
GPB0F403.2975
IF ((local_sum_ystart .NE. st_no_data) .AND. GPB0F403.2976
& (local_sum_yend .NE. st_no_data)) THEN GPB0F403.2977
GPB0F403.2978
CALL GCG_RSUM(
partial_sum_data_sizey,gc_proc_row_group, GPB0F403.2979
& info,partial_SUMZBOT(local_sum_ystart)) GPB0F403.2980
CALL GCG_RSUM(
partial_sum_data_sizey,gc_proc_row_group, GPB0F403.2981
& info,partial_SUMZTOP(local_sum_ystart)) GPB0F403.2982
GPB0F403.2983
! So now the partial_* arrays actually contain the full sums GPB0F403.2984
! along the row GPB0F403.2985
GPB0F403.2986
! 3.1 And put the mean zonal values into the fieldout array GPB0F403.2987
GPB0F403.2988
! Only processors in the subdomain area need to record the GPB0F403.2989
! results GPB0F403.2990
IF ((local_sum_xstart .NE. st_no_data) .AND. GPB0F403.2991
& (local_sum_xend .NE. st_no_data)) THEN GPB0F403.2992
GPB0F403.2993
DO j=local_sum_ystart,local_sum_yend GPB0F403.2994
IF (partial_SUMZBOT(j) .EQ. 0.0) THEN GPB0F403.2995
fieldout(j)=rmdi GPB0F403.2996
ELSE GPB0F403.2997
fieldout(j)=partial_SUMZTOP(j)/partial_SUMZBOT(j) GPB0F403.2998
ENDIF GPB0F403.2999
ENDDO GPB0F403.3000
GPB0F403.3001
ENDIF ! is this processor in the subdomain GPB0F403.3002
GPB0F403.3003
ENDIF ! does the subdomain intersect with this processor row GPB0F403.3004
GPB0F403.3005
*ENDIF GPB0F403.3006
CL STZONM1A.450
999 CONTINUE STZONM1A.451
RETURN STZONM1A.452
END STZONM1A.453
*ENDIF STZONM1A.454