1 | !DERNIERE VERSION DU SCRIPT D'INTERPOLATION (May 2014) v2.1 |
---|
2 | !Interpolation NL/lineaire rayon 200/400 km + orbital forcing + CO2 decrease interpo lin ou log |
---|
3 | |
---|
4 | module climat_forcage_insolation_mod |
---|
5 | |
---|
6 | ! forcage avec champs mensuels |
---|
7 | ! ce qui a trait aux lacs proglaciaires passe dans un module separe. |
---|
8 | ! les tests sur geoplace sont enleves et sont remplacés par les |
---|
9 | ! lectures de fichers appropries. |
---|
10 | ! fonctionne avec un index en co2 et des snapshots a differents tx de co2 |
---|
11 | ! nouvelle version avec liste des variables utilisées par le module |
---|
12 | ! C. Dumas 07/2015 |
---|
13 | |
---|
14 | use module3D_phy,only:nx,ny,S,H,flot,slv,Tann,Tjuly,Tmois,acc,coefbmshelf,ro,num_param,num_rep_42,dirnameinp,time,pi,dx,xlong,ylat,bsoc |
---|
15 | use netcdf |
---|
16 | use io_netcdf_grisli |
---|
17 | |
---|
18 | implicit none |
---|
19 | |
---|
20 | ! 1=decalaration variables |
---|
21 | !------------------------- |
---|
22 | |
---|
23 | integer :: nft ! NFT est le nombre de lignes a lire dans le fichier contenant le forcage climatique |
---|
24 | integer :: np ! nbr de points englaces poses |
---|
25 | |
---|
26 | integer,parameter :: mois=12 |
---|
27 | integer,parameter :: ntr=2 ! nb de snapshots selon les paramètres orbitaux |
---|
28 | integer,parameter :: gtr=4 ! nb de snapshots selon l'état de la calotte |
---|
29 | integer,parameter :: ctr=4 ! nb de snapshots selon le CO2 |
---|
30 | real,dimension(ctr) :: Seuil_haut |
---|
31 | real,dimension(ctr) :: Seuil_bas |
---|
32 | integer :: CO2SnapMin,CO2SnapMax |
---|
33 | character(len=12) :: orbital_interpolation='La2004' !Choose between La2004, constant and sinusoid |
---|
34 | character(len=12) :: ice_int='yes' !Choose between yes and no |
---|
35 | character(len=12) :: interpolation_ice='nonlinear' !Choose between linear and nonlinear |
---|
36 | integer :: rayon_interpolation_ice=60 !(In km) Choose a multiple of nx. |
---|
37 | |
---|
38 | !real :: poids_nb_points=0.5 |
---|
39 | !real :: poids_proximity=0.5 |
---|
40 | character(len=15) :: CO2_function='variable' !Choose between variable and constant |
---|
41 | integer :: nb_slope_dis_CO2 ! nbr de ligne fichier CO2 |
---|
42 | real :: CO2_value=980. |
---|
43 | character(len=12) :: interpolation_CO2='logarithmic' !Choose between linear and logarithmic |
---|
44 | |
---|
45 | !integer :: itr ! index of snapshot |
---|
46 | real :: coefsin ! coef pour param orbitaux |
---|
47 | double precision :: factsin |
---|
48 | real :: orbite |
---|
49 | real :: coefCO2,ccoefCO2 |
---|
50 | real :: factCO2 |
---|
51 | real :: surf_test |
---|
52 | real :: retroicecoeff |
---|
53 | real,dimension(ntr) :: summorb !Contient la moyenne DJF ou JJA de l'insolation pour |
---|
54 | ! chacun des paramètres orbitaux. On a WSO = 485 W.m-² et CSO = 382.2 W.m-² |
---|
55 | real,dimension(ctr,gtr) :: palier_ice |
---|
56 | real,dimension(ctr) :: palier_CO2 |
---|
57 | |
---|
58 | real,dimension(nx,ny,mois,ntr) :: Tm ! temperature mensuelle de chaque tranche |
---|
59 | real,dimension(nx,ny,mois,ntr) :: Pm ! precipitation mensuelle |
---|
60 | |
---|
61 | real,dimension(nx,ny,mois,ctr,gtr,ntr) :: Tm_fin ! tableau d'interpolation stylé |
---|
62 | real,dimension(nx,ny,mois,ctr,gtr,ntr) :: Pm_fin ! tableau d'interpolation stylé |
---|
63 | |
---|
64 | !interpolation sur param orbitaux |
---|
65 | |
---|
66 | !Définition des variables propres au calcul de la fonction d'Insolation |
---|
67 | !Nom du fichier contenant les points de temps et d'insolation récupérés du site |
---|
68 | !de Laskar. |
---|
69 | integer :: w |
---|
70 | !nb de points récupérés par le calcul de Laskar (e.g. 1e6 années avec un point |
---|
71 | !tous les 100 ans => 10001 points) |
---|
72 | integer,parameter :: nb_points_laskar=5001 |
---|
73 | !Les variables TEMPS, INSOL_dec, INSOL_jan, INSOL_fev correspondent au points |
---|
74 | !récupérés directement dans le fichier txt du site de Laskar. INSOL est la |
---|
75 | !moyenne des trois variables précédentes TEMPS_mod est une échelle de temps |
---|
76 | !recalibrée pour débuter à 0 et être échelonnée en années. |
---|
77 | double precision,dimension(nb_points_laskar) :: TEMPS,TEMPS_mod |
---|
78 | double precision,dimension(nb_points_laskar) :: INSOL,INSOL_dec,INSOL_jan,INSOL_fev |
---|
79 | !yp1_ins et ypn_ins sont les dérivés premières au 1er et dernier point de INSOL. |
---|
80 | double precision :: yp1_ins,ypn_ins |
---|
81 | !var_bidon1 et 2 sont des variables inutiles qui servent à ne pas multiplier le |
---|
82 | !nombre de tableaux contenant les différents points de TEMPS. |
---|
83 | real :: var_bidon1,var_bidon2 |
---|
84 | |
---|
85 | real,dimension(nx,ny,mois,ctr,gtr) :: Tm_time_fin_1 ! temperature mensuelle au temps time (non corrige altitude) |
---|
86 | real,dimension(nx,ny,mois,ctr,gtr) :: Pm_time_fin_1 ! precipitation mensuelle au temps time |
---|
87 | |
---|
88 | !interpolation sur surface glace |
---|
89 | !real,allocatable :: nb_points_max(:) |
---|
90 | real,dimension(nx,ny) :: prox_max ! somme des distances pour chaque point |
---|
91 | real,allocatable :: maillage_prox(:,:) ! distance des points autour du point etudie |
---|
92 | real,allocatable :: Hlarge(:,:) ! H avec grille elargie |
---|
93 | integer :: error |
---|
94 | real :: distsq |
---|
95 | real :: real_rayon_ice |
---|
96 | integer :: grid_int ! rayon de recherche en nbr de points de grille |
---|
97 | !integer :: indice |
---|
98 | real,dimension(nx,ny) :: Height_new,Height_old |
---|
99 | real,dimension(nx,ny) :: coeff2_stored |
---|
100 | !real,dimension(nx,ny) :: coeff1_stored,coeff2_stored |
---|
101 | real,dimension(nx,ny,mois,ctr) :: Tm_time_fin_2 ! temperature mensuelle au temps time (non corrige altitude) |
---|
102 | real,dimension(nx,ny,mois,ctr) :: Pm_time_fin_2 ! precipitation mensuelle au temps time |
---|
103 | |
---|
104 | |
---|
105 | !interpolation sur le CO2 |
---|
106 | double precision,allocatable :: CO2_time(:), CO2_val(:) ! depend du nbr de points du fichier CO2 |
---|
107 | real,dimension(nx,ny,mois) :: Tm_time_fin_3 ! temperature mensuelle au temps time (non corrige altitude) |
---|
108 | real,dimension(nx,ny,mois) :: Pm_time_fin_3 ! precipitation mensuelle au temps time |
---|
109 | |
---|
110 | |
---|
111 | real,dimension(nx,ny,mois,ctr,gtr) :: Tm_surf_mod ! correction altitude |
---|
112 | real,dimension(nx,ny,mois,ctr,gtr) :: Pm_surf_mod ! correction altitude |
---|
113 | |
---|
114 | real,dimension(nx,ny,mois) :: Tm_surf ! surface temperature (after topo. correction) |
---|
115 | |
---|
116 | real,dimension(nx,ny,mois) :: Pm_surf ! surface precipitation (after topo. correction) |
---|
117 | |
---|
118 | real,dimension(nx,ny,mois) :: lapserate ! lapse rate |
---|
119 | real :: psolid=2. ! temp limit between liquid and solid precip |
---|
120 | |
---|
121 | character(len=150) :: filin ! nom temporaire |
---|
122 | character(len=100) :: file_temporel ! forcage temporel |
---|
123 | character(len=100),dimension(ctr,gtr,ntr) :: filtr_t !snapshot temp file name |
---|
124 | character(len=100),dimension(ctr,gtr,ntr) :: filtr_p ! precip file |
---|
125 | character(len=100),dimension(ctr,gtr) :: surf_ice ! topo file |
---|
126 | character(len=100),dimension(3) :: orb_file ! orbite file |
---|
127 | character(len=100) :: co2_file ! co2 file |
---|
128 | real,dimension(nx,ny,ctr,gtr) :: Ssnap ! topo reference |
---|
129 | |
---|
130 | real,dimension(nx,ny) :: ZS !< surface topography above sea level |
---|
131 | |
---|
132 | ! specifique greeneem15 : calcul points englace sur Groenland uniquement : |
---|
133 | logical, dimension(nx,ny,2) :: mask_cal ! masque calotte Groenland (comme dans greeneem/output) |
---|
134 | integer,dimension(2) :: INP ! nbr de points englacés |
---|
135 | |
---|
136 | real :: mincoefbmelt ! butoirs pour coefbmshelf |
---|
137 | real :: maxcoefbmelt |
---|
138 | |
---|
139 | |
---|
140 | |
---|
141 | contains |
---|
142 | |
---|
143 | ! 2=lecture des inputs |
---|
144 | !-------------------- |
---|
145 | |
---|
146 | subroutine input_clim ! routine qui permet d'initialiser les variables climatiques |
---|
147 | ! variables locales |
---|
148 | !------------------- |
---|
149 | |
---|
150 | implicit none |
---|
151 | integer :: mo,ti,tj |
---|
152 | character(len=8) :: control ! label to check clim. forc. file (filin) is usable |
---|
153 | integer :: l ! In snapshot files:the first column is the mask, read but not used |
---|
154 | real :: T_surf_ref ! variable de travail calcul temp a l'instant t a la surface S |
---|
155 | integer :: intr |
---|
156 | integer :: igtr |
---|
157 | integer :: ictr |
---|
158 | integer :: k,d1,d2 |
---|
159 | integer :: i,j |
---|
160 | character(len=100) :: file_ncdf !< fichier netcdf |
---|
161 | real*8, dimension(:,:,:), pointer :: data_3D => null() ! donnees lues dans le netcdf |
---|
162 | real*8, dimension(:,:),pointer :: data_2D => null() ! donnees lues dans le netcdf |
---|
163 | |
---|
164 | ! lecture des fichiers snapshots pour tout geoplace |
---|
165 | ! ------------------------------------------------- |
---|
166 | write(6,*) 'fichiers snapshots' |
---|
167 | do ictr=1,ctr ! co2 |
---|
168 | do igtr=1,gtr ! calotte |
---|
169 | do intr=1,ntr ! orbitaux |
---|
170 | |
---|
171 | !temperature |
---|
172 | filin=trim(dirnameinp)//'forcing/'//trim(filtr_t(ictr,igtr,intr)) |
---|
173 | call Read_ncdf_var('t2m',trim(filin),data_3D) ! Temperature |
---|
174 | Tm_fin(:,:,:,ictr,igtr,intr)=data_3D(:,:,:) |
---|
175 | ! write(6,*) trim(filin) |
---|
176 | ! open(20,file=trim(filin)) |
---|
177 | ! do j=1,ny |
---|
178 | ! do i=1,nx |
---|
179 | ! do J=ny,1,-1 |
---|
180 | ! do I=1,nx |
---|
181 | ! read(20,*) ti, tj, (Tm_fin(i,j,mo,ictr,igtr,intr),mo=1,12) |
---|
182 | ! end do |
---|
183 | ! end do |
---|
184 | ! close(20) |
---|
185 | |
---|
186 | !precipitation |
---|
187 | filin=trim(dirnameinp)//'forcing/'//trim(filtr_p(ictr,igtr,intr)) |
---|
188 | call Read_ncdf_var('precip',trim(filin),data_3D) ! precipitation |
---|
189 | Pm_fin(:,:,:,ictr,igtr,intr)=data_3D(:,:,:) |
---|
190 | ! write(6,*) trim(filin) |
---|
191 | ! open(20,file=trim(filin)) |
---|
192 | ! do j=1,ny |
---|
193 | ! do i=1,nx |
---|
194 | ! do J=ny,1,-1 |
---|
195 | ! do I=1,nx |
---|
196 | ! read(20,*) ti, tj, (Pm_fin(i,j,mo,ictr,igtr,intr),mo=1,12) |
---|
197 | ! end do |
---|
198 | ! end do |
---|
199 | ! close(20) |
---|
200 | end do |
---|
201 | |
---|
202 | ! topo |
---|
203 | filin=trim(dirnameinp)//'forcing/'//trim(surf_ice(ictr,igtr)) |
---|
204 | call Read_ncdf_var('TOPO',trim(filin),data_2D) ! topo |
---|
205 | Ssnap(:,:,ictr,igtr)=data_2D(:,:) |
---|
206 | where(Ssnap(:,:,ictr,igtr).eq.0.0) ! Pour PLIOMIP niv marin=25m |
---|
207 | Ssnap(:,:,ictr,igtr)=25.0 |
---|
208 | endwhere |
---|
209 | ! write(6,*) trim(filin) |
---|
210 | ! open(20,file=trim(filin)) |
---|
211 | ! do j=1,ny |
---|
212 | ! do i=1,nx |
---|
213 | ! do J=ny,1,-1 |
---|
214 | ! do I=1,nx |
---|
215 | ! read(20,*) Ssnap(i,j,ictr,igtr) |
---|
216 | ! end do |
---|
217 | ! end do |
---|
218 | ! close(20) |
---|
219 | end do |
---|
220 | end do |
---|
221 | |
---|
222 | |
---|
223 | !Lecture des parametres orbitaux |
---|
224 | select case(trim(orbital_interpolation)) |
---|
225 | case('La2004') |
---|
226 | |
---|
227 | print *,'Laskar 2004 orbital parameters' |
---|
228 | open(70,file=trim(dirnameinp)//'forcing/'//trim(orb_file(1))) |
---|
229 | do w=1,nb_points_laskar |
---|
230 | read(70,*) TEMPS(w),INSOL_dec(w) |
---|
231 | end do |
---|
232 | close(70) |
---|
233 | |
---|
234 | open(71,file=trim(dirnameinp)//'forcing/'//trim(orb_file(2))) |
---|
235 | do w=1,nb_points_laskar |
---|
236 | read(71,*) var_bidon1,INSOL_jan(w) |
---|
237 | end do |
---|
238 | close(71) |
---|
239 | |
---|
240 | open(72,file=trim(dirnameinp)//'forcing/'//trim(orb_file(3))) |
---|
241 | do w=1,nb_points_laskar |
---|
242 | read(72,*) var_bidon2,INSOL_fev(w) |
---|
243 | end do |
---|
244 | close(72) |
---|
245 | |
---|
246 | do w=1,nb_points_laskar |
---|
247 | TEMPS_mod(w) = 1000*TEMPS(w) !+34000000 |
---|
248 | INSOL(w)=(INSOL_dec(w)+INSOL_jan(w)+INSOL_fev(w))/3 |
---|
249 | end do |
---|
250 | |
---|
251 | !derivée 1er et dernier point |
---|
252 | yp1_ins=(INSOL(2)-INSOL(1))/(TEMPS_mod(2)-TEMPS_mod(1)) |
---|
253 | ypn_ins=(INSOL(nb_points_laskar)-INSOL(nb_points_laskar-1))/(TEMPS_mod(nb_points_laskar)-TEMPS_mod(nb_points_laskar-1)) |
---|
254 | |
---|
255 | case('constant') |
---|
256 | print *,'Constant orbital parameters' |
---|
257 | |
---|
258 | case('sinusoid') |
---|
259 | print *,'Sinusoidal variation of orbital parameters' |
---|
260 | |
---|
261 | end select |
---|
262 | |
---|
263 | !Calcul des poids relatifs lies a la position d'un point par rapport a un autre |
---|
264 | select case(trim(ice_int)) |
---|
265 | case('no') |
---|
266 | print *,"Ice interpolation not prescribed" |
---|
267 | |
---|
268 | case('yes') |
---|
269 | print *,"Ice interpolation prescribed" |
---|
270 | |
---|
271 | select case(trim(interpolation_ice)) |
---|
272 | case('linear') |
---|
273 | print *,"Linear ice mode" |
---|
274 | |
---|
275 | case('nonlinear') |
---|
276 | print *,"Non linear ice mode" |
---|
277 | |
---|
278 | ! Calculation of the radius of search in terms of indexes. |
---|
279 | grid_int=nint(rayon_interpolation_ice/(dx/1000.)) |
---|
280 | real_rayon_ice=real(rayon_interpolation_ice) |
---|
281 | print *,grid_int,ntr,gtr,ctr,intr,igtr,ictr |
---|
282 | print*,'dx=',dx |
---|
283 | print*,'rayon_interpolation_ice=',rayon_interpolation_ice |
---|
284 | print*,'grid_int=',grid_int |
---|
285 | ! indice=grid_int |
---|
286 | ! do j=1,ny |
---|
287 | ! do i=1,nx |
---|
288 | !Calculation of the array indice, which stores the number of points |
---|
289 | !taken into account in the interpolation. Practically overAntarctica, |
---|
290 | !it is always equal to the number of points within the circle defined |
---|
291 | !by grid_int, but closer to the edges of the grid, this number is smaller. |
---|
292 | !cdc indice(i,j)=min(min(i,j),min(nx-(i-1),ny-(j-1)))-1 |
---|
293 | !cdc if (indice(i,j).gt.(grid_int)) then |
---|
294 | ! indice(i,j)=grid_int |
---|
295 | !cdc endif |
---|
296 | |
---|
297 | ! if ((j.eq.198).and.(i.eq.25)) then |
---|
298 | ! print *,'time = ',time,'ictr = ',ictr,'np = ',np |
---|
299 | ! print *,'i = ',i,'j = ',j,'indice = ',indice(i,j) |
---|
300 | ! endif |
---|
301 | ! if ((j.eq.197).and.(i.eq.25)) then |
---|
302 | ! print *,'time = ',time,'ictr = ',ictr,'np = ',np |
---|
303 | ! print *,'i = ',i,'j = ',j,'indice = ',indice(i,j) |
---|
304 | ! endif |
---|
305 | ! enddo |
---|
306 | ! enddo |
---|
307 | |
---|
308 | !Allocation of the array nb_points_max, which stores the maximum number of |
---|
309 | !points potentially used in the interpolation for every indice value. |
---|
310 | !allocate(nb_points_max(grid_int),stat=error) |
---|
311 | !if (error.ne.0) then |
---|
312 | ! print *,'error: could not allocate memory for array' |
---|
313 | ! stop |
---|
314 | !endif |
---|
315 | !Allocation of the array prox_max. Same as above but for the proximity |
---|
316 | !parameter. |
---|
317 | !cdc allocate(prox_max(grid_int),stat=error) |
---|
318 | ! if (error.ne.0) then |
---|
319 | ! print *,'error: could not allocate memory for array' |
---|
320 | ! stop |
---|
321 | ! endif |
---|
322 | !Allocation of the array maillage_prox, which stores, for every indice |
---|
323 | !value, the proximity parameter associated with each point within the |
---|
324 | !radius of search. |
---|
325 | allocate(maillage_prox(-grid_int:grid_int,-grid_int:grid_int),stat=error) |
---|
326 | if (error.ne.0) then |
---|
327 | print *,'error: could not allocate memory for array' |
---|
328 | stop |
---|
329 | endif |
---|
330 | ! print*,'Hlarge',grid_int, 1-grid_int, nx+grid_int,ny+grid_int |
---|
331 | |
---|
332 | allocate(Hlarge(1-grid_int:nx+grid_int,1-grid_int:ny+grid_int),stat=error) |
---|
333 | if (error.ne.0) then |
---|
334 | print *,'error: could not allocate memory for array' |
---|
335 | stop |
---|
336 | endif |
---|
337 | Hlarge=0. |
---|
338 | |
---|
339 | !Initialization at 0 for the three arrays allocated before. |
---|
340 | !nb_points_max=0 |
---|
341 | prox_max=0 |
---|
342 | maillage_prox=0 |
---|
343 | |
---|
344 | !Filling of the three arrays. The proximity parameter depends on a ration |
---|
345 | !of exponential functions. |
---|
346 | !cdc do k=1,grid_int |
---|
347 | do d2=-grid_int,grid_int |
---|
348 | do d1=-grid_int,grid_int |
---|
349 | distsq=(abs(d1)*(dx/1000.))**2+(abs(d2)*(dx/1000.))**2 |
---|
350 | !print *,'distsq = ',distsq,'real_rayon_ice =',real_rayon_ice |
---|
351 | if ((sqrt(distsq).le.real_rayon_ice).and.((d1/=0).or.(d2/=0))) then |
---|
352 | !nb_points_max(k)=nb_points_max(k)+1 |
---|
353 | !cdc prox_max(k)=prox_max(k)+100*exp(-((-1*log(0.001))/real_rayon_ice)*(sqrt(distsq)))/exp(-((-1*log(0.001))/real_rayon_ice)*(dx/1000.)) |
---|
354 | !Indexes displacement to match elements |
---|
355 | maillage_prox(d1,d2)=100*exp(-((-1*log(0.001))/real_rayon_ice)*(sqrt(distsq)))/exp(-((-1*log(0.001))/real_rayon_ice)*(dx/1000.)) |
---|
356 | !print *,'nb_points_max = ',nb_points_max(k),'prox_max = ',prox_max(k),'maillage_prox = ',maillage_prox(k,d1+(k+1),d2+(k+1)) |
---|
357 | endif |
---|
358 | enddo |
---|
359 | enddo |
---|
360 | !cdc enddo |
---|
361 | |
---|
362 | |
---|
363 | prox_max(:,:)=SUM(maillage_prox(:,:)) |
---|
364 | ! PRINT *,'maillage_prox =',maillage_prox(:,:) |
---|
365 | ! PRINT*,'sum(maillage_prox)',SUM(maillage_prox(:,:)) |
---|
366 | ! PRINT*,'fin calcul maillage prox' |
---|
367 | end select |
---|
368 | end select |
---|
369 | |
---|
370 | Height_new=0. |
---|
371 | Height_old=0. |
---|
372 | !coeff1_stored=0. |
---|
373 | coeff2_stored=0. |
---|
374 | |
---|
375 | select case(trim(CO2_function)) |
---|
376 | case('constant') |
---|
377 | print *,'CO2 kept constant at ',CO2_value |
---|
378 | |
---|
379 | case('variable') |
---|
380 | print *,'The CO2 will vary with time' |
---|
381 | open(75,file=trim(dirnameinp)//'forcing/'//trim(co2_file)) |
---|
382 | read(75,*) nb_slope_dis_CO2 |
---|
383 | allocate(CO2_time(nb_slope_dis_CO2),stat=error) |
---|
384 | if (error.ne.0) then |
---|
385 | print *,'error: could not allocate memory for array CO2_time' |
---|
386 | stop |
---|
387 | endif |
---|
388 | allocate(CO2_val(nb_slope_dis_CO2),stat=error) |
---|
389 | if (error.ne.0) then |
---|
390 | print *,'error: could not allocate memory for array CO2_val' |
---|
391 | stop |
---|
392 | endif |
---|
393 | do w=1,nb_slope_dis_CO2 |
---|
394 | read(75,*) CO2_time(w),CO2_val(w) |
---|
395 | end do |
---|
396 | close(75) |
---|
397 | !print *,'CO2_time = ',CO2_time(:),'CO2_val = ',CO2_val(:) |
---|
398 | end select |
---|
399 | |
---|
400 | |
---|
401 | ! initilisation region Groenland pour calcul nbr points englaces |
---|
402 | mask_cal(:,:,:)=.false. |
---|
403 | mask_cal(:,:,1)=.true. |
---|
404 | do j=1,ny |
---|
405 | do i=1,nx |
---|
406 | ! -- Groenland |
---|
407 | IF ( (((xlong(i,j).ge.290).AND.(xlong(i,j).le.350)).AND. & |
---|
408 | ((ylat(i,j).ge.79.5).AND.(ylat(i,j).le.85))).OR. & |
---|
409 | (((xlong(i,j).ge.286).AND.(xlong(i,j).lt.345)).AND. & |
---|
410 | ((ylat(i,j).ge.75).AND.(ylat(i,j).le.79.5))).OR. & |
---|
411 | (((xlong(i,j).ge.300).AND.(xlong(i,j).le.345)).AND. & |
---|
412 | ((ylat(i,j).ge.67).AND.(ylat(i,j).le.75))).OR. & |
---|
413 | (((xlong(i,j).ge.305).AND.(xlong(i,j).le.330)).AND. & |
---|
414 | ((ylat(i,j).ge.55).AND.(ylat(i,j).le.67))) ) mask_cal(i,j,2)=.true. |
---|
415 | enddo |
---|
416 | enddo |
---|
417 | |
---|
418 | |
---|
419 | end subroutine input_clim |
---|
420 | !-------------------------------------------------------------------------------- |
---|
421 | !subroutine input_climat_ref |
---|
422 | ! quand on traite en absolu, pas besoin du climat de reference |
---|
423 | |
---|
424 | !end subroutine input_climat_ref |
---|
425 | |
---|
426 | |
---|
427 | |
---|
428 | SUBROUTINE init_forclim |
---|
429 | |
---|
430 | ! fichiers snapshots |
---|
431 | namelist/snap_forcage_mois_JB/filtr_t,filtr_p,Seuil_haut,Seuil_bas,summorb,palier_ice,surf_ice,palier_CO2,orb_file,co2_file ! ce bloc est a dupliquer pour chaque snapshot en changeant ! la numerotation. ntr snapshots |
---|
432 | |
---|
433 | ! forcage temporel |
---|
434 | !------------------ |
---|
435 | namelist/forc_temporel/file_temporel,mincoefbmelt,maxcoefbmelt |
---|
436 | |
---|
437 | ! lecture par namelist |
---|
438 | !--------------------- |
---|
439 | ! formats pour les ecritures dans 42 |
---|
440 | 428 format(A) |
---|
441 | rewind(num_param) ! pour revenir au debut du fichier param_list.dat |
---|
442 | read(num_param,snap_forcage_mois_JB) |
---|
443 | write(num_rep_42,428)'!___________________________________________________________' |
---|
444 | write(num_rep_42,428) '&snap_forcage_mois_JB ! module climat-forcage-insolation_mod' |
---|
445 | write(num_rep_42,'(A,A)') 'filtr_t = ', filtr_t |
---|
446 | write(num_rep_42,'(A,A)') 'filtr_p = ', filtr_p |
---|
447 | write(num_rep_42,'(A,2(f7.1,","))') 'Seuil_haut = ', Seuil_haut(:) |
---|
448 | write(num_rep_42,'(A,2(f7.1,","))') 'Seuil_bas = ', Seuil_bas(:) |
---|
449 | write(num_rep_42,'(A,2(f5.1,","))') 'summorb = ', summorb(:) |
---|
450 | write(num_rep_42,'(A,2(f7.1,","))') 'palier_ice = ', palier_ice(:,:) |
---|
451 | write(num_rep_42,'(A,A)') 'surf_ice = ', surf_ice |
---|
452 | write(num_rep_42,'(A,2(f3.1,","))') 'palier_CO2 = ', palier_CO2(:) |
---|
453 | write(num_rep_42,'(A,A)') 'orb_file = ', orb_file |
---|
454 | write(num_rep_42,'(A,A)') 'co2_file = ', co2_file |
---|
455 | write(num_rep_42,*)'/' |
---|
456 | write(num_rep_42,428) '! fichiers temperature et precip : 12 mois ordre : ' |
---|
457 | write(num_rep_42,428) '! 1/ CO2, 2/ regrowth, 3/ insol. insolmax_regrowthmaw_co2max --> insolmin_noice_co2min ' |
---|
458 | write(num_rep_42,*) |
---|
459 | |
---|
460 | ! do i=1,ntr |
---|
461 | ! glaciaire |
---|
462 | ! write(filtr_t(i),'(A,i3,A)') filtr_t1(1:32),int(ttr(i)),filtr_t1(36:50) |
---|
463 | ! write(filtr_p(i),'(A,i3,A)') filtr_p1(1:34),int(ttr(i)),filtr_p1(38:52) |
---|
464 | ! write(filtr_t(i),'(A)') filtr_t |
---|
465 | ! write(filtr_p(i),'(A)') filtr_p |
---|
466 | ! enddo |
---|
467 | |
---|
468 | |
---|
469 | call lect_lapserate_months ! lit les lasperate mensuels |
---|
470 | ! pour une version spatialisee ecrire une autre routine |
---|
471 | ! fichiers donnant l'evolution temporelle |
---|
472 | ! ---------------------------- ------------ |
---|
473 | |
---|
474 | rewind(num_param) ! pour revenir au debut du fichier param_list.dat |
---|
475 | read(num_param,forc_temporel) |
---|
476 | |
---|
477 | write(num_rep_42,428)'!___________________________________________________________' |
---|
478 | write(num_rep_42,428) '&forc_temporel ! module climat_forcage_mois_mod' |
---|
479 | write(num_rep_42,'(A,A)') 'file_temporel =', file_temporel |
---|
480 | write(num_rep_42,*) 'mincoefbmelt =', mincoefbmelt |
---|
481 | write(num_rep_42,*) 'maxcoefbmelt =', maxcoefbmelt |
---|
482 | write(num_rep_42,*)'/' |
---|
483 | write(num_rep_42,428) '!fichier forcage temporel pour snapshot' |
---|
484 | write(num_rep_42,*) |
---|
485 | |
---|
486 | |
---|
487 | end subroutine init_forclim |
---|
488 | !--------------------------------------------------------------------- |
---|
489 | |
---|
490 | !forcage climatique au cours du temps |
---|
491 | |
---|
492 | subroutine forclim |
---|
493 | |
---|
494 | implicit none |
---|
495 | |
---|
496 | real COEFT,COEFP ! |
---|
497 | !integer l ! dumm index for loops on snapshots files l=ITR,NTR-1 |
---|
498 | !cdc integer itr ! index of the current snapshot file (change with time) |
---|
499 | |
---|
500 | integer mo |
---|
501 | integer :: ictr |
---|
502 | integer :: igtr |
---|
503 | |
---|
504 | |
---|
505 | !Définition des variables propres au calcul de la fonction d'Insolation |
---|
506 | !y2_ins est le tableau contenant l'ensemble des dérivées secondes au points considérés (cf calcul de |
---|
507 | !l'interpolation par spline cubique). |
---|
508 | double precision,dimension(nb_points_laskar) :: y2_ins |
---|
509 | !insolval est la valeur de l'insolation d'été au pas de temps considere |
---|
510 | double precision :: insolval |
---|
511 | |
---|
512 | !initialisation des paramètres pour l'interpolation entre les fichiers de glace |
---|
513 | !real,allocatable :: sub_H(:,:) |
---|
514 | !real,allocatable :: sub_maillage_prox(:,:) |
---|
515 | !real :: nb_points,prox |
---|
516 | real :: prox |
---|
517 | !real,dimension(nx,ny) :: coeff1,coeff2 |
---|
518 | real,dimension(nx,ny) :: coeff2 |
---|
519 | integer :: k1,k2,m1,m2 |
---|
520 | integer,dimension(nx,ny) :: Mask,Mask2 |
---|
521 | integer :: update_H |
---|
522 | integer :: i,j,l |
---|
523 | |
---|
524 | !Definition des variables pour le calcul de la fonction de CO2 |
---|
525 | double precision :: coefCO2 |
---|
526 | |
---|
527 | !***************************************************************************** |
---|
528 | ! triple interpolation orbite, glace, CO2 + correction altitude |
---|
529 | !***************************************************************************** |
---|
530 | |
---|
531 | |
---|
532 | select case(trim(CO2_function)) |
---|
533 | case('constant') |
---|
534 | CO2SnapMin=1 |
---|
535 | CO2SnapMax=1 |
---|
536 | |
---|
537 | case('variable') |
---|
538 | if (time.le.CO2_time(1)) then |
---|
539 | CO2_value=CO2_val(1) |
---|
540 | else if (time.ge.CO2_time(nb_slope_dis_CO2)) then |
---|
541 | CO2_value=CO2_val(nb_slope_dis_CO2) |
---|
542 | else |
---|
543 | l=1 |
---|
544 | do while (time.gt.CO2_time(l)) |
---|
545 | l = l+1 |
---|
546 | end do |
---|
547 | |
---|
548 | CO2_value=(((CO2_val(l)-CO2_val(l-1))/(CO2_time(l)-CO2_time(l-1)))*(time-CO2_time(l-1))+CO2_val(l-1)) |
---|
549 | |
---|
550 | ! pour ne pas depasser les valeurs CO2 des 2 snapshots min et max CO2 |
---|
551 | if (CO2_value.lt.palier_CO2(ctr)) then |
---|
552 | CO2_value=palier_CO2(ctr) |
---|
553 | else if (CO2_value.gt.palier_CO2(1)) then |
---|
554 | CO2_value=palier_CO2(1) |
---|
555 | endif |
---|
556 | |
---|
557 | endif |
---|
558 | |
---|
559 | l=1 |
---|
560 | do while (CO2_value.lt.palier_CO2(l+1)) |
---|
561 | l=l+1 |
---|
562 | enddo |
---|
563 | CO2SnapMin=l |
---|
564 | CO2SnapMax=l+1 |
---|
565 | print *,'time = ',time,'CO2_value = ',CO2_value, 'CO2SnapMin = ',CO2SnapMin,'CO2SnapMax = ',CO2SnapMax |
---|
566 | |
---|
567 | ! if (CO2_value.ge.360) then |
---|
568 | ! CO2SnapMin=1 |
---|
569 | ! CO2SnapMax=2 |
---|
570 | ! else if ((coefCO2.lt.360).and.(coefCO2.ge.280)) then |
---|
571 | ! CO2SnapMin=2 |
---|
572 | ! CO2SnapMax=3 |
---|
573 | ! else if (coefCO2.lt.280) then |
---|
574 | ! CO2SnapMin=3 |
---|
575 | ! CO2SnapMax=4 |
---|
576 | ! endif |
---|
577 | |
---|
578 | !print *,'CO2SnapMin = ',CO2SnapMin,'CO2SnapMax = ',CO2SnapMax |
---|
579 | end select |
---|
580 | |
---|
581 | !************************************************************************* |
---|
582 | !* triple interpolation orbite, glace, CO2 + correction altitude * |
---|
583 | !************************************************************************* |
---|
584 | |
---|
585 | |
---|
586 | !Nouvelle fonction d'interpolation des param orbitaux qui permet de récupérer |
---|
587 | !l'insolation réelle de Laskar 2004 |
---|
588 | |
---|
589 | |
---|
590 | select case(trim(orbital_interpolation)) |
---|
591 | case('La2004') |
---|
592 | |
---|
593 | call spline(TEMPS_mod,INSOL,nb_points_laskar,yp1_ins,ypn_ins,y2_ins) |
---|
594 | |
---|
595 | call splint(TEMPS_mod,INSOL,y2_ins,nb_points_laskar,insolval) |
---|
596 | |
---|
597 | ! Dans massud_param_list.dat, les snapshots doivent etre dans l'ordre |
---|
598 | ! decroissant partant du plus chaud |
---|
599 | if (insolval.gt.summorb(1)) then |
---|
600 | Tm_time_fin_1(:,:,:,:,:)=Tm_fin(:,:,:,:,:,1) |
---|
601 | Pm_time_fin_1(:,:,:,:,:)=Pm_fin(:,:,:,:,:,1) |
---|
602 | else if (insolval.lt.summorb(ntr)) then |
---|
603 | Tm_time_fin_1(:,:,:,:,:)=Tm_fin(:,:,:,:,:,ntr) |
---|
604 | Pm_time_fin_1(:,:,:,:,:)=Pm_fin(:,:,:,:,:,ntr) |
---|
605 | else |
---|
606 | l=1 |
---|
607 | do while (insolval.lt.summorb(l)) |
---|
608 | l = l+1 |
---|
609 | enddo |
---|
610 | factsin=(insolval-summorb(l))/(summorb(l-1)-summorb(l)) |
---|
611 | Tm_time_fin_1(:,:,:,:,:)=Tm_fin(:,:,:,:,:,l-1)*factsin+Tm_fin(:,:,:,:,:,l)*(1-factsin) |
---|
612 | Pm_time_fin_1(:,:,:,:,:)=Pm_fin(:,:,:,:,:,l-1)*factsin+Pm_fin(:,:,:,:,:,l)*(1-factsin) |
---|
613 | endif |
---|
614 | |
---|
615 | |
---|
616 | case('constant') |
---|
617 | !Tm_time_fin_1(:,:,:,:,:)=(Tm_fin(:,:,:,:,:,1)+Tm_fin(:,:,:,:,:,2))/2 |
---|
618 | !Pm_time_fin_1(:,:,:,:,:)=(Pm_fin(:,:,:,:,:,1)+Pm_fin(:,:,:,:,:,2))/2 |
---|
619 | Tm_time_fin_1(:,:,:,:,:)=Tm_fin(:,:,:,:,:,1) |
---|
620 | Pm_time_fin_1(:,:,:,:,:)=Pm_fin(:,:,:,:,:,1) |
---|
621 | |
---|
622 | |
---|
623 | case('sinusoid') |
---|
624 | orbite=(1+sin(2*pi*time/40000.))/2. |
---|
625 | Tm_time_fin_1(:,:,:,:,:)=orbite*Tm_fin(:,:,:,:,:,1)+(1-orbite)*Tm_fin(:,:,:,:,:,2) |
---|
626 | Pm_time_fin_1(:,:,:,:,:)=orbite*Pm_fin(:,:,:,:,:,1)+(1-orbite)*Pm_fin(:,:,:,:,:,2) |
---|
627 | |
---|
628 | end select |
---|
629 | |
---|
630 | |
---|
631 | !do ictr=CO2SnapMin,CO2SnapMax,1 |
---|
632 | ! do igtr=1,gtr |
---|
633 | ! print *,surf_ice(ictr,igtr) |
---|
634 | ! enddo |
---|
635 | !enddo |
---|
636 | |
---|
637 | |
---|
638 | !Correction d'altitude pour les états |
---|
639 | !il faut que Ssnap soit un tableau avec les différentes hauteurs de glace selon la |
---|
640 | !simulation (no ice, med ice, full ice et 2x, 2.5x, 3x) |
---|
641 | do j=1,ny |
---|
642 | do i=1,nx |
---|
643 | Zs(i,j)=max(slv(i,j),S(i,j)) |
---|
644 | do ictr=CO2SnapMin,CO2SnapMax,1 |
---|
645 | do igtr=1,gtr |
---|
646 | if (Zs(i,j).ge.Ssnap(i,j,ictr,igtr)) then |
---|
647 | do mo=1,mois |
---|
648 | ! correction d'altitude |
---|
649 | Tm_surf_mod(i,j,mo,ictr,igtr)=-lapserate(i,j,mo)*(Zs(i,j)-Ssnap(i,j,ictr,igtr)) & |
---|
650 | +Tm_time_fin_1(i,j,mo,ictr,igtr) |
---|
651 | |
---|
652 | Pm_surf_mod(i,j,mo,ictr,igtr)=Pm_time_fin_1(i,j,mo,ictr,igtr)*exp(0.05*(Tm_surf_mod(i,j,mo,ictr,igtr) & |
---|
653 | -Tm_time_fin_1(i,j,mo,ictr,igtr))) |
---|
654 | |
---|
655 | end do |
---|
656 | else if (Zs(i,j).lt.Ssnap(i,j,ictr,igtr)) then |
---|
657 | do mo=1,mois |
---|
658 | ! correction d'altitude avec condition pour que T ne soit |
---|
659 | ! pas supérieure à la T de l'état sans glace corrigé |
---|
660 | Tm_surf_mod(i,j,mo,ictr,igtr)=min(-lapserate(i,j,mo)*(Zs(i,j)-Ssnap(i,j,ictr,igtr))+Tm_time_fin_1(i,j,mo,ictr,igtr), & |
---|
661 | -lapserate(i,j,mo)*(Zs(i,j)-Ssnap(i,j,ictr,gtr))+Tm_time_fin_1(i,j,mo,ictr,gtr)) |
---|
662 | |
---|
663 | Pm_surf_mod(i,j,mo,ictr,igtr)=Pm_time_fin_1(i,j,mo,ictr,igtr)*exp(0.05*(Tm_surf_mod(i,j,mo,ictr,igtr) & |
---|
664 | -Tm_time_fin_1(i,j,mo,ictr,igtr))) |
---|
665 | end do |
---|
666 | endif |
---|
667 | end do |
---|
668 | end do |
---|
669 | end do |
---|
670 | end do |
---|
671 | !print*,'debug Tm_surf_mod corr vert ', Tm_surf_mod(25,198,1,:,:) |
---|
672 | |
---|
673 | ! calcul du nbr de points glace pose : |
---|
674 | do l=1,2 |
---|
675 | INP(l) = count(mask_cal(:,:,l).and.(H(:,:).gt.2.).and..not.flot(:,:)) |
---|
676 | enddo |
---|
677 | np = INP(2) |
---|
678 | ! np = count((H(:,:).gt.2.).and..not.flot(:,:)) ! version std |
---|
679 | !Interpolation glace |
---|
680 | surf_test=max(0,np) |
---|
681 | Height_new=H |
---|
682 | print *,'time = ',time |
---|
683 | !print *,'CO2SnapMin = ',CO2SnapMin,'CO2SnapMax = ',CO2SnapMax |
---|
684 | !print *,'Seuil_haut(CO2SnapMin) = ',Seuil_haut(CO2SnapMin),'Seuil_haut(CO2SnapMax) = ',Seuil_haut(CO2SnapMax) |
---|
685 | !print *,'Seuil_bas(CO2SnapMin) = ',Seuil_bas(CO2SnapMin),'Seuil_bas(CO2SnapMax) = ',Seuil_bas(CO2SnapMax) |
---|
686 | print *,'surf_test = ',surf_test |
---|
687 | !print *,'coeff1_stored(154,154) = ',coeff1_stored(154,154),'coeff2_stored(154,154) = ',coeff2_stored(154,154) |
---|
688 | !print *,'coeff1_stored(184,184) = ',coeff1_stored(184,184),'coeff2_stored(184,184) = ',coeff2_stored(184,184) |
---|
689 | !print *,'coeff1_stored(200,117) = ',coeff1_stored(200,117),'coeff2_stored(200,117) = ',coeff2_stored(200,117) |
---|
690 | |
---|
691 | select case(trim(ice_int)) |
---|
692 | case('no') |
---|
693 | Tm_time_fin_2(:,:,:,:)=Tm_surf_mod(:,:,:,:,1) |
---|
694 | Pm_time_fin_2(:,:,:,:)=Pm_surf_mod(:,:,:,:,1) |
---|
695 | |
---|
696 | case('yes') |
---|
697 | do ictr=CO2SnapMin,CO2SnapMax,1 |
---|
698 | if (surf_test.ge.Seuil_haut(ictr)) then |
---|
699 | Tm_time_fin_2(:,:,:,ictr)=Tm_surf_mod(:,:,:,ictr,1) |
---|
700 | Pm_time_fin_2(:,:,:,ictr)=Pm_surf_mod(:,:,:,ictr,1) |
---|
701 | |
---|
702 | update_H=1 |
---|
703 | else if (surf_test.le.Seuil_bas(ictr)) then |
---|
704 | Tm_time_fin_2(:,:,:,ictr)=Tm_surf_mod(:,:,:,ictr,gtr) |
---|
705 | Pm_time_fin_2(:,:,:,ictr)=Pm_surf_mod(:,:,:,ictr,gtr) |
---|
706 | |
---|
707 | update_H=0 |
---|
708 | else |
---|
709 | l=1 |
---|
710 | do while (surf_test.lt.palier_ice(ictr,l)) |
---|
711 | l = l+1 |
---|
712 | end do |
---|
713 | |
---|
714 | select case(trim(interpolation_ice)) |
---|
715 | case('linear') |
---|
716 | retroicecoeff=(surf_test-palier_ice(ictr,l))/((palier_ice(ictr,l-1)-palier_ice(ictr,l))) |
---|
717 | Tm_time_fin_2(:,:,:,ictr)=Tm_surf_mod(:,:,:,ictr,l-1)*retroicecoeff+Tm_surf_mod(:,:,:,ictr,l)*(1-retroicecoeff) |
---|
718 | Pm_time_fin_2(:,:,:,ictr)=Pm_surf_mod(:,:,:,ictr,l-1)*retroicecoeff+Pm_surf_mod(:,:,:,ictr,l)*(1-retroicecoeff) |
---|
719 | |
---|
720 | case('nonlinear') |
---|
721 | !Important: the distinction between ice and vegetation points used |
---|
722 | !before has been removed because it would end up with giving the |
---|
723 | !same interpolation. In this code, the calculation is done only over |
---|
724 | !surrounding ice points. |
---|
725 | where (((Height_new > 5.).and.(Height_old < 5.)).or.((Height_new < 5.).and.(Height_old > 5.))) |
---|
726 | Mask = 1. |
---|
727 | elsewhere |
---|
728 | Mask = 0. |
---|
729 | end where |
---|
730 | |
---|
731 | !print *,'Mask = ',Mask |
---|
732 | |
---|
733 | ! allocate(sub_maillage_prox(2*indice+1,2*indice+1),stat=error) |
---|
734 | ! if (error.ne.0) then |
---|
735 | ! print *,'error: could not allocate memory for array' |
---|
736 | ! endif |
---|
737 | |
---|
738 | Mask2 = 0. |
---|
739 | do j=1,ny |
---|
740 | do i=1,nx |
---|
741 | if (Mask(i,j).eq.1) then |
---|
742 | !print *,'i = ',i,'j = ',j,'Mask = ',Mask(i,j) |
---|
743 | do m2=max(1,j-grid_int),min(j+grid_int,ny) !cdc |
---|
744 | do m1=max(i-grid_int,1),min(i+grid_int,nx) !cdc |
---|
745 | Mask2(m1,m2) = 1. |
---|
746 | end do |
---|
747 | end do |
---|
748 | endif |
---|
749 | end do |
---|
750 | end do |
---|
751 | |
---|
752 | !print *,'Mask2 = ',Mask2 |
---|
753 | Hlarge(1:nx,1:ny)=H(:,:) |
---|
754 | do j=1,ny |
---|
755 | do i=1,nx |
---|
756 | if (Mask2(i,j).eq.1) then |
---|
757 | !The number of ice points nb_points is initialized at 0 |
---|
758 | !Same for the proximity parameter, prox. |
---|
759 | !nb_points=0 |
---|
760 | ! prox=0 |
---|
761 | !Case where indice = 0, on the edges of the grid. |
---|
762 | !We actually dont care here because Antarctica is far from the |
---|
763 | !edges of the grid. |
---|
764 | |
---|
765 | !if ((j.eq.154).and.(i.eq.154)) then |
---|
766 | ! print *,'indice =',indice(i,j) |
---|
767 | !endif |
---|
768 | |
---|
769 | !If indice = 0, no interpolation, the climate used comes from |
---|
770 | !the deglaciated simulation (practically, we dont care about |
---|
771 | !this because it concerns only the 1st and last rows and |
---|
772 | !columns of the grid, so not Antarctica.... Could be |
---|
773 | !problematic in other contexts) |
---|
774 | !if (indice(i,j).eq.0) then |
---|
775 | ! Tm_time_fin_2(i,j,:,ictr)=Tm_surf_mod(i,j,:,ictr,l) |
---|
776 | ! Pm_time_fin_2(i,j,:,ictr)=Pm_surf_mod(i,j,:,ictr,l) |
---|
777 | |
---|
778 | !General case |
---|
779 | !else |
---|
780 | !Allocation of the array sub_H, which will be used to count |
---|
781 | !the number of ice points around the focused point. |
---|
782 | !allocate(sub_H(2*indice(i,j)+1,2*indice(i,j)+1),stat=error) |
---|
783 | !if (error.ne.0) then |
---|
784 | ! print *,'error: could not allocate memory for array' |
---|
785 | !endif |
---|
786 | !sub_H is initialized at 1 everywhere except on the |
---|
787 | !focused point which is not taken into account. |
---|
788 | !sub_H=1 |
---|
789 | !sub_H(indice(i,j)+1,indice(i,j)+1)=0 |
---|
790 | |
---|
791 | !where (maillage_prox(indice(i,j),:,:) == 0.) |
---|
792 | ! sub_H(:,:)=0. |
---|
793 | !end where |
---|
794 | |
---|
795 | !Calculation of the number of ice points present around the |
---|
796 | !focused one. |
---|
797 | !nb_points=sum(sub_H,mask=H(i-indice(i,j):i+indice(i,j):1,j-indice(i,j):j+indice(i,j):1).ge.5) |
---|
798 | |
---|
799 | !if ((j.eq.117).and.(i.eq.200)) then |
---|
800 | ! print *,'time =',time,'sub_H =',sub_H(:,:),'nb_points =',nb_points,'H =',H(i-indice(i,j):i+indice(i,j):1,j-indice(i,j):j+indice(i,j):1) |
---|
801 | ! print *,'time =',time,'nb_points =',nb_points |
---|
802 | !endif |
---|
803 | |
---|
804 | !deallocate(sub_H) |
---|
805 | |
---|
806 | !Allocation of the array sub_maillage_prox, which is |
---|
807 | !extracted from the array maillage_prox (calculated above |
---|
808 | !in input_clim) accordingly to the position of the focused |
---|
809 | !point (ie the value of indice). |
---|
810 | ! allocate(sub_maillage_prox(2*indice(i,j)+1,2*indice(i,j)+1),stat=error) |
---|
811 | ! if (error.ne.0) then |
---|
812 | ! print *,'error: could not allocate memory for array' |
---|
813 | ! endif |
---|
814 | !sub_maillage_prox is initialized at 0 everywhere. |
---|
815 | ! sub_maillage_prox=0 |
---|
816 | |
---|
817 | !sub_maillage_prox is then filled with the corresponding |
---|
818 | !values from maillage_prox. |
---|
819 | ! do k2=1,2*indice+1 |
---|
820 | ! do k1=1,2*indice+1 |
---|
821 | ! sub_maillage_prox(k1,k2)=maillage_prox(k1,k2) |
---|
822 | ! end do |
---|
823 | ! end do |
---|
824 | prox=0. |
---|
825 | !Calculation of the proximity parameter. |
---|
826 | ! do k2=max(j-indice,1),min(j+indice,ny) |
---|
827 | ! do k1=max(i-indice,1),min(i+indice,nx) |
---|
828 | ! if (H(k1,k2).ge.5) prox=prox+sub_maillage_prox(k1,k2) |
---|
829 | ! enddo |
---|
830 | ! enddo |
---|
831 | |
---|
832 | ! maillage_prox_ij(i-grid_int:i+grid_int:1,j-grid_int:j+grid_int:1)=maillage_prox |
---|
833 | |
---|
834 | |
---|
835 | |
---|
836 | prox=sum(maillage_prox,mask=Hlarge(i-grid_int:i+grid_int:1,j-grid_int:j+grid_int:1).ge.5) |
---|
837 | |
---|
838 | ! if ((j.eq.198).and.(i.eq.25)) then |
---|
839 | ! print *,'maillage_prox =',maillage_prox(:,:),'prox =',prox |
---|
840 | ! print *,'prox_max =',prox_max(i,j) |
---|
841 | ! endif |
---|
842 | |
---|
843 | ! deallocate(sub_maillage_prox) |
---|
844 | |
---|
845 | !Calculation of the relative coefficient (<1) for the |
---|
846 | !number of points and the proximity. |
---|
847 | !coeff1(i,j)=nb_points/nb_points_max(indice(i,j)) |
---|
848 | coeff2(i,j)=prox/prox_max(i,j) |
---|
849 | ! PRINT*,'i=',i,'j=',j |
---|
850 | ! PRINT*,'prox=',prox |
---|
851 | ! PRINT*,'prox_max=',prox_max(i,j) |
---|
852 | ! PRINT*,'coeff2=',coeff2(i,j) |
---|
853 | ! DO m1=j+grid_int,j-grid_int,-1 |
---|
854 | ! PRINT*,'Hlarge',Hlarge(i-grid_int:i+grid_int:1,m1) |
---|
855 | ! ENDDO |
---|
856 | ! PRINT* |
---|
857 | |
---|
858 | !if (((j.eq.154).and.(i.eq.154)).or.((j.eq.184).and.(i.eq.184)).or.((j.eq.117).and.(i.eq.200))) then |
---|
859 | ! print *,'time = ',time,'i = ',i,'j = ',j,'coeff1 = ',coeff1(i,j),'coeff2 = ',coeff2(i,j) |
---|
860 | !endif |
---|
861 | |
---|
862 | !Interpolation: |
---|
863 | !Tm_surf_mod_noice*((1-a*coeff1)+(1-b*coeff2))/2+Tm_surf_mod_ice*(a*coeff1+b*coeff2)/2 |
---|
864 | !Tm_time_fin_2(i,j,:,ictr)=Tm_surf_mod(i,j,:,ictr,l)*((1-(2*poids_nb_points)*coeff1(i,j))+(1-(2*poids_proximity)*coeff2(i,j)))/2+Tm_surf_mod(i,j,:,ictr,l-1)*((2*poids_nb_points)*coeff1(i,j)+(2*poids_proximity)*coeff2(i,j))/2 |
---|
865 | !Pm_time_fin_2(i,j,:,ictr)=Pm_surf_mod(i,j,:,ictr,l)*((1-(2*poids_nb_points)*coeff1(i,j))+(1-(2*poids_proximity)*coeff2(i,j)))/2+Pm_surf_mod(i,j,:,ictr,l-1)*((2*poids_nb_points)*coeff1(i,j)+(2*poids_proximity)*coeff2(i,j))/2 |
---|
866 | |
---|
867 | !Pour après |
---|
868 | Tm_time_fin_2(i,j,:,ictr)=Tm_surf_mod(i,j,:,ictr,l)*(1-coeff2(i,j))+Tm_surf_mod(i,j,:,ictr,l-1)*coeff2(i,j) |
---|
869 | Pm_time_fin_2(i,j,:,ictr)=Pm_surf_mod(i,j,:,ictr,l)*(1-coeff2(i,j))+Pm_surf_mod(i,j,:,ictr,l-1)*coeff2(i,j) |
---|
870 | |
---|
871 | !coeff1_stored(i,j)=coeff1(i,j) |
---|
872 | coeff2_stored(i,j)=coeff2(i,j) |
---|
873 | !print *,'coeff1_stored(154,154) = ',coeff1_stored(154,154),'coeff2_stored(154,154) = ',coeff2_stored(154,154) |
---|
874 | !print *,'coeff1_stored(184,184) = ',coeff1_stored(184,184),'coeff2_stored(184,184) = ',coeff2_stored(184,184) |
---|
875 | !print *,'coeff1_stored(200,117) = ',coeff1_stored(200,117),'coeff2_stored(200,117) = ',coeff2_stored(200,117) |
---|
876 | !endif |
---|
877 | else |
---|
878 | !Tm_time_fin_2(i,j,:,ictr)=Tm_surf_mod(i,j,:,ictr,l)*((1-(2*poids_nb_points)*coeff1_stored(i,j))+(1-(2*poids_proximity)*coeff2_stored(i,j)))/2+Tm_surf_mod(i,j,:,ictr,l-1)*((2*poids_nb_points)*coeff1_stored(i,j)+(2*poids_proximity)*coeff2_stored(i,j))/2 |
---|
879 | !Pm_time_fin_2(i,j,:,ictr)=Pm_surf_mod(i,j,:,ictr,l)*((1-(2*poids_nb_points)*coeff1_stored(i,j))+(1-(2*poids_proximity)*coeff2_stored(i,j)))/2+Pm_surf_mod(i,j,:,ictr,l-1)*((2*poids_nb_points)*coeff1_stored(i,j)+(2*poids_proximity)*coeff2_stored(i,j))/2 |
---|
880 | !Pour après |
---|
881 | Tm_time_fin_2(i,j,:,ictr)=Tm_surf_mod(i,j,:,ictr,l)*(1-coeff2_stored(i,j))+Tm_surf_mod(i,j,:,ictr,l-1)*coeff2_stored(i,j) |
---|
882 | Pm_time_fin_2(i,j,:,ictr)=Pm_surf_mod(i,j,:,ictr,l)*(1-coeff2_stored(i,j))+Pm_surf_mod(i,j,:,ictr,l-1)*coeff2_stored(i,j) |
---|
883 | endif |
---|
884 | |
---|
885 | end do |
---|
886 | end do |
---|
887 | ! deallocate(sub_maillage_prox) |
---|
888 | end select |
---|
889 | |
---|
890 | update_H=1 |
---|
891 | endif |
---|
892 | end do |
---|
893 | end select |
---|
894 | !print*,'debug Tm_time_fin_2 ', Tm_time_fin_2(25,198,1,:) |
---|
895 | !print*,'debug coeff2_stored ', coeff2_stored(25,198) |
---|
896 | !print*,'debug grid_int ', grid_int |
---|
897 | |
---|
898 | |
---|
899 | !do j=1,ny |
---|
900 | ! do i=1,nx |
---|
901 | ! if (coeff1_stored(i,j).gt.0) then |
---|
902 | ! print *,'i = ',i,'j = ',j,'coeff1_stored = ',coeff1_stored(i,j) |
---|
903 | ! endif |
---|
904 | ! if (coeff2_stored(i,j).gt.0) then |
---|
905 | ! print *,'i = ',i,'j = ',j,'coeff2_stored = ',coeff2_stored(i,j) |
---|
906 | ! endif |
---|
907 | ! end do |
---|
908 | !end do |
---|
909 | |
---|
910 | if (update_H.eq.0) then |
---|
911 | Height_old=0. |
---|
912 | print *,'No update of H' |
---|
913 | else if (update_H.eq.1) then |
---|
914 | Height_old=Height_new |
---|
915 | print *,'H updated' |
---|
916 | else |
---|
917 | print *,'Ice sheet topography error. Exit' |
---|
918 | stop |
---|
919 | endif |
---|
920 | !print *,'time = ',time,'TEMP(200,117) = ',Tm_time_fin_2(200,117,:,ictr),'PRECIP(200,117) = ',Pm_time_fin_2(200,117,:,ictr) |
---|
921 | |
---|
922 | !fonction de décroissance du CO2 |
---|
923 | !CO2 max en 1er puis décroissance dans l'ordre |
---|
924 | |
---|
925 | select case(trim(CO2_function)) |
---|
926 | case('constant') |
---|
927 | Tm_time_fin_3(:,:,:)=Tm_time_fin_2(:,:,:,1) |
---|
928 | Pm_time_fin_3(:,:,:)=Pm_time_fin_2(:,:,:,1) |
---|
929 | |
---|
930 | |
---|
931 | case DEFAULT |
---|
932 | print *,CO2_value |
---|
933 | if (CO2_value.ge.palier_CO2(1)) then |
---|
934 | Tm_time_fin_3(:,:,:)=Tm_time_fin_2(:,:,:,1) |
---|
935 | Pm_time_fin_3(:,:,:)=Pm_time_fin_2(:,:,:,1) |
---|
936 | else if (CO2_value.le.palier_CO2(ctr)) then |
---|
937 | Tm_time_fin_3(:,:,:)=Tm_time_fin_2(:,:,:,ctr) |
---|
938 | Pm_time_fin_3(:,:,:)=Pm_time_fin_2(:,:,:,ctr) |
---|
939 | else |
---|
940 | l=1 |
---|
941 | do while (CO2_value.lt.palier_CO2(l)) |
---|
942 | l = l+1 |
---|
943 | end do |
---|
944 | select case(trim(interpolation_CO2)) |
---|
945 | case('linear') |
---|
946 | factCO2=(CO2_value-palier_CO2(l))/((palier_CO2(l-1)-palier_CO2(l))) |
---|
947 | case('logarithmic') |
---|
948 | factCO2=log(CO2_value/palier_CO2(l))/log(palier_CO2(l-1)/palier_CO2(l)) |
---|
949 | end select |
---|
950 | Tm_time_fin_3(:,:,:)=Tm_time_fin_2(:,:,:,l-1)*factCO2+Tm_time_fin_2(:,:,:,l)*(1-factCO2) |
---|
951 | Pm_time_fin_3(:,:,:)=Pm_time_fin_2(:,:,:,l-1)*factCO2+Pm_time_fin_2(:,:,:,l)*(1-factCO2) |
---|
952 | endif |
---|
953 | end select |
---|
954 | !print*,'debug Tm_time_fin_3 ', Tm_time_fin_3(25,198,1) |
---|
955 | !print *,time,h(196,145),uxbar(196,145),uybar(196,145),bm(196,145) |
---|
956 | |
---|
957 | do i=1,nx |
---|
958 | do j=1,ny |
---|
959 | do mo=1,mois |
---|
960 | Tm_surf(i,j,mo)=Tm_time_fin_3(i,j,mo) |
---|
961 | Pm_surf(i,j,mo)=Pm_time_fin_3(i,j,mo) |
---|
962 | end do |
---|
963 | end do |
---|
964 | end do |
---|
965 | !print*,'debug Tm_surf = Tm_3 ', Tm_surf(25,198,1) |
---|
966 | |
---|
967 | !coefbmshelf coefficient pour la fusion basale sous les ice shelves |
---|
968 | coefbmshelf=1.0 |
---|
969 | coefbmshelf=max(coefbmshelf,mincoefbmelt) |
---|
970 | coefbmshelf=min(coefbmshelf,maxcoefbmelt) |
---|
971 | |
---|
972 | |
---|
973 | |
---|
974 | |
---|
975 | !********************************* |
---|
976 | !Correction d'altitude à vérifier |
---|
977 | !********************************* |
---|
978 | |
---|
979 | |
---|
980 | ! Correction d'altitude pour la temperature y compris sur les lacs |
---|
981 | ! Zs est l'altitude de la surface qu'elle soit mer, glace ou lac |
---|
982 | |
---|
983 | !do j=1,ny |
---|
984 | ! do i=1,nx |
---|
985 | ! ZS(I,J)=max(slv(i,j),S(I,J)) |
---|
986 | ! do mo=1,mois |
---|
987 | ! Tm_surf(i,j,mo)= - lapserate(i,j,mo) * (Zs(i,j)-Ssnap(i,j)) & ! correction d'altitude T |
---|
988 | ! + Tm_time(i,j,mo) |
---|
989 | ! |
---|
990 | ! Pm_surf(i,j,mo)= Pm_time(i,j,mo)*exp(0.05*(Tm_surf(i,j,mo)-Tm_time(i,j,mo))) |
---|
991 | ! |
---|
992 | ! end do |
---|
993 | ! end do |
---|
994 | !end do |
---|
995 | |
---|
996 | |
---|
997 | do mo=1,mois |
---|
998 | Tmois(:,:,mo)=Tm_surf(:,:,mo) |
---|
999 | enddo |
---|
1000 | !print*,'debug Tmois ', Tmois(25,198,1) |
---|
1001 | |
---|
1002 | ! calcul de Tann et Tjuly pour les sorties : |
---|
1003 | Tann(:,:)=sum(Tmois,dim=3)/12. ! moy annuelle |
---|
1004 | Tjuly(:,:)=Tmois(:,:,7) ! temp juillet |
---|
1005 | !print*,'debug Tann ', Tann(25,198) |
---|
1006 | |
---|
1007 | acc(:,:)=sum(Pm_surf,dim=3,mask=Tmois < psolid) ! /12. |
---|
1008 | acc(:,:)=acc(:,:)*1000./ro |
---|
1009 | |
---|
1010 | ! pas beau ATTENTION |
---|
1011 | ! pb plantage zone spitzberg bord de grille !!!!! |
---|
1012 | !do j=180,190 |
---|
1013 | ! do i=123,126 |
---|
1014 | ! acc(i,j)=0. |
---|
1015 | ! print*,'bsoc(i,j)',i,j,bsoc(i,j) |
---|
1016 | ! enddo |
---|
1017 | !enddo |
---|
1018 | |
---|
1019 | END subroutine forclim |
---|
1020 | |
---|
1021 | |
---|
1022 | |
---|
1023 | !************************************************************************ |
---|
1024 | ! Numerical Recipes |
---|
1025 | ! interpolation spline cubique |
---|
1026 | |
---|
1027 | !Récupéré grace à Christophe. Modifié 17.04.13 par JB |
---|
1028 | SUBROUTINE splint(xa,ya,y2a,n,y) |
---|
1029 | INTEGER,intent(in) :: n |
---|
1030 | double precision,dimension(n),intent(in) :: xa,y2a,ya |
---|
1031 | double precision,intent(out) :: y |
---|
1032 | ! Calculates the cubic spline interpolation. |
---|
1033 | ! Given 2 arrays of dimension n, xa and ya, and y2a, the second derivative |
---|
1034 | ! of the function ya at any of the n points, it computes the interpolation for |
---|
1035 | ! the array y of dimension nmax. |
---|
1036 | ! for example, if n is 10001 (e.g. 1e6 years computed with Laskar algorithm and |
---|
1037 | ! a sampling step of 100 years), then nmax would be 1e6 because GRISLI has a |
---|
1038 | ! sampling step of 1 year. |
---|
1039 | INTEGER l |
---|
1040 | REAL a,b,h |
---|
1041 | ! We will find the right place in the table by means of bisection. |
---|
1042 | |
---|
1043 | ! do i=1,nmax |
---|
1044 | ! print *,x(i) |
---|
1045 | ! write (*,*) 'Press Enter to Continue' |
---|
1046 | ! read (*,*) |
---|
1047 | ! enddo |
---|
1048 | |
---|
1049 | !l=1 |
---|
1050 | !do j=1,nmax |
---|
1051 | !if (j==1) then |
---|
1052 | ! l=2 |
---|
1053 | !else if (j==nmax) then |
---|
1054 | ! l=n |
---|
1055 | !else if (x(j).gt.xa(l)) then |
---|
1056 | ! l=l+1 |
---|
1057 | !endif |
---|
1058 | |
---|
1059 | |
---|
1060 | if (time==0) then |
---|
1061 | l=2 |
---|
1062 | else if (time==xa(n)) then |
---|
1063 | l=n |
---|
1064 | else |
---|
1065 | l=1 |
---|
1066 | do while (time.gt.xa(l)) |
---|
1067 | l=l+1 |
---|
1068 | enddo |
---|
1069 | endif |
---|
1070 | |
---|
1071 | |
---|
1072 | h=xa(l)-xa(l-1) |
---|
1073 | a=(xa(l)-time)/h |
---|
1074 | b=(time-xa(l-1))/h |
---|
1075 | y=a*ya(l-1)+b*ya(l)+((a**3-a)*y2a(l-1)+(b**3-b)*y2a(l))*(h**2)/6. |
---|
1076 | |
---|
1077 | ! print *,time,l,xa(l-1),xa(l),ya(l-1),ya(l),h,a,b,y |
---|
1078 | ! write (*,*) 'Press Enter to Continue' |
---|
1079 | ! read (*,*) |
---|
1080 | |
---|
1081 | return |
---|
1082 | |
---|
1083 | END SUBROUTINE splint |
---|
1084 | |
---|
1085 | |
---|
1086 | |
---|
1087 | ! Calculates the 2nd derivative of the y function for any points |
---|
1088 | ! Recupere grace à Christophe. Modifié par JB 18.04.13 |
---|
1089 | SUBROUTINE spline(x,y,n,yp1,ypn,y2) |
---|
1090 | INTEGER,intent(in) :: n |
---|
1091 | double precision,dimension(n), intent(in) :: x,y |
---|
1092 | double precision,dimension(n), intent(out) :: y2 |
---|
1093 | double precision,intent(in) :: yp1,ypn |
---|
1094 | |
---|
1095 | INTEGER i,k |
---|
1096 | double precision :: p,qn,sig,un |
---|
1097 | double precision,dimension(n) :: u |
---|
1098 | |
---|
1099 | if (yp1.gt..99e30) then ! The lower boundary condition is set either to 0 |
---|
1100 | y2(1)=0. |
---|
1101 | u(1)=0. |
---|
1102 | else ! or else to have a specified first derivative. |
---|
1103 | y2(1)=-0.5 |
---|
1104 | u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1) |
---|
1105 | endif |
---|
1106 | do i=2,n-1 |
---|
1107 | ! This is the decomposition loop of the tridiagonal algorithm. y2 and u are used |
---|
1108 | ! for temporary storage of the decomposed factors. |
---|
1109 | |
---|
1110 | sig=(x(i)-x(i-1))/(x(i+1)-x(i-1)) |
---|
1111 | p=sig*y2(i-1)+2. |
---|
1112 | y2(i)=(sig-1.)/p |
---|
1113 | u(i)=(6.*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1)) & |
---|
1114 | /(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*u(i-1))/p |
---|
1115 | enddo |
---|
1116 | |
---|
1117 | if (ypn.gt..99e30) then ! The upper boundary condition is set eith |
---|
1118 | qn=0. |
---|
1119 | un=0. |
---|
1120 | else ! or else to have a specified first derivative. |
---|
1121 | qn=0.5 |
---|
1122 | un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1))) |
---|
1123 | endif |
---|
1124 | y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.) |
---|
1125 | do k=n-1,1,-1 ! This is the backsubstitution loop of the tridiagonal algorithm |
---|
1126 | y2(k)=y2(k)*y2(k+1)+u(k) |
---|
1127 | enddo |
---|
1128 | return |
---|
1129 | |
---|
1130 | END SUBROUTINE spline |
---|
1131 | |
---|
1132 | |
---|
1133 | |
---|
1134 | |
---|
1135 | |
---|
1136 | |
---|
1137 | |
---|
1138 | !------------------------------------------------------------------------------------------------------------ |
---|
1139 | subroutine lect_lapserate_months ! lapserates mensuels mais uniformes spatialement |
---|
1140 | |
---|
1141 | implicit none |
---|
1142 | real,dimension(12) :: lect_lapse ! pour la lecture |
---|
1143 | integer :: i,j |
---|
1144 | |
---|
1145 | namelist/lapse_month/lect_lapse |
---|
1146 | |
---|
1147 | ! lecture de la namelist |
---|
1148 | |
---|
1149 | ! formats pour les ecritures dans 42 |
---|
1150 | 428 format(A) |
---|
1151 | |
---|
1152 | rewind(num_param) ! pour revenir au debut du fichier param_list.dat |
---|
1153 | read(num_param,lapse_month) |
---|
1154 | |
---|
1155 | write(num_rep_42,428)'!___________________________________________________________' |
---|
1156 | write(num_rep_42,428) '&lapse_month ! module climat_forcage_mois_mod' |
---|
1157 | write(num_rep_42,'(A,12(f0.2,","))') 'lapse_month = ', lect_lapse |
---|
1158 | write(num_rep_42,*)'/' |
---|
1159 | write(num_rep_42,428) '! laspe rates janvier -> decembre en deg/km' |
---|
1160 | |
---|
1161 | |
---|
1162 | ! pour repasser en deg/m et copier dans lapserate |
---|
1163 | |
---|
1164 | do j=1,ny |
---|
1165 | do i=1,nx |
---|
1166 | lapserate(i,j,:)=lect_lapse(:)/1000. |
---|
1167 | end do |
---|
1168 | end do |
---|
1169 | end subroutine lect_lapserate_months |
---|
1170 | !-------------------------------------------------------------------------------------------------------- |
---|
1171 | |
---|
1172 | end module climat_forcage_insolation_mod |
---|