166
167
168
169
170 integer, intent(in) :: ng, tile, model
171 integer, intent(in) :: LBi, UBi, LBj, UBj
172 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
173 integer, intent(in) :: kstp, krhs, knew
174# ifdef SOLVE3D
175 integer, intent(in) :: nstp, nnew
176# endif
177
178# ifdef ASSUMED_SHAPE
179# ifdef MASKING
180 real(r8), intent(in) :: rmask(LBi:,LBj:)
181 real(r8), intent(in) :: umask(LBi:,LBj:)
182 real(r8), intent(in) :: vmask(LBi:,LBj:)
183# endif
184# ifdef WET_DRY
185 real(r8), intent(in) :: rmask_wet(LBi:,LBj:)
186 real(r8), intent(inout) :: umask_wet(LBi:,LBj:)
187 real(r8), intent(inout) :: vmask_wet(LBi:,LBj:)
188# endif
189# ifdef SOLVE3D
190 real(r8), intent(in) :: Hz(LBi:,LBj:,:)
191# endif
192 real(r8), intent(in) :: zeta(LBi:,LBj:,:)
193# ifdef SOLVE3D
194# if defined SEDIMENT || defined BBL_MODEL
195 real(r8), intent(inout) :: bottom(LBi:,LBj:,:)
196# endif
197# if defined SEDIMENT
198 real(r8), intent(inout) :: bed(LBi:,LBj:,:,:)
199 real(r8), intent(inout) :: bed_frac(LBi:,LBj:,:,:)
200 real(r8), intent(inout) :: bed_mass(LBi:,LBj:,:,:,:)
201# endif
202# endif
203# ifdef PERFECT_RESTART
204# ifdef SOLVE3D
205 real(r8), intent(inout) :: ru(LBi:,LBj:,0:,:)
206 real(r8), intent(inout) :: rv(LBi:,LBj:,0:,:)
207# endif
208 real(r8), intent(inout) :: rubar(LBi:,LBj:,:)
209 real(r8), intent(inout) :: rvbar(LBi:,LBj:,:)
210 real(r8), intent(inout) :: rzeta(LBi:,LBj:,:)
211# endif
212# ifdef SOLVE3D
213 real(r8), intent(inout) :: t(LBi:,LBj:,:,:,:)
214 real(r8), intent(inout) :: u(LBi:,LBj:,:,:)
215 real(r8), intent(inout) :: v(LBi:,LBj:,:,:)
216# endif
217 real(r8), intent(inout) :: ubar(LBi:,LBj:,:)
218 real(r8), intent(inout) :: vbar(LBi:,LBj:,:)
219
220# else
221
222# ifdef MASKING
223 real(r8), intent(in) :: rmask(LBi:UBi,LBj:UBj)
224 real(r8), intent(in) :: umask(LBi:UBi,LBj:UBj)
225 real(r8), intent(in) :: vmask(LBi:UBi,LBj:UBj)
226# endif
227# ifdef WET_DRY
228 real(r8), intent(in) :: rmask_wet(LBi:UBi,LBj:UBj)
229 real(r8), intent(inout) :: umask_wet(LBi:UBi,LBj:UBj)
230 real(r8), intent(inout) :: vmask_wet(LBi:UBi,LBj:UBj)
231# endif
232# ifdef SOLVE3D
233 real(r8), intent(in) :: Hz(LBi:UBi,LBj:UBj,N(ng))
234# endif
235 real(r8), intent(in) :: zeta(LBi:UBi,LBj:UBj,:)
236# ifdef SOLVE3D
237# if defined SEDIMENT || defined BBL_MODEL
238 real(r8), intent(inout) :: bottom(LBi:UBi,LBj:UBj,MBOTP)
239# endif
240# if defined SEDIMENT
241 real(r8), intent(inout) :: bed(LBi:UBi,LBj:UBj,Nbed,MBEDP)
242 real(r8), intent(inout) :: bed_frac(LBi:UBi,LBj:UBj,Nbed,NST)
243 real(r8), intent(inout) :: bed_mass(LBi:UBi,LBj:UBj,Nbed,2,NST)
244# endif
245# endif
246# ifdef PERFECT_RESTART
247# ifdef SOLVE3D
248 real(r8), intent(inout) :: ru(LBi:UBi,LBj:UBj,0:N(ng),2)
249 real(r8), intent(inout) :: rv(LBi:UBi,LBj:UBj,0:N(ng),2)
250# endif
251 real(r8), intent(inout) :: rubar(LBi:UBi,LBj:UBj,2)
252 real(r8), intent(inout) :: rvbar(LBi:UBi,LBj:UBj,2)
253 real(r8), intent(inout) :: rzeta(LBi:UBi,LBj:UBj,2)
254# endif
255# ifdef SOLVE3D
256 real(r8), intent(inout) :: t(LBi:UBi,LBj:UBj,N(ng),3,NT(ng))
257 real(r8), intent(inout) :: u(LBi:UBi,LBj:UBj,N(ng),2)
258 real(r8), intent(inout) :: v(LBi:UBi,LBj:UBj,N(ng),2)
259# endif
260 real(r8), intent(inout) :: ubar(LBi:UBi,LBj:UBj,:)
261 real(r8), intent(inout) :: vbar(LBi:UBi,LBj:UBj,:)
262# endif
263
264
265
266 integer :: i, ic, itrc, j, k
267# if defined SEDIMENT || defined BBL_MODEL
268 integer :: ised
269# endif
270
271 real(r8) :: cff1, cff2
272# ifdef SOLVE3D
273 real(r8), dimension(IminS:ImaxS,0:N(ng)) :: CF
274 real(r8), dimension(IminS:ImaxS,0:N(ng)) :: DC
275# endif
276
277# include "set_bounds.h"
278
279# ifdef SOLVE3D
280
281
282
283
284
285 IF (.not.perfectrst(ng)) THEN
286 DO j=jstrb,jendb
287 DO k=1,n(ng)
288 DO i=istrm,iendb
289 cff1=u(i,j,k,nstp)
290# ifdef MASKING
291 cff1=cff1*umask(i,j)
292# endif
293# ifdef WET_DRY
294 cff1=cff1*umask_wet(i,j)
295# endif
296 u(i,j,k,nstp)=cff1
297 END DO
298 END DO
299
300 IF (j.ge.jstrm) THEN
301 DO k=1,n(ng)
302 DO i=istrb,iendb
303 cff2=v(i,j,k,nstp)
304# ifdef MASKING
305 cff2=cff2*vmask(i,j)
306# endif
307# ifdef WET_DRY
308 cff2=cff2*vmask_wet(i,j)
309# endif
310 v(i,j,k,nstp)=cff2
311 END DO
312 END DO
313 END IF
314 END DO
315
316
317
318 CALL u3dbc_tile (ng, tile, &
319 & lbi, ubi, lbj, ubj, n(ng), &
320 & imins, imaxs, jmins, jmaxs, &
321 & nstp, nstp, &
322 & u)
323 CALL v3dbc_tile (ng, tile, &
324 & lbi, ubi, lbj, ubj, n(ng), &
325 & imins, imaxs, jmins, jmaxs, &
326 & nstp, nstp, &
327 & v)
328 END IF
329
330 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
331 CALL exchange_u3d_tile (ng, tile, &
332 & lbi, ubi, lbj, ubj, 1, n(ng), &
333 & u(:,:,:,nstp))
334 CALL exchange_v3d_tile (ng, tile, &
335 & lbi, ubi, lbj, ubj, 1, n(ng), &
336 & v(:,:,:,nstp))
337 END IF
338
339# ifdef DISTRIBUTE
340
341 CALL mp_exchange3d (ng, tile, model, 2, &
342 & lbi, ubi, lbj, ubj, 1, n(ng), &
343 & nghostpoints, &
344 & ewperiodic(ng), nsperiodic(ng), &
345 & u(:,:,:,nstp), v(:,:,:,nstp))
346# endif
347# endif
348
349# ifdef SOLVE3D
350
351
352
353
354
355
356
357
358
359 IF (.not.perfectrst(ng)) THEN
360 DO j=jstrb,jendb
361 DO i=istrm,iendb
362 dc(i,0)=0.0_r8
363 cf(i,0)=0.0_r8
364 END DO
365 DO k=1,n(ng)
366 DO i=istrm,iendb
367 dc(i,k)=0.5_r8*(hz(i,j,k)+hz(i-1,j,k))
368 dc(i,0)=dc(i,0)+dc(i,k)
369 cf(i,0)=cf(i,0)+dc(i,k)*u(i,j,k,nstp)
370 END DO
371 END DO
372 DO i=istrm,iendb
373 cff1=1.0_r8/dc(i,0)
374 cff2=cf(i,0)*cff1
375# ifdef MASKING
376 cff2=cff2*umask(i,j)
377# endif
378# ifdef WET_DRY
379 cff2=cff2*umask_wet(i,j)
380# endif
381 ubar(i,j,kstp)=cff2
382 END DO
383
384 IF (j.ge.jstrm) THEN
385 DO i=istrb,iendb
386 dc(i,0)=0.0_r8
387 cf(i,0)=0.0_r8
388 END DO
389 DO k=1,n(ng)
390 DO i=istrb,iendb
391 dc(i,k)=0.5_r8*(hz(i,j,k)+hz(i,j-1,k))
392 dc(i,0)=dc(i,0)+dc(i,k)
393 cf(i,0)=cf(i,0)+dc(i,k)*v(i,j,k,nstp)
394 END DO
395 END DO
396 DO i=istrb,iendb
397 cff1=1.0_r8/dc(i,0)
398 cff2=cf(i,0)*cff1
399# ifdef MASKING
400 cff2=cff2*vmask(i,j)
401# endif
402# ifdef WET_DRY
403 cff2=cff2*vmask_wet(i,j)
404# endif
405 vbar(i,j,kstp)=cff2
406 END DO
407 END IF
408 END DO
409
410
411
412 IF (.not.(any(lbc(:,isubar,ng)%radiation).or. &
413 & any(lbc(:,isvbar,ng)%radiation).or. &
414 & any(lbc(:,isubar,ng)%Flather).or. &
415 & any(lbc(:,isvbar,ng)%Flather))) THEN
416 CALL u2dbc_tile (ng, tile, &
417 & lbi, ubi, lbj, ubj, &
418 & imins, imaxs, jmins, jmaxs, &
419 & krhs, kstp, kstp, &
420 & ubar, vbar, zeta)
421 CALL v2dbc_tile (ng, tile, &
422 & lbi, ubi, lbj, ubj, &
423 & imins, imaxs, jmins, jmaxs, &
424 & krhs, kstp, kstp, &
425 & ubar, vbar, zeta)
426 END IF
427 END IF
428
429 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
430 CALL exchange_u2d_tile (ng, tile, &
431 & lbi, ubi, lbj, ubj, &
432 & ubar(:,:,kstp))
433 CALL exchange_v2d_tile (ng, tile, &
434 & lbi, ubi, lbj, ubj, &
435 & vbar(:,:,kstp))
436 END IF
437
438# ifdef DISTRIBUTE
439
440 CALL mp_exchange2d (ng, tile, model, 2, &
441 & lbi, ubi, lbj, ubj, &
442 & nghostpoints, &
443 & ewperiodic(ng), nsperiodic(ng), &
444 & ubar(:,:,kstp), vbar(:,:,kstp))
445# endif
446
447# else
448
449
450
451
452
453
454 IF (.not.perfectrst(ng)) THEN
455 DO j=jstrb,jendb
456 DO i=istrm,iendb
457 cff1=ubar(i,j,kstp)
458# ifdef MASKING
459 cff1=cff1*umask(i,j)
460# endif
461# ifdef WET_DRY
462 cff1=cff1*umask_wet(i,j)
463# endif
464 ubar(i,j,kstp)=cff1
465 END DO
466
467 IF (j.ge.jstrm) THEN
468 DO i=istrb,iendb
469 cff2=vbar(i,j,kstp)
470# ifdef MASKING
471 cff2=cff2*vmask(i,j)
472# endif
473# ifdef WET_DRY
474 cff2=cff2*vmask_wet(i,j)
475# endif
476 vbar(i,j,kstp)=cff2
477 END DO
478 END IF
479 END DO
480
481
482
483 IF (.not.(any(lbc(:,isubar,ng)%radiation).or. &
484 & any(lbc(:,isvbar,ng)%radiation).or. &
485 & any(lbc(:,isubar,ng)%Flather).or. &
486 & any(lbc(:,isvbar,ng)%Flather))) THEN
487 CALL u2dbc_tile (ng, tile, &
488 & lbi, ubi, lbj, ubj, &
489 & imins, imaxs, jmins, jmaxs, &
490 & krhs, kstp, kstp, &
491 & ubar, vbar, zeta)
492 CALL v2dbc_tile (ng, tile, &
493 & lbi, ubi, lbj, ubj, &
494 & imins, imaxs, jmins, jmaxs, &
495 & krhs, kstp, kstp, &
496 & ubar, vbar, zeta)
497 END IF
498 END IF
499
500 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
501 CALL exchange_u2d_tile (ng, tile, &
502 & lbi, ubi, lbj, ubj, &
503 & ubar(:,:,kstp))
504 CALL exchange_v2d_tile (ng, tile, &
505 & lbi, ubi, lbj, ubj, &
506 & vbar(:,:,kstp))
507 IF (perfectrst(ng)) THEN
508 CALL exchange_u2d_tile (ng, tile, &
509 & lbi, ubi, lbj, ubj, &
510 & ubar(:,:,knew))
511 CALL exchange_v2d_tile (ng, tile, &
512 & lbi, ubi, lbj, ubj, &
513 & vbar(:,:,knew))
514 END IF
515 END IF
516
517# ifdef DISTRIBUTE
518
519 CALL mp_exchange2d (ng, tile, model, 2, &
520 & lbi, ubi, lbj, ubj, &
521 & nghostpoints, &
522 & ewperiodic(ng), nsperiodic(ng), &
523 & ubar(:,:,kstp), vbar(:,:,kstp))
524 IF (perfectrst(ng)) THEN
525 CALL mp_exchange2d (ng, tile, model, 2, &
526 & lbi, ubi, lbj, ubj, &
527 & nghostpoints, &
528 & ewperiodic(ng), nsperiodic(ng), &
529 & ubar(:,:,knew), vbar(:,:,knew))
530 END IF
531# endif
532# endif
533
534# ifdef SOLVE3D
535
536
537
538
539
540 ic=0
541 IF (.not.perfectrst(ng)) THEN
542 DO itrc=1,nt(ng)
543 IF (ltracerclm(itrc,ng).and.lnudgetclm(itrc,ng)) THEN
544 ic=ic+1
545 END IF
546 DO k=1,n(ng)
547 DO j=jstrb,jendb
548 DO i=istrb,iendb
549 cff1=t(i,j,k,nstp,itrc)
550# ifdef MASKING
551 cff1=cff1*rmask(i,j)
552# endif
553 t(i,j,k,nstp,itrc)=cff1
554 END DO
555 END DO
556 END DO
557
558
559
560 CALL t3dbc_tile (ng, tile, itrc, ic, &
561 & lbi, ubi, lbj, ubj, n(ng), nt(ng), &
562 & imins, imaxs, jmins, jmaxs, &
563 & nstp, nstp, &
564 & t)
565 END DO
566 END IF
567
568 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
569 DO itrc=1,nt(ng)
570 CALL exchange_r3d_tile (ng, tile, &
571 & lbi, ubi, lbj, ubj, 1, n(ng), &
572 & t(:,:,:,nstp,itrc))
573 END DO
574 END IF
575
576# ifdef DISTRIBUTE
577
578 CALL mp_exchange4d (ng, tile, model, 1, &
579 & lbi, ubi, lbj, ubj, 1, n(ng), 1, nt(ng), &
580 & nghostpoints, &
581 & ewperiodic(ng), nsperiodic(ng), &
582 & t(:,:,:,nstp,:))
583# endif
584
585# if defined BBL_MODEL || defined SEDIMENT
586
587
588
589
590
591# ifdef SEDIMENT
592 IF (.not.perfectrst(ng)) THEN
593 DO k=1,nbed
594 DO j=jstrt,jendt
595 DO i=istrt,iendt
596 DO ised=1,nst
597 cff1=bed_mass(i,j,k,1,ised)
598 bed_mass(i,j,k,2,ised)=cff1
599 END DO
600 END DO
601 END DO
602 END DO
603 END IF
604# endif
605
606 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
607# ifdef SEDIMENT
608 DO ised=1,nst
609 CALL exchange_r3d_tile (ng, tile, &
610 & lbi, ubi, lbj, ubj, 1, nbed, &
611 & bed_frac(:,:,:,ised))
612 CALL exchange_r3d_tile (ng, tile, &
613 & lbi, ubi, lbj, ubj, 1, nbed, &
614 & bed_mass(:,:,:,1,ised))
615 CALL exchange_r3d_tile (ng, tile, &
616 & lbi, ubi, lbj, ubj, 1, nbed, &
617 & bed_mass(:,:,:,2,ised))
618 END DO
619 DO ised=1,mbedp
620 CALL exchange_r3d_tile (ng, tile, &
621 & lbi, ubi, lbj, ubj, 1, nbed, &
622 & bed(:,:,:,ised))
623 END DO
624# endif
625 CALL exchange_r3d_tile (ng, tile, &
626 & lbi, ubi, lbj, ubj, 1, mbotp, &
627 & bottom)
628 END IF
629
630# ifdef DISTRIBUTE
631# ifdef SEDIMENT
632 CALL mp_exchange4d (ng, tile, model, 1, &
633 & lbi, ubi, lbj, ubj, 1, nbed, 1, nst, &
634 & nghostpoints, &
635 & ewperiodic(ng), nsperiodic(ng), &
636 & bed_frac)
637 CALL mp_exchange4d (ng, tile, model, 2, &
638 & lbi, ubi, lbj, ubj, 1, nbed, 1, nst, &
639 & nghostpoints, &
640 & ewperiodic(ng), nsperiodic(ng), &
641 & bed_mass(:,:,:,1,:),bed_mass(:,:,:,2,:))
642 CALL mp_exchange4d (ng, tile, model, 1, &
643 & lbi, ubi, lbj, ubj, 1, nbed, 1, mbedp, &
644 & nghostpoints, &
645 & ewperiodic(ng), nsperiodic(ng), &
646 & bed)
647# endif
648 CALL mp_exchange3d (ng, tile, model, 1, &
649 & lbi, ubi, lbj, ubj, 1, mbotp, &
650 & nghostpoints, &
651 & ewperiodic(ng), nsperiodic(ng), &
652 & bottom)
653# endif
654# endif
655# endif
656
657# ifdef PERFECT_RESTART
658
659
660
661
662
663
664 IF (perfectrst(ng)) THEN
665 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
666 DO i=1,2
667 CALL exchange_u2d_tile (ng, tile, &
668 & lbi, ubi, lbj, ubj, &
669 & rubar(:,:,i))
670 CALL exchange_v2d_tile (ng, tile, &
671 & lbi, ubi, lbj, ubj, &
672 & rvbar(:,:,i))
673 CALL exchange_r2d_tile (ng, tile, &
674 & lbi, ubi, lbj, ubj, &
675 & rzeta(:,:,i))
676# ifdef SOLVE3D
677 CALL exchange_u3d_tile (ng, tile, &
678 & lbi, ubi, lbj, ubj, 0, n(ng), &
679 & ru(:,:,:,i))
680 CALL exchange_v3d_tile (ng, tile, &
681 & lbi, ubi, lbj, ubj, 0, n(ng), &
682 & rv(:,:,:,i))
683# endif
684 END DO
685 END IF
686
687# ifdef DISTRIBUTE
688 CALL mp_exchange3d (ng, tile, model, 3, &
689 & lbi, ubi, lbj, ubj, 1, 2, &
690 & nghostpoints, &
691 & ewperiodic(ng), nsperiodic(ng), &
692 & rubar, rvbar, rzeta)
693# ifdef SOLVE3D
694 CALL mp_exchange4d (ng, tile, model, 2, &
695 & lbi, ubi, lbj, ubj, 0, n(ng), 1, 2, &
696 & nghostpoints, &
697 & ewperiodic(ng), nsperiodic(ng), &
698 & ru, rv)
699# endif
700# endif
701 END IF
702# endif
703
704 RETURN