source: trunk/LMDZ.MARS/libf/phymars/dust_rad_adjust_mod.F90 @ 2616

Last change on this file since 2616 was 2616, checked in by romain.vande, 3 years ago

LMDZ_MARS RV : Open_MP;
Put all the "save" variables as "!$OMP THREADPRIVATE" in phymars.
The code can now be tested, see README for more info

File size: 5.6 KB
Line 
1module dust_rad_adjust_mod
2
3implicit none
4
5real,save,allocatable :: dust_rad_adjust_prev(:) ! adjustment coefficient
6                         ! computed when at current t_scenario
7real,save,allocatable :: dust_rad_adjust_next(:) ! adjustment coefficient
8                         ! computed for t_scenario of the next sol
9
10!$OMP THREADPRIVATE(dust_rad_adjust_prev,dust_rad_adjust_next)
11
12contains
13
14  subroutine compute_dust_rad_adjust(ngrid,nlayer,zday,pplev, &
15                                     taudust,dust_rad_adjust)
16 
17  use geometry_mod, only: longitude_deg
18  use time_phylmdz_mod, only: dtphys, daysec
19  use dust_param_mod, only: odpref, t_scenario_sol
20 
21  implicit none
22 
23  integer,intent(in) :: ngrid ! number of atmospheric columns
24  integer,intent(in) :: nlayer ! number of atmospheric levels
25  real,intent(in) :: zday ! tim (in sols and fraction thereof)
26  real,intent(in) :: pplev(ngrid,nlayer+1) ! pressure (Pa) at layer boundaries
27  real,intent(in) :: taudust(ngrid) ! visible dust columns opacity in the GCM
28  real,intent(out) :: dust_rad_adjust(ngrid) ! radiative adjustment coefficient
29                      ! for dust
30 
31  real,allocatable,save :: local_time(:) ! LT at current physics time step
32  real,allocatable,save :: local_time_prevdt(:) ! LT at previous physics time step
33  real :: zday_prevdt !value of zday at previous physics time step
34  real,save :: zday_scenario ! to fetch dod values from the scenario
35  real,save :: zday_scenario_next ! to fetch dod values from the scenario the next day
36  logical,save :: firstcall=.true.
37  integer :: ig
38!  real,allocatable,save :: tau_pref_scenario(:)
39  real,allocatable,save :: tau_pref_scenario_next(:)
40  real :: weight ! interpolation weight
41  real,save :: zday_prev_call=-666. ! stored value of zday from previous call
42 
43!$OMP THREADPRIVATE(  local_time,local_time_prevdt,zday_scenario,zday_scenario_next)
44!$OMP THREADPRIVATE(firstcall,tau_pref_scenario_next,zday_prev_call)
45
46 
47  ! 0. preliminary stuff
48  ! NB: this routine may be called multiple times per physics
49  ! so we have to save some arrays to store the information and not
50  ! recompute it for each call
51 
52  if (firstcall) then
53    write(*,*) "compute_dust_rad_adjust: dust scenario assumed exact at", &
54               " time(sol)=",t_scenario_sol
55    allocate(local_time(ngrid))
56    allocate(local_time_prevdt(ngrid))
57!    allocate(tau_pref_scenario(ngrid))
58    allocate(tau_pref_scenario_next(ngrid))
59    firstcall=.false.
60  endif ! of if firstcall
61 
62  ! 1. Compute local times (in sol fraction), if not already done
63  if (zday/=zday_prev_call) then
64    local_time(1:ngrid)=modulo(1.+(zday-INT(zday)) + &
65                         (longitude_deg(1:ngrid)/15)/24,1.)
66    zday_prevdt=zday-dtphys/daysec
67    local_time_prevdt(1:ngrid)=modulo(1.+(zday_prevdt-INT(zday_prevdt)) + &
68                         (longitude_deg(1:ngrid)/15)/24,1.)
69   
70    zday_scenario=zday-modulo(zday,1.) ! integer value of the day: the scenario
71    ! opacity is assumed to be measured at 2pm but stored at nidnight
72    zday_scenario_next=zday_scenario+1
73  endif ! of if (zday/=zday_prev_call)
74 
75  ! 2. Load dust opacities for zday_scenario and zday_scenario_next
76  !    if not already done
77  if (zday/=zday_prev_call) then
78!    call read_dust_scenario(ngrid,nlayer,zday_scenario,pplev,     &
79!                                         tau_pref_scenario)
80    call read_dust_scenario(ngrid,nlayer,zday_scenario_next,pplev, &
81                                         tau_pref_scenario_next)
82  endif ! of if (zday/=zday_prev_call)
83
84  ! 3. Update dust_rad_adjust_* for grid points which just reached 2pm
85  ! but only when this routine is called for the first time
86  ! during this time step
87  if (zday/=zday_prev_call) then
88   do ig=1,ngrid
89    if ((local_time(ig).ge.t_scenario_sol).and. &
90                 (local_time_prevdt(ig).lt.(t_scenario_sol))) then
91      ! store previous "next" as "prev" (NB we could also decide to recompute
92      ! it using the current taudust...)
93      dust_rad_adjust_prev(ig)=dust_rad_adjust_next(ig)
94      ! compute new target based on current dust opacity
95      dust_rad_adjust_next(ig)=tau_pref_scenario_next(ig)* &
96                               pplev(ig,1)/odpref/taudust(ig)
97    endif
98   enddo
99  endif ! of if (zday/=zday_prev_call)
100 
101  ! 4. Compute dust_rad_adjust using linear interpolation
102  ! between dust_rad_adjust_prev and dust_rad_adjust_next
103  do ig=1,ngrid
104    ! prev and next are separated by a sol exactly
105    ! we just need the distance (in sol) between current local time
106    ! and 2pm the day before
107    if (local_time(ig).ge.t_scenario_sol) then
108      ! we are between t_scenario_sol and midnight
109      weight=local_time(ig)-t_scenario_sol
110    else
111      ! we are between midnight and t_scenario_sol of the next day
112      weight=(1.-t_scenario_sol)+local_time(ig)
113    endif
114    dust_rad_adjust(ig)=dust_rad_adjust_prev(ig)+ &
115                        weight* &
116                        (dust_rad_adjust_next(ig)-dust_rad_adjust_prev(ig))
117  enddo! of do=ig=1,ngrid
118 
119  ! update zday_prev_call
120  zday_prev_call=zday
121 
122  end subroutine compute_dust_rad_adjust
123
124!=======================================================================
125! Initialization of the module variables
126
127  subroutine ini_dust_rad_adjust_mod(ngrid)
128       
129  implicit none
130       
131  integer, intent(in) :: ngrid
132       
133  allocate(dust_rad_adjust_prev(ngrid))
134  allocate(dust_rad_adjust_next(ngrid))
135       
136  end subroutine ini_dust_rad_adjust_mod
137       
138  subroutine end_dust_rad_adjust_mod
139       
140  implicit none
141       
142  if (allocated(dust_rad_adjust_prev)) deallocate(dust_rad_adjust_prev)
143  if (allocated(dust_rad_adjust_next)) deallocate(dust_rad_adjust_next)
144
145  end subroutine end_dust_rad_adjust_mod
146
147end module dust_rad_adjust_mod
Note: See TracBrowser for help on using the repository browser.