copyright (C) 2001 MSC-RPN COMM %%%MC2%%%
***s/r physlb -- Prepares slice j and runs the physics package on it.
*
subroutine physlb (icpu,njdone,kount, 1,39
$ up,vp,wp,tp,esp,clp,um,vm,tm,esm,htm,clm,
$ ttrad,tugwd,tvgwd,thudifv,ttdifv,tudifv,tvdifv,twdifv,
$ thucond,ttcond,cltend,lebus,geofld,
$ bus_o,prt,psm,area,nis,njs,nks)
implicit none
*
integer icpu,njdone,kount,nis,njs,nks
real up (nis,njs,nks),vp (nis,njs,nks),wp (nis,njs,nks),
$ tp
(nis,njs,nks),esp(nis,njs,nks),clp(nis,njs,nks,*),
$ um (nis,njs,nks),vm (nis,njs,nks),tm (nis,njs,nks),
$ esm(nis,njs,nks),htm(nis,njs,nks),clm(nis,njs,nks,*),
$ ttrad(nis,njs,nks),tugwd(nis,njs,nks),tvgwd(nis,njs,nks),
$ thudifv(nis,njs,nks),ttdifv(nis,njs,nks),tudifv(nis,njs,nks),
$ tvdifv(nis,njs,nks),twdifv(nis,njs,nks),thucond(nis,njs,nks),
$ ttcond(nis,njs,nks),cltend(nis,njs,nks,*),prt(nis,njs,nks)
real psm(nis,njs),area(nis,njs),lebus(*),geofld(*),bus_o(*)
*
*AUTHOR Robert Benoit / Michel Desgagne Apr 1993
*
*REVISION
*001 JM Belanger/M. Desgagne Sept. 1994
* - New physics interface (PARAM).
*002 Bernard Bilodeau (Feb 1999) - Entry bus
*003 J. Mailhot (Mar 1999) - Changes for new SURFACE interface
*
*OBJECT
* This routine will succesively prepare "njs" slices and call the
* physics package (phyexe) for each slice. PHYSLB loads slice j
* of the dynamic variables on busdyn. It gets back tendencies
* (due to physical processes) from busvol and does the recuperation
* of the output fields from the appropriate buses.
* In the description below (t*) stands for the time level after the
* dynamic timestep.
*
*FILES
*
*ARGUMENTS
* NAMES I/O TYPE A/S DESCRIPTION
*
* icpu I I S cpu number executing slice "trnch"
* njdone I/O I S number of slices previously done
* kount I I S timestep
* up I/O R A u component of the wind at time (t*)
* vp I/O R A v component of the wind at time (t*)
* wp I R A real vertical wind at time (t*)
* tp I/O R A temperature at time (t*)
* esp I/O R A humidity at time (t*)
* clp I R A tracers at time (t*)
* um I R A u component of the wind at time (t-dt)
* vm I R A v component of the wind at time (t-dt)
* tm I R A temperature at time (t-dt)
* esm I R A humidity at time (t-dt)
* clm I R A tracers at time (t-dt)
* ttrad O R A temperature tendency due to radiative
* processes
* tugwd O R A u tendency due to gravity wave drag
* tvgwd O R A v tendency due to gravity wave drag
* thudifv O R A humidity tendency due to vertical
* diffusion
* ttdifv O R A temperature tendency due to vertical
* diffusion
* tudifv O R A u tendency due to vertical diffusion
* tvdifv O R A v tendency due to vertical diffusion
* twdifv O R A omega tendency due to vertical diffusion
* thucond O R A humidity tendency due to condensation
* ttcond O R A temperature tendency due to condensation
* qctend O R A water content tendency due to condensation
* qrtend O R A liq. precipitation tendency.
* qitend O R A ice content tendency.
* qgtend O R A graupel.hail tendency.
* etend O R A turbulent energy tendency.
* bus_o O R A bus containing physics output variables
* geofld I R bus containing geophysical fields
* prt I R A hydrostatic pressure on thermo. levels
* psm I R A surface pressure at time (t-dt)
* nis I I S first horizontal dimension
* njs I I S second horizontal dimension
* nks I I S vertical dimension
*
*IMPLICIT
*
#include "yomdyn1.cdk"
#include "mc2lck.cdk"
#include "physcom.cdk"
#include "physnml.cdk"
#include "lesbus.cdk"
#include "busind.cdk"
#include "lcldim.cdk"
#include "lun.cdk"
#include "consdyn_8.cdk"
*
*MODULES
*
**
integer xnerr,i,j,k,ii,im,offbo,offbd,offbe,offbp,offbv
integer lght,init0,ifcp,nkk
integer pid,gid,mul,offp,offg,maxind
integer read_db_file,write_db_file
external read_db_file,write_db_file
*
real busent(max(1,sizebus)),busdyn(max(1,sizdbus)),
$ busper,busper2(max(1,sizpbus)),busvol(max(1,sizvbus))
pointer (pabusper,busper(*))
real um1(nis),vm1(nis),tm1(nis),qm1(nis)
*
*----------------------------------------------------------------------
*
if (.not.incore) pabusper=loc(busper2(1))
*40
* *************** computing physics on njs slices ********************
*
j=0
400 continue
!$omp critical
if (j.ne.0) call mzonopr(-3,j)
njdone = njdone + 1
if (njdone .le. njs ) then
if (incore) then
j = njdone
pabusper = loc (lebus((j-1)*sizpbus+1))
else
if (kount.eq.0) then
j = njdone
else
xnerr = read_db_file (un_gbusper,j,1)
xnerr = read_db_file (un_gbusper,busper,sizpbus)
endif
endif
call mzonopr(3,j)
endif
!$omp end critical
if (njdone .gt. njs ) go to 500
*
* copy busgeo into busent
* -----------------------
*
if (kount.eq.0) then
*
do i=1,sizebus
busent(i)=0.0
end do
do 20 pid=1,enttop
if (entpar(pid,3).gt.0) then
do gid=1,geotop
if (entnm(pid).eq.geonm(gid,1)) then
do mul=1,geopar(gid,3)
offp =entpar(pid,1)+(mul-1)*fni
offg =geopar(gid,1)+(mul-1)*ldni*ldnj+(j-1)*fni
maxind=geopar(gid,1)+(mul-1)*ldni*ldnj+ldni*ldnj-1
do i=1,fni
busent(offp+i-1)=geofld(min(offg+i-1,maxind))
end do
end do
goto 20
endif
end do
print*, 'PROBLEM WITH ',entnm(pid)
stop
endif
20 continue
*
endif
*
* * Prepare slice j
*
call tranche2
(busdyn( umoins) ,um ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( vmoins) ,vm ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( tmoins) ,tm ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( humoins) ,esm ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn(gzmoins6) ,htm ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( pmoins) ,psm ,j,nis,njs, 1,nis, 1,32)
*
call tranche2
(busdyn( uplus) ,up ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( vplus) ,vp ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( tplus) ,tp ,j,nis,njs,nks,nis,nks,32)
call tranche2
(busdyn( huplus) ,esp ,j,nis,njs,nks,nis,nks,32)
*
if((qcmoins.gt.0).and.(ipqc.gt.0)) call tranche2
(busdyn(qcmoins),
$ clm(1,1,1,ipqc),j,nis,njs,nks,nis,nks,32)
if((qcplus .gt.0).and.(ipqc.gt.0)) call tranche2
(busdyn( qcplus),
$ clp(1,1,1,ipqc),j,nis,njs,nks,nis,nks,32)
if((qrmoins.gt.0).and.(ipqr.gt.0)) call tranche2
(busdyn(qrmoins),
$ clm(1,1,1,ipqr),j,nis,njs,nks,nis,nks,32)
if((qrplus .gt.0).and.(ipqr.gt.0)) call tranche2
(busdyn( qrplus),
$ clp(1,1,1,ipqr),j,nis,njs,nks,nis,nks,32)
if((qimoins.gt.0).and.(ipqi.gt.0)) call tranche2
(busdyn(qimoins),
$ clm(1,1,1,ipqi),j,nis,njs,nks,nis,nks,32)
if((qiplus .gt.0).and.(ipqi.gt.0)) call tranche2
(busdyn( qiplus),
$ clp(1,1,1,ipqi),j,nis,njs,nks,nis,nks,32)
if((qgmoins.gt.0).and.(ipqg.gt.0)) call tranche2
(busdyn(qgmoins),
$ clm(1,1,1,ipqg),j,nis,njs,nks,nis,nks,32)
if((qgplus .gt.0).and.(ipqg.gt.0)) call tranche2
(busdyn( qgplus),
$ clp(1,1,1,ipqg),j,nis,njs,nks,nis,nks,32)
if((enplus .gt.0).and.(ipen.gt.0)) call tranche2
(busdyn(enplus),
$ clp(1,1,1,ipen),j,nis,njs,nks,nis,nks,32)
*
* Vertical motion (in pa/s)
do k=1,nks
*VDIR NODEP
do i=1,nis
busdyn(sigm +(k-1)*nis+i-1) = prt(i,j,k)/prt(i,j,nks)
busdyn(omegap+(k-1)*nis+i-1) = - wp(i,j,k)*
$ prt(i,j,k)*grav_8/(rgasd_8*tp
(i,j,k)*(1.+0.608*esp(i,j,k)))
end do
end do
*
call getindx2
('FCPOID', 'D',ifcp, lght,init0)
if (init0.eq.1) then
do i=1,nis
busdyn(ifcp+i-1) = 1.
end do
endif
call getindx2
('FCPMSK', 'D',ifcp, lght,init0)
if (init0.eq.1) then
do i=1,nis
busdyn(ifcp+i-1) = -2.
end do
endif
*
* Grid mesh
*VDIR NODEP
do i=1,nis
busdyn(dxdy +i-1) = area(i,j)
busdyn(pplus +i-1) = prt(i,j,nks)
busdyn(eponmod+i-1) = 1.
end do
*
* * Physics package : Radiation, Boundary Layer, Vertical Diffusion
* Gravity Wave Drag and Convection.
*
busvol = 0.
c do i=1,dyntop
c nkk=1
c if (dynpar(i,2).gt.nis) nkk=nks
c call statfld ( busdyn(dynpar(i,1)),dynnm(i), j,'physl',
c $ .true., 1,nis,1,1,nkk, 1,1,1,nis,1,nkk)
c end do
**********************************************************************
call phyexe1
(busent ,busdyn ,busper ,busvol ,
$ sizebus,sizdbus,sizpbus,sizvbus,
$ dt,j,kount,icpu,nis,nks)
**********************************************************************
*
* Transfer user asked physics output fields onto bus_o
*
do 50 i=1,bus_otop
*
if (bus_oname(i,1).eq.'SCREEN') then
*VDIR NODEP
do ii=1,nis
bus_o(bus_opar(i,1)+0*nis*njs+(j-1)*nis+ii-1)= 1./knams_8 *
$ (up(ii,j,nks) + busvol(udifv+(nks-1)*nis+ii-1) * 2.0*grdt)
bus_o(bus_opar(i,1)+1*nis*njs+(j-1)*nis+ii-1)= 1./knams_8 *
$ (vp(ii,j,nks) + busvol(vdifv+(nks-1)*nis+ii-1) * 2.0*grdt)
bus_o(bus_opar(i,1)+2*nis*njs+(j-1)*nis+ii-1)= -tcdk_8 +
$ tp
(ii,j,nks) + busvol(tdifv+(nks-1)*nis+ii-1) * 2.0*grdt
bus_o(bus_opar(i,1)+3*nis*njs+(j-1)*nis+ii-1)=
$ esp(ii,j,nks) + busvol(qdifv+(nks-1)*nis+ii-1) * 2.0*grdt
end do
goto 50
endif
*
if (bus_oname(i,1).eq.'RAIN') then
*VDIR NODEP
do ii=1,nis
bus_o(bus_opar(i,1)+0*nis*njs+(j-1)*nis+ii-1) =
$ busper(alc+ii-1) + busper(als+ii-1) +
$ busper(asc+ii-1) + busper(ass+ii-1)
bus_o(bus_opar(i,1)+1*nis*njs+(j-1)*nis+ii-1) =
$ busper(alc+ii-1) + busper(asc+ii-1)
bus_o(bus_opar(i,1)+2*nis*njs+(j-1)*nis+ii-1) =
$ busper(tlc+ii-1) + busper(tls+ii-1) +
$ busper(tsc+ii-1) + busper(tss+ii-1)
bus_o(bus_opar(i,1)+3*nis*njs+(j-1)*nis+ii-1) =
$ busper(tsc+ii-1) + busper(tss+ii-1)
end do
goto 50
endif
*
if (bus_oname(i,1).eq.'MIXED') then
do k =1,nks
*VDIR NODEP
do ii=1,nis
bus_o(bus_opar(i,1)+0*nis*njs*nks+(k-1)*nis*njs+
$ (j-1)*nis+ii-1)=busvol(fice+(k-1)*nis+ii-1)
bus_o(bus_opar(i,1)+1*nis*njs*nks+(k-1)*nis*njs+
$ (j-1)*nis+ii-1)=busvol(fice+(k-1)*nis+ii-1) *
$ clp(ii,j,k,ipqc)
bus_o(bus_opar(i,1)+2*nis*njs*nks+(k-1)*nis*njs+
$ (j-1)*nis+ii-1)=(1 -
$ busvol(fice+(k-1)*nis+ii-1))*clp(ii,j,k,ipqc)
end do
end do
goto 50
endif
*
if (bus_oname(i,3).eq.'P') then
*
do im=1,bus_opar(i,4)
do k =1,bus_opar(i,3)
do ii=1,nis
offbo=bus_opar(i,1)+(im-1)*nis*njs*bus_opar(i,3)
offbp=bus_opar(i,6)+(im-1)*nis*bus_opar(i,3)
bus_o(offbo+(k-1)*nis*njs+(j-1)*nis+ii-1) =
$ busper(offbp+(k-1)*nis+ii-1)
end do
end do
end do
*
endif
*
if (bus_oname(i,3).eq.'V') then
*
do im=1,bus_opar(i,4)
do k =1,bus_opar(i,3)
do ii=1,nis
offbo=bus_opar(i,1)+(im-1)*nis*njs*bus_opar(i,3)
offbv=bus_opar(i,6)+(im-1)*nis*bus_opar(i,3)
bus_o(offbo+(k-1)*nis*njs+(j-1)*nis+ii-1) =
$ busvol(offbv+(k-1)*nis+ii-1)
end do
end do
end do
*
endif
*
if (bus_oname(i,3).eq.'D') then
do im=1,bus_opar(i,4)
do k =1,bus_opar(i,3)
do ii=1,nis
offbo=bus_opar(i,1)+(im-1)*nis*njs*bus_opar(i,3)
offbd=bus_opar(i,6)+(im-1)*nis*bus_opar(i,3)
bus_o(offbo+(k-1)*nis*njs+(j-1)*nis+ii-1) =
$ busdyn(offbd+(k-1)*nis+ii-1)
end do
end do
end do
*
endif
*
if (kount.eq.0) then
if (bus_oname(i,3).eq.'E') then
*
do im=1,bus_opar(i,4)
do k =1,bus_opar(i,3)
do ii=1,nis
offbo=bus_opar(i,1)+(im-1)*nis*njs*bus_opar(i,3)
offbe=bus_opar(i,6)+(im-1)*nis*bus_opar(i,3)
bus_o(offbo+(k-1)*nis*njs+(j-1)*nis+ii-1) =
$ busent(offbe+(k-1)*nis+ii-1)
end do
end do
end do
*
endif
endif
*
50 continue
*
if (kount.gt.0) then
*VDIR NODEP
do i=1,nis*nks
busvol(udifv+i-1) = busvol(udifv+i-1) + busper(ufcp+i-1)
busvol(vdifv+i-1) = busvol(vdifv+i-1) + busper(vfcp+i-1)
end do
call tranche2
(busvol(trad) ,ttrad ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(udifv) ,tudifv ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(vdifv) ,tvdifv ,j,nis,njs,nks,nis,nks,23)
if (wdifv.gt.0)
$call tranche2 (busvol(wdifv) ,twdifv ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(tdifv) ,ttdifv ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(qdifv) ,thudifv ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(ugwd) ,tugwd ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(vgwd) ,tvgwd ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(tcond) ,ttcond ,j,nis,njs,nks,nis,nks,23)
call tranche2
(busvol(hucond) ,thucond ,j,nis,njs,nks,nis,nks,23)
if((qccond.gt.0).and.(ipqc.gt.0))
$ call tranche2
(busvol(qccond) ,cltend(1,1,1,ipqc) ,j,
$ nis,njs,nks,nis,nks,23)
if((qrcond.gt.0).and.(ipqr.gt.0))
$ call tranche2
(busvol(qrcond) ,cltend(1,1,1,ipqr) ,j,
$ nis,njs,nks,nis,nks,23)
if((qicond.gt.0).and.(ipqi.gt.0))
$ call tranche2
(busvol(qicond) ,cltend(1,1,1,ipqi) ,j,
$ nis,njs,nks,nis,nks,23)
if((qgcond.gt.0).and.(ipqg.gt.0))
$ call tranche2
(busvol(qgcond) ,cltend(1,1,1,ipqg) ,j,
$ nis,njs,nks,nis,nks,23)
if((edifv.gt.0) .and.(ipen.gt.0))
$ call tranche2
(busvol(edifv) ,cltend(1,1,1,ipen) ,j,
$ nis,njs,nks,nis,nks,23)
*
endif
*
if (.not.incore) then
!$omp critical
xnerr = write_db_file (un_gbusper,j,1)
xnerr = write_db_file (un_gbusper,busper,sizpbus)
!$omp end critical
endif
*
go to 400
*
500 continue
*
*----------------------------------------------------------------------
return
end