Changeset 4152 for trunk/LMDZ.COMMON
- Timestamp:
- Mar 25, 2026, 11:19:02 AM (6 weeks ago)
- Location:
- trunk/LMDZ.COMMON/libf/evolution
- Files:
-
- 14 edited
-
changelog.txt (modified) (1 diff)
-
clim_state_init.F90 (modified) (3 diffs)
-
config.F90 (modified) (2 diffs)
-
deftank/README (modified) (1 diff)
-
deftank/clean.sh (modified) (1 diff)
-
deftank/pcm_run.job (modified) (1 diff)
-
deftank/pem_workflow_lib.sh (modified) (4 diffs)
-
geometry.F90 (modified) (1 diff)
-
io_netcdf.F90 (modified) (1 diff)
-
output.F90 (modified) (12 diffs)
-
pem.F90 (modified) (1 diff)
-
stopping_crit.F90 (modified) (1 diff)
-
surf_ice.F90 (modified) (4 diffs)
-
tendencies.F90 (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/evolution/changelog.txt
r4147 r4152 940 940 - Making the PEM able to do 0 year. 941 941 - Explicit information about the frost values computed by the PEM + enforcing positivity of yearly minima. 942 943 == 25/03/2026 == JBC 944 - Fix outputs "diagevo.nc" for 3D data. 945 - Fix sign in computing exchanges due to adsorption/ice table and in balancing H2O flux from/into atmosphere. 946 - Few cleanings. -
trunk/LMDZ.COMMON/libf/evolution/clim_state_init.F90
r4135 r4152 377 377 378 378 ! H2O ice 379 call print_msg("'h2o_ice' is initialized with default value 'h2oice_huge_ini' where 'watercaptag' is true and where yearly minimum of frost can be considered as a huge reservoir ('threshold_h2oice_cap').",LVL_ NFO)379 call print_msg("'h2o_ice' is initialized with default value 'h2oice_huge_ini' where 'watercaptag' is true and where yearly minimum of frost can be considered as a huge reservoir ('threshold_h2oice_cap').",LVL_WRN) 380 380 h2o_ice(:,:) = 0._dp 381 381 do i = 1,ngrid … … 388 388 389 389 ! CO2 ice 390 call print_msg("'co2_ice' is initialized with 'perennial_co2ice' and yearly minimum of frost found in the PCM.",LVL_ NFO)390 call print_msg("'co2_ice' is initialized with 'perennial_co2ice' and yearly minimum of frost found in the PCM.",LVL_WRN) 391 391 co2_ice(:,:) = co2_perice_PCM(:,:) + co2frost_PCM(:,:) - co2_frost4PCM(:,:) 392 392 … … 486 486 ! Layering 487 487 if (do_layering) then 488 call print_msg('layerings_map is initialized with sub-surface strata.',LVL_ NFO)489 call print_msg("Ice is added with 'h2oice_huge_ini' where 'watercaptag' is true and otherwise with 'perennial_co2ice' found in the PCM.",LVL_ NFO)488 call print_msg('layerings_map is initialized with sub-surface strata.',LVL_WRN) 489 call print_msg("Ice is added with 'h2oice_huge_ini' where 'watercaptag' is true and otherwise with 'perennial_co2ice' found in the PCM.",LVL_WRN) 490 490 do i = 1,ngrid 491 491 if (is_h2o_perice_PCM(i)) then -
trunk/LMDZ.COMMON/libf/evolution/config.F90
r4134 r4152 452 452 ! Initialize physical data 453 453 ! Arguments order: rad, g, mugaz, rcp 454 call print_msg(' > Initializing physical constants',LVL_NFO)454 call print_msg('> Initializing physical constants',LVL_NFO) 455 455 call init_physics(controle(5),controle(7),controle(8),controle(9)) 456 456 457 457 ! Initialize soil data 458 call print_msg(' > Initializing soil parameters',LVL_NFO)458 call print_msg('> Initializing soil parameters',LVL_NFO) 459 459 volcapa = controle(35) 460 460 if (abs(volcapa) < minieps) call stop_clean(__FILE__,__LINE__,'volcapa is 0 in "'//startfi_name//'"!',1) … … 462 462 ! Initialize orbital data 463 463 ! Arguments order: Obliquity, Perihelion, Aphelion, Date of perihelion, Year length, Sol length 464 call print_msg(' > Initializing orbital characteristics of the planet',LVL_NFO)464 call print_msg('> Initializing orbital characteristics of the planet',LVL_NFO) 465 465 call init_orbit(controle(18),controle(15),controle(16),controle(17),controle(14),controle(10)) 466 466 -
trunk/LMDZ.COMMON/libf/evolution/deftank/README
r4110 r4152 62 62 The PEM simulation generates the following files: 63 63 > the usual outputs of the PCM: "restartfi.nc", "restart.nc"/"restart1D.txt", "diagfi.nc", etc; 64 > the XIOS outputs of the PCM: " Xoutdaily4pem*.nc"/"Xoutyearly4pem*.nc";64 > the XIOS outputs of the PCM: "xoutdaily4pem*.nc"/"xoutyearly4pem*.nc"; 65 65 > the outputs of the chained simulation: "pem_workflow.log", "pem_workflow.sts" and possibly "kill_pem_workflow.sh"; 66 66 > the usual outputs of the PEM: "restartevo.nc", "restartfi.nc", "restart.nc"/"restart1D.txt" and "diagevo.nc". -
trunk/LMDZ.COMMON/libf/evolution/deftank/clean.sh
r4110 r4152 19 19 rm -f start*.nc 20 20 rm -f used_* 21 rm -f Xout*4pem*.nc21 rm -f xout*4pem*.nc 22 22 rm -f xios_client_* 23 23 rm -f diag*.nc -
trunk/LMDZ.COMMON/libf/evolution/deftank/pcm_run.job
r4110 r4152 65 65 k=0 66 66 if [ $(echo "$k > 0" | bc) -eq 1 ]; then # Only the last 2 years are taken for the PEM 67 cp Xoutdaily4pem.nc Xoutdaily4pem_Y${k}.nc68 cp Xoutyearly4pem.nc Xoutyearly4pem_Y${k}.nc67 cp xoutdaily4pem.nc xoutdaily4pem_y${k}.nc 68 cp xoutyearly4pem.nc xoutyearly4pem_y${k}.nc 69 69 fi 70 mv Xoutdaily4pem.nc diags/Xoutdaily4pem${i_pcm_run}.nc71 mv Xoutyearly4pem.nc diags/Xoutyearly4pem${i_pcm_run}.nc70 mv xoutdaily4pem.nc diags/xoutdaily4pem${i_pcm_run}.nc 71 mv xoutyearly4pem.nc diags/xoutyearly4pem${i_pcm_run}.nc 72 72 cp restartfi.nc starts/restartfi${i_pcm_run}.nc 73 73 mv restartfi.nc startfi.nc -
trunk/LMDZ.COMMON/libf/evolution/deftank/pem_workflow_lib.sh
r4117 r4152 498 498 cleanup diags/diagfi .nc $i_resume 499 499 cleanup diags/diagsoil .nc $i_resume 500 cleanup diags/ Xoutdaily4pem .nc $i_resume501 cleanup diags/ Xoutyearly4pem .nc $i_resume500 cleanup diags/xoutdaily4pem .nc $i_resume 501 cleanup diags/xoutyearly4pem .nc $i_resume 502 502 cleanup logs/run_pcm .log $i_resume 503 503 cleanup starts/restart1D .txt $i_resume … … 527 527 fi 528 528 if [ $i_resume -eq $(($n_pcm_runs_ini - 1)) ]; then 529 cp diags/ Xoutdaily4pem${i_resume}.nc Xoutdaily4pem_Y1.nc530 cp diags/ Xoutyearly4pem${i_resume}.nc Xoutyearly4pem_Y1.nc529 cp diags/xoutdaily4pem${i_resume}.nc xoutdaily4pem_y1.nc 530 cp diags/xoutyearly4pem${i_resume}.nc xoutyearly4pem_y1.nc 531 531 submit_cycle $1 $n_pcm_runs_ini $i_pcm_run 532 532 elif [ $i_resume -eq $n_pcm_runs_ini ]; then 533 cp diags/ Xoutdaily4pem$(($i_resume - 1)).nc Xoutdaily4pem_Y1.nc534 cp diags/ Xoutyearly4pem$(($i_resume - 1)).nc Xoutyearly4pem_Y1.nc535 cp diags/ Xoutdaily4pem${i_resume}.nc Xoutdaily4pem_Y2.nc536 cp diags/ Xoutyearly4pem${i_resume}.nc Xoutyearly4pem_Y2.nc533 cp diags/xoutdaily4pem$(($i_resume - 1)).nc xoutdaily4pem_y1.nc 534 cp diags/xoutyearly4pem$(($i_resume - 1)).nc xoutyearly4pem_y1.nc 535 cp diags/xoutdaily4pem${i_resume}.nc xoutdaily4pem_y2.nc 536 cp diags/xoutyearly4pem${i_resume}.nc xoutyearly4pem_y2.nc 537 537 submit_pem_phase $1 # The next job is a PEM run 538 538 else … … 554 554 cp starts/restartevo$(($i_pem_run - 1)).nc startevo.nc 555 555 if [ $il -eq $(($n_pcm_runs - 1)) ]; then # Second to last PCM run 556 cp diags/ Xoutdaily4pem${i_resume}.nc Xoutdaily4pem_Y1.nc557 cp diags/ Xoutyearly4pem${i_resume}.nc Xoutyearly4pem_Y1.nc556 cp diags/xoutdaily4pem${i_resume}.nc xoutdaily4pem_y1.nc 557 cp diags/xoutyearly4pem${i_resume}.nc xoutyearly4pem_y1.nc 558 558 submit_cycle $1 $n_pcm_runs $(($il + 1)) 559 559 elif [ $il -eq $n_pcm_runs ]; then # Last PCM run so the next job is a PEM run 560 cp diags/ Xoutdaily4pem$(($i_resume - 1)).nc Xoutdaily4pem_Y1.nc561 cp diags/ Xoutyearly4pem$(($i_resume - 1)).nc Xoutyearly4pem_Y1.nc562 cp diags/ Xoutdaily4pem${i_resume}.nc Xoutdaily4pem_Y2.nc563 cp diags/ Xoutyearly4pem${i_resume}.nc Xoutyearly4pem_Y2.nc560 cp diags/xoutdaily4pem$(($i_resume - 1)).nc xoutdaily4pem_y1.nc 561 cp diags/xoutyearly4pem$(($i_resume - 1)).nc xoutyearly4pem_y1.nc 562 cp diags/xoutdaily4pem${i_resume}.nc xoutdaily4pem_y2.nc 563 cp diags/xoutyearly4pem${i_resume}.nc xoutyearly4pem_y2.nc 564 564 submit_pem_phase $1 565 565 else … … 582 582 cleanup starts/restart .nc $(($i_pcm_run - 1)) 583 583 cleanup starts/restartfi .nc $(($i_pcm_run - 1)) 584 cleanup diags/ Xoutdaily4pem .nc $(($i_pcm_run - 1))585 cleanup diags/ Xoutyearly4pem .nc $(($i_pcm_run - 1))584 cleanup diags/xoutdaily4pem .nc $(($i_pcm_run - 1)) 585 cleanup diags/xoutyearly4pem .nc $(($i_pcm_run - 1)) 586 586 cleanup diags/diagevo .nc $i_resume 587 587 cleanup diags/diagevo_soil .nc $i_resume -
trunk/LMDZ.COMMON/libf/evolution/geometry.F90
r4147 r4152 362 362 ! The longitudes -180 and +180 are duplicated (PCM dynamics). 363 363 ! For extensive variables, the values at the poles must be averaged 364 ! over the number of longitudes for computation on the dynamical grid. 364 ! over the number of longitudes to be computed/outputted on the 365 ! dynamical grid. 365 366 !----------------------------------------------------------------------- 366 367 -
trunk/LMDZ.COMMON/libf/evolution/io_netcdf.F90
r4145 r4152 33 33 character(10), parameter :: startfi_name = 'startfi.nc' 34 34 character(11), parameter :: startevo_name = 'startevo.nc' 35 character(19), parameter :: xios_day_name1 = ' Xoutdaily4pem_Y1.nc' ! XIOS daily output file, second to last PCM year36 character(19), parameter :: xios_day_name2 = ' Xoutdaily4pem_Y2.nc' ! XIOS daily output file, last PCM year37 character(20), parameter :: xios_yr_name1 = ' Xoutyearly4pem_Y1.nc' ! XIOS yearly output file, second to last PCM year38 character(20), parameter :: xios_yr_name2 = ' Xoutyearly4pem_Y2.nc' ! XIOS yearly output file, last PCM year35 character(19), parameter :: xios_day_name1 = 'xoutdaily4pem_y1.nc' ! XIOS daily output file, second to last PCM year 36 character(19), parameter :: xios_day_name2 = 'xoutdaily4pem_y2.nc' ! XIOS daily output file, last PCM year 37 character(20), parameter :: xios_yr_name1 = 'xoutyearly4pem_y1.nc' ! XIOS yearly output file, second to last PCM year 38 character(20), parameter :: xios_yr_name2 = 'xoutyearly4pem_y2.nc' ! XIOS yearly output file, last PCM year 39 39 character(10), parameter :: diagevo_name = 'diagevo.nc' 40 40 -
trunk/LMDZ.COMMON/libf/evolution/output.F90
r4147 r4152 384 384 allocate(var_dyn(nlon_loc,nlat)) 385 385 call vect2dyngrd(longitudes,var_dyn) 386 call put_var_nc('longitude',var_dyn )386 call put_var_nc('longitude',var_dyn(:,1)) 387 387 call vect2dyngrd(latitudes,var_dyn) 388 call put_var_nc('latitude',var_dyn )388 call put_var_nc('latitude',var_dyn(1,:)) 389 389 call put_var_nc('ap',ap) 390 390 call put_var_nc('bp',bp) 391 391 call put_var_nc('soildepth',mlayer) 392 call vect2dyngrd(cell_area,var_dyn )392 call vect2dyngrd(cell_area,var_dyn,extensive = .true.) 393 393 call put_var_nc('cell_area',var_dyn) 394 394 deallocate(var_dyn) … … 402 402 403 403 !======================================================================= 404 SUBROUTINE write_diagevo(var_name,title,units,var,dimids _in)404 SUBROUTINE write_diagevo(var_name,title,units,var,dimids,extensive) 405 405 !----------------------------------------------------------------------- 406 406 ! NAME … … 421 421 ! - If "diagevo.def" holds a list of variable names, then these 422 422 ! are outputted. 423 ! > If 'var' is an array, then the argument 'dimids _in' is mandatory.424 ! 'dimids _in' contains the dimension IDs of the variable in order.423 ! > If 'var' is an array, then the argument 'dimids' is mandatory. 424 ! 'dimids' contains the dimension IDs of the variable in order. 425 425 ! If the variable holds a dimension 'ngrid', then it must appear 426 426 ! in the first position. 427 ! > For extensive variables, the values at the poles must be 428 ! averaged over the number of longitudes to be computed/outputted 429 ! on the dynamical grid. 427 430 !----------------------------------------------------------------------- 428 431 … … 442 445 character(*), intent(in) :: var_name, title, units 443 446 real(dp), dimension(..), intent(in) :: var ! Assumed-rank array 444 integer(di), dimension(:), intent(in), optional :: dimids_in 447 integer(di), dimension(:), intent(in), optional :: dimids 448 logical(k4), intent(in), optional :: extensive 445 449 446 450 ! LOCAL VARIABLES 447 451 ! --------------- 448 integer(di), dimension(:), allocatable :: dimids 452 integer(di), dimension(:), allocatable :: dimids_nc 449 453 integer(di) :: idim_ngrid, nlon_loc, ndim, i, j 450 454 real(dp), dimension(:,:), allocatable :: var_dyn … … 452 456 real(dp), dimension(:,:,:,:), allocatable :: var2d_dyn 453 457 integer(di) :: itime ! Current time index to record variables 458 logical(k4) :: extensive_l 454 459 455 460 … … 474 479 475 480 ! Write the variable 481 extensive_l = .false. 482 if (present(extensive)) extensive_l = extensive 476 483 call open_nc(diagevo_name,'write') ! Open diagevo_name only it is not done yet 477 484 select rank (var) ! Assumed-rank array removes compile-time rank information which is required by the following subroutines using generic interface overload … … 480 487 call put_var_nc(var_name,var,itime) 481 488 rank default ! Arrays 482 if (.not. present(dimids _in)) call stop_clean(__FILE__,__LINE__,'The argument ''dimids_in'' must be present to output arrays!',1)483 ndim = size(dimids _in)484 if (any(dimids _in== dim_ngrid)) then485 idim_ngrid = findloc(dimids _in,dim_ngrid,dim = 1)489 if (.not. present(dimids)) call stop_clean(__FILE__,__LINE__,'The argument ''dimids'' must be present to output arrays!',1) 490 ndim = size(dimids) 491 if (any(dimids == dim_ngrid)) then 492 idim_ngrid = findloc(dimids,dim_ngrid,dim = 1) 486 493 if (idim_ngrid /= 1) call stop_clean(__FILE__,__LINE__,'The dimension ''ngrid'' must be the first one to output the array!',1) 487 allocate(dimids (ndim + 2))488 dimids (1) = dim_nlon489 dimids (2) = dim_nlat490 dimids (3:ndim + 1) = dimids_in(2:ndim)491 dimids (ndim + 2) = dim_time494 allocate(dimids_nc(ndim + 2)) 495 dimids_nc(1) = dim_nlon 496 dimids_nc(2) = dim_nlat 497 dimids_nc(3:ndim + 1) = dimids(2:ndim) 498 dimids_nc(ndim + 2) = dim_time 492 499 if (ngrid == 1) then ! 1D 493 500 nlon_loc = 1 … … 495 502 nlon_loc = nlon + 1 496 503 end if 497 call def_var_nc(var_name,title,units,dimids ) ! Define the variable only it is not done yet504 call def_var_nc(var_name,title,units,dimids_nc) ! Define the variable only it is not done yet 498 505 select rank (var) ! Assumed-rank array removes compile-time rank information which is required by the following subroutines using generic interface overload 499 506 rank(1) 500 507 allocate(var_dyn(nlon_loc,nlat)) 501 call vect2dyngrd(var,var_dyn )508 call vect2dyngrd(var,var_dyn,extensive_l) 502 509 call put_var_nc(var_name,var_dyn,itime) 503 510 deallocate(var_dyn) … … 505 512 allocate(var1d_dyn(nlon_loc,nlat,size(var,2))) 506 513 do i = 1,size(var,2) 507 call vect2dyngrd(var(:,i),var1d_dyn(:,:,i) )514 call vect2dyngrd(var(:,i),var1d_dyn(:,:,i),extensive_l) 508 515 end do 509 516 call put_var_nc(var_name,var1d_dyn,itime) … … 513 520 do i = 1,size(var,2) 514 521 do j = 1,size(var,3) 515 call vect2dyngrd(var(:,i,j),var2d_dyn(:,:,i,j) )522 call vect2dyngrd(var(:,i,j),var2d_dyn(:,:,i,j),extensive_l) 516 523 end do 517 524 end do … … 522 529 end select 523 530 else ! No 'ngrid' dimension 524 allocate(dimids (ndim + 1))525 dimids (1:ndim) = dimids_in(:)526 dimids (ndim + 1) = dim_time527 call def_var_nc(var_name,title,units,dimids ) ! Define the variable only it is not done yet531 allocate(dimids_nc(ndim + 1)) 532 dimids_nc(1:ndim) = dimids(:) 533 dimids_nc(ndim + 1) = dim_time 534 call def_var_nc(var_name,title,units,dimids_nc) ! Define the variable only it is not done yet 528 535 select rank (var) ! Assumed-rank array removes compile-time rank information which is required by the following subroutines using generic interface overload 529 536 rank(1) … … 539 546 end select 540 547 end if 541 deallocate(dimids )548 deallocate(dimids_nc) 542 549 end select 543 550 call close_nc(diagevo_name) -
trunk/LMDZ.COMMON/libf/evolution/pem.F90
r4147 r4152 279 279 idt = 0 280 280 do while (n_yr_run < min(nmax_yr_runorb,nmax_yr_run) .and. n_yr_sim < ntot_yr_sim) 281 call print_msg('**** Iteration of the PEM run [ Planetary years]: '//real2str(n_yr_run + dt),LVL_NFO)281 call print_msg('**** Iteration of the PEM run [plnt yr]: '//real2str(n_yr_run + dt),LVL_NFO) 282 282 ! Evolve global surface pressure 283 283 call evolve_pressure(d_co2ice,delta_co2_ads,do_sorption,ps_avg_glob_old,ps_avg_glob,ps_avg) -
trunk/LMDZ.COMMON/libf/evolution/stopping_crit.F90
r4110 r4152 450 450 S_atm_2_h2o = S_atm_2_h2o + delta_h2o_ads(i)*cell_area(i) 451 451 else 452 S_h2o_2_atm = S_h2o_2_atm +delta_h2o_ads(i)*cell_area(i)452 S_h2o_2_atm = S_h2o_2_atm - delta_h2o_ads(i)*cell_area(i) 453 453 end if 454 454 if (delta_icetable(i) > 0._dp) then 455 455 S_atm_2_h2o = S_atm_2_h2o + delta_icetable(i)*cell_area(i) 456 456 else 457 S_h2o_2_atm = S_h2o_2_atm +delta_icetable(i)*cell_area(i)457 S_h2o_2_atm = S_h2o_2_atm - delta_icetable(i)*cell_area(i) 458 458 end if 459 459 do islope = 1,nslope -
trunk/LMDZ.COMMON/libf/evolution/surf_ice.F90
r4147 r4152 378 378 end if 379 379 380 h2o_ice = h2o_ice + d_h2oice_new*dt381 zshift_surf = d_h2oice_new*dt/rho_h2oice380 h2o_ice(:,:) = h2o_ice(:,:) + d_h2oice_new(:,:)*dt 381 zshift_surf(:,:) = d_h2oice_new(:,:)*dt/rho_h2oice 382 382 383 383 END SUBROUTINE evolve_h2oice … … 385 385 386 386 !======================================================================= 387 SUBROUTINE balance_h2oice_reservoirs(S_atm_2_h2o,S_h2o_2_atm,S_atm_2_h2oice,S_h2oice_2_atm,h2o_ice,d_h2oice,d_ h2oice_new)387 SUBROUTINE balance_h2oice_reservoirs(S_atm_2_h2o,S_h2o_2_atm,S_atm_2_h2oice,S_h2oice_2_atm,h2o_ice,d_h2oice,d_balanced) 388 388 !----------------------------------------------------------------------- 389 389 ! NAME … … 414 414 real(dp), dimension(:,:), intent(in) :: h2o_ice 415 415 real(dp), dimension(:,:), intent(inout) :: d_h2oice 416 real(dp), dimension(:,:), intent(out) :: d_ h2oice_new416 real(dp), dimension(:,:), intent(out) :: d_balanced 417 417 418 418 ! LOCAL VARIABLES 419 419 ! --------------- 420 420 integer(di) :: i, islope 421 real(qp) :: S_ target, S_target_subl_h2oice, S_target_cond_h2oice, S_ghostice ! Balance variables421 real(qp) :: S_corr_subl, S_corr_cond, S_target_subl, S_target_cond, S_ghostice ! Balance variables 422 422 real(dp) :: d_target 423 423 424 424 ! CODE 425 425 ! ---- 426 S_target = (S_atm_2_h2o + S_h2o_2_atm)/2._dp 427 S_target_cond_h2oice = S_atm_2_h2oice + S_target - S_atm_2_h2o 428 S_target_subl_h2oice = S_h2oice_2_atm + S_target - S_h2o_2_atm 429 430 d_h2oice_new = 0._dp 426 ! Compute global targets 427 S_corr_cond = (S_h2o_2_atm - S_atm_2_h2o)/2._qp ! Correction = deviation to the mean 428 S_corr_subl = (S_atm_2_h2o - S_h2o_2_atm)/2._qp ! Correction = deviation to the mean 429 S_target_cond = abs(S_atm_2_h2oice + S_corr_cond) 430 S_target_subl = abs(S_h2oice_2_atm + S_corr_subl) 431 432 ! Compute balanced tendencies with positivity limiter 433 d_balanced(:,:) = 0._dp 431 434 S_ghostice = 0._qp 432 435 do i = 1,ngrid 433 436 do islope = 1,nslope 434 if (d_h2oice(i,islope) > 0._dp) then ! Condens ing435 d_ h2oice_new(i,islope) = d_h2oice(i,islope)*real(S_target_cond_h2oice/S_atm_2_h2oice,dp)436 else if (d_h2oice(i,islope) < 0._dp) then ! Sublimati ng437 d_target = d_h2oice(i,islope)*real(S_target_subl _h2oice/S_h2oice_2_atm,dp)438 if (abs(d_target*dt) <= h2o_ice(i,islope)) then ! Enough ice to sublimate everything439 d_ h2oice_new(i,islope) = d_target440 else ! Not enough ice to sublimate everything441 ! We sublimate what we can442 d_ h2oice_new(i,islope) =h2o_ice(i,islope)/dt443 ! I t means the tendency is zeronext time437 if (d_h2oice(i,islope) > 0._dp) then ! Condensation 438 d_balanced(i,islope) = d_h2oice(i,islope)*real(S_target_cond/S_atm_2_h2oice,dp) 439 else if (d_h2oice(i,islope) < 0._dp) then ! Sublimation 440 d_target = d_h2oice(i,islope)*real(S_target_subl/S_h2oice_2_atm,dp) 441 if (abs(d_target*dt) <= h2o_ice(i,islope)) then ! Enough ice to sublimate 442 d_balanced(i,islope) = d_target 443 else ! Not enough ice to sublimate 444 ! Sublimate all the available ice 445 d_balanced(i,islope) = -h2o_ice(i,islope)/dt 446 ! If fully depleted, zero tendency for next time 444 447 d_h2oice(i,islope) = 0._dp 445 ! We compute the amount of H2O ice that we could not makesublimate446 S_ghostice = S_ghostice + abs(d_target*dt) - h2o_ice(i,islope)448 ! Compute the amount of H2O ice unable to sublimate 449 S_ghostice = S_ghostice + real(abs(d_target*dt),qp) - real(h2o_ice(i,islope),qp) 447 450 end if 448 451 end if … … 450 453 end do 451 454 452 ! We need to remove this ice unable to sublimate from places where ice condensed in order to keep balance453 where (d_ h2oice_new > 0._dp) d_h2oice_new = d_h2oice_new*real((S_target_cond_h2oice - S_ghostice)/S_target_cond_h2oice,dp)455 ! Enforce conservation removing the ghost ice from places where ice condensed 456 where (d_balanced(:,:) > 0._dp) d_balanced(:,:) = d_balanced(:,:)*real((S_target_cond - S_ghostice)/S_target_cond,dp) 454 457 455 458 END SUBROUTINE balance_h2oice_reservoirs -
trunk/LMDZ.COMMON/libf/evolution/tendencies.F90
r4140 r4152 65 65 66 66 ! If the tendency is negative but there is no ice reservoir for the PEM 67 where (d_ice < 0._dp .and. abs(perice) < minieps) d_ice= 0._dp67 where (d_ice(:,:) < 0._dp .and. abs(perice(:,:)) < minieps) d_ice(:,:) = 0._dp 68 68 69 69 END SUBROUTINE compute_tendice … … 89 89 ! DEPENDENCIES 90 90 ! ------------ 91 use geometry, only: ngrid, nslope, nday92 use physics, only: sigmaB, alpha_clap_co2, beta_clap_co2, Lco2, m_co2, A, B93 use orbit, only: yr_len_sol, sol_len_s94 use display, only: print_msg, LVL_NFO95 use utility, only: real2str91 use geometry, only: ngrid, nslope, nday 92 use physics, only: sigmaB, alpha_clap_co2, beta_clap_co2, Lco2, m_co2, A, B 93 use orbit, only: yr_len_sol, sol_len_s 94 use display, only: print_msg, LVL_NFO 95 use utility, only: real2str 96 96 97 97 ! DECLARATION
Note: See TracChangeset
for help on using the changeset viewer.
