Changeset 3297 for trunk


Ignore:
Timestamp:
Apr 8, 2024, 3:49:41 PM (8 months ago)
Author:
jbclement
Message:

PEM:
Integration of the module "layering_mod.F90" with the rest of the PEM:

  • The linked list data structure representative of layered deposits is converted into an array which can be outputed in the "restratpem.nc" files. This array has dimensions (ngrid,nslope,nb_str_max,6) where 'nb_str_max' is the maximum number of 'stratum' through the layerings and '6' is the number of properties of 'stratum';
  • this structure can also be read from "startpem.nc" files to initialize PEM runs;
  • The layering algorithm is now used in the main PEM loop to make the layerings evolve.

JBC

Location:
trunk/LMDZ.COMMON
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.COMMON/arch/arch-gfortran.fcm

    r3180 r3297  
    1 %COMPILER            gfortran
    2 %LINK                gfortran
     1%COMPILER            mpif90
     2%LINK                mpif90
    33%AR                  ar
    44%MAKE                make
     
    77%CPP_DEF             LAPACK
    88%FPP_DEF             NC_DOUBLE
    9 %BASE_FFLAGS         -c -fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -fno-align-commons -fallow-argument-mismatch
    10 %PROD_FFLAGS         -O3
    11 %DEV_FFLAGS          -O
    12 %DEBUG_FFLAGS        -ffpe-trap=invalid,zero,overflow -fbounds-check -g3 -O0 -fstack-protector-all -finit-real=snan -fbacktrace
     9%BASE_FFLAGS         -pg -c -fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -fno-align-commons -fallow-argument-mismatch
     10%PROD_FFLAGS         -O2
     11%DEV_FFLAGS          -O -Wall -fbounds-check
     12%DEBUG_FFLAGS        -fcheck=all -ffree-line-length-0 -Wall -ffpe-trap=invalid,zero,overflow -fbounds-check -g3 -O0 -fstack-protector-all -finit-real=nan -fbacktrace
    1313%C_COMPILER          gcc
    14 %C_OPTIM             -O3
    15 %MPI_FFLAGS
     14%C_OPTIM             -O2
     15%MPI_FFLAGS          -I/usr/lib/x86_64-linux-gnu/openmpi/include
    1616%OMP_FFLAGS         
    17 %BASE_LD     
    18 %MPI_LD
     17%BASE_LD             -pg
     18%MPI_LD              -lmpi
    1919%OMP_LD             
  • trunk/LMDZ.COMMON/arch/arch-gfortran.path

    r3180 r3297  
    11ROOT=$PWD
     2NETCDF="$HOME/netcdf4hdf5"
    23
    34NETCDF_LIBDIR="-L$NETCDF/lib"
  • trunk/LMDZ.COMMON/libf/evolution/changelog.txt

    r3296 r3297  
    265265== 08/04/2024 == JBC
    266266Correction of "launch_pem.sh" in the deftank: the number of years to be simulated was not respected because of extra PCM runs at the end of the simulation due to the order of PCM/PEM runs inside the loop.
     267
     268== 08/04/2024 == JBC
     269Integration of the module "layering_mod.F90" with the rest of the PEM:
     270    - The linked list data structure representative of layered deposits is converted into an array which can be outputed in the "restratpem.nc" files. This array has dimensions (ngrid,nslope,nb_str_max,6) where 'nb_str_max' is the maximum number of 'stratum' through the layerings  and '6' is the number of properties of 'stratum';
     271    - this structure can also be read from "startpem.nc" files to initialize PEM runs;
     272    - The layering algorithm is now used in the main PEM loop to make the layerings evolve.
  • trunk/LMDZ.COMMON/libf/evolution/info_PEM_mod.F90

    r3173 r3297  
    3838    call execute_command_line('sed -i "1s/.*/'//trim(ich1)//' '//trim(ich2)//' '//trim(fch)//'/" info_PEM.txt',cmdstat = cstat)
    3939    if (cstat > 0) then
    40         error stop 'info_PEM: command exection failed!'
     40        error stop 'info_PEM: command execution failed!'
    4141    else if (cstat < 0) then
    4242        error stop 'info_PEM: command execution not supported!'
  • trunk/LMDZ.COMMON/libf/evolution/iostart_PEM.F90

    r3206 r3297  
    22!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    33!!!
    4 !!! Purpose: Read and write specific netcdf for the PEM 
    5 !!! 
    6 !!! 
     4!!! Purpose: Read and write specific netcdf for the PEM
     5!!!
     6!!!
    77!!! Author: LL, inspired by iostart from the PCM
    88!!!
     
    1313    INTEGER,SAVE :: nid_start ! NetCDF file identifier for startfi.nc file
    1414    INTEGER,SAVE :: nid_restart ! NetCDF file identifier for restartfi.nc file
    15    
     15
    1616    ! restartfi.nc file dimension identifiers: (see open_restartphy())
    17     INTEGER,SAVE :: idim1 ! "index" dimension
    18     INTEGER,SAVE :: idim2 ! "physical_points" dimension
    19     INTEGER,SAVE :: idim3 ! "subsurface_layers" dimension
    20     INTEGER,SAVE :: idim4 ! "nlayer_plus_1" dimension
    21     INTEGER,SAVE :: idim5 ! "number_of_advected_fields" dimension
    22     INTEGER,SAVE :: idim6 ! "nlayer" dimension
    23     INTEGER,SAVE :: idim7 ! "Time" dimension
    24     INTEGER,SAVE :: idim8 ! "nslope" dimension
    25     INTEGER,SAVE :: idim9 ! "inter slope" dimension
     17    INTEGER,SAVE :: idim1  ! "index" dimension
     18    INTEGER,SAVE :: idim2  ! "physical_points" dimension
     19    INTEGER,SAVE :: idim3  ! "subsurface_layers" dimension
     20    INTEGER,SAVE :: idim4  ! "nlayer_plus_1" dimension
     21    INTEGER,SAVE :: idim5  ! "number_of_advected_fields" dimension
     22    INTEGER,SAVE :: idim6  ! "nlayer" dimension
     23    INTEGER,SAVE :: idim7  ! "Time" dimension
     24    INTEGER,SAVE :: idim8  ! "nslope" dimension
     25    INTEGER,SAVE :: idim9  ! "inter slope" dimension
     26    INTEGER,SAVE :: idim10 ! "nb_str_max" dimension
    2627    INTEGER,SAVE :: timeindex ! current time index (for time-dependent fields)
    2728    INTEGER,PARAMETER :: length=100 ! size of tab_cntrl array
    28    
     29
    2930    INTERFACE get_field
    3031      MODULE PROCEDURE Get_field_r1,Get_field_r2,Get_field_r3
    3132    END INTERFACE get_field
    32    
     33
    3334    INTERFACE get_var
    3435      MODULE PROCEDURE get_var_r0,Get_var_r1,Get_var_r2,Get_var_r3
     
    4849    PUBLIC inquire_field, inquire_field_ndims
    4950    PUBLIC open_startphy,close_startphy,open_restartphy,close_restartphy
    50    
     51
    5152CONTAINS
    5253
     
    6667      ENDIF
    6768    ENDIF
    68    
     69
    6970    CALL bcast(nid_start) ! tell all procs about nid_start
    70  
     71
    7172  END SUBROUTINE open_startphy
    7273
     
    9394    INTEGER :: varid
    9495    INTEGER :: ierr
    95    
     96
    9697    IF (is_master) THEN
    9798      ierr=NF90_INQ_VARID(nid_start,Field_name,varid)
     
    109110
    110111  FUNCTION inquire_field_ndims(Field_name)
    111   ! give the number of dimensions of "Field_name" stored in the input file 
     112  ! give the number of dimensions of "Field_name" stored in the input file
    112113  USE netcdf, only: nf90_inq_varid, nf90_inquire_variable, &
    113114                    NF90_NOERR, nf90_strerror
     
    118119    INTEGER :: varid
    119120    INTEGER :: ierr
    120    
     121
    121122    IF (is_master) THEN
    122123      ierr=nf90_inq_varid(nid_start,Field_name,varid)
     
    145146    INTEGER :: varid
    146147    INTEGER :: ierr
    147    
     148
    148149    IF (is_master) THEN
    149150      ierr=NF90_INQ_DIMID(nid_start,Field_name,varid)
     
    169170    INTEGER :: varid
    170171    INTEGER :: ierr
    171    
     172
    172173    IF (is_master) THEN
    173174      ierr=nf90_inq_dimid(nid_start,Field_name,varid)
     
    194195    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
    195196    REAL,INTENT(INOUT)               :: Field(:)
    196     LOGICAL,INTENT(OUT),OPTIONAL   :: found 
     197    LOGICAL,INTENT(OUT),OPTIONAL   :: found
    197198    INTEGER,INTENT(IN),OPTIONAL    :: timeindex ! time index of sought data
    198199
     
    211212      CALL Get_field_rgen(field_name,field,1,corners,edges)
    212213    ENDIF
    213      
     214
    214215  END SUBROUTINE Get_Field_r1
    215  
     216
    216217  SUBROUTINE Get_Field_r2(field_name,field,found,timeindex)
    217218  ! For a "3D" horizontal-vertical field
     
    220221    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
    221222    REAL,INTENT(INOUT)               :: Field(:,:)
    222     LOGICAL,INTENT(OUT),OPTIONAL   :: found 
     223    LOGICAL,INTENT(OUT),OPTIONAL   :: found
    223224    INTEGER,INTENT(IN),OPTIONAL    :: timeindex ! time index of sought data
    224225
     
    232233      corners(3)=timeindex
    233234    endif
    234    
     235
    235236    IF (PRESENT(found)) THEN
    236237      CALL Get_field_rgen(field_name,field,size(field,2),&
     
    241242    ENDIF
    242243
    243      
     244
    244245  END SUBROUTINE Get_Field_r2
    245  
     246
    246247  SUBROUTINE Get_Field_r3(field_name,field,found,timeindex)
    247248  ! for a "4D" field surf/alt/??
     
    250251    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
    251252    REAL,INTENT(INOUT)               :: Field(:,:,:)
    252     LOGICAL,INTENT(OUT),OPTIONAL   :: found 
     253    LOGICAL,INTENT(OUT),OPTIONAL   :: found
    253254    INTEGER,INTENT(IN),OPTIONAL    :: timeindex ! time index of sought data
    254255
     
    263264      corners(4)=timeindex
    264265    endif
    265    
     266
    266267    IF (PRESENT(found)) THEN
    267268      CALL Get_field_rgen(field_name,field,size(field,2)*size(field,3),&
     
    271272                          corners,edges)
    272273    ENDIF
    273      
     274
    274275  END SUBROUTINE Get_Field_r3
    275  
     276
    276277  SUBROUTINE Get_field_rgen(field_name,field,field_size, &
    277278                            corners,edges,found)
     
    287288    INTEGER,INTENT(IN) :: edges(4)
    288289    LOGICAL,OPTIONAL :: found
    289    
     290
    290291    REAL    :: field_glo(klon_glo,field_size)
    291292    LOGICAL :: tmp_found
    292293    INTEGER :: varid
    293294    INTEGER :: ierr
    294    
     295
    295296    IF (is_master) THEN
    296  
     297
    297298      ierr=NF90_INQ_VARID(nid_start,Field_name,varid)
    298      
     299
    299300      IF (ierr==NF90_NOERR) THEN
    300301        CALL body(field_glo)
     
    303304        tmp_found=.FALSE.
    304305      ENDIF
    305    
    306     ENDIF
    307    
     306
     307    ENDIF
     308
    308309    CALL bcast(tmp_found)
    309310
     
    311312      CALL scatter(field_glo,field)
    312313    ENDIF
    313    
     314
    314315    IF (PRESENT(found)) THEN
    315316      found=tmp_found
     
    320321      ENDIF
    321322    ENDIF
    322  
    323    
     323
     324
    324325    CONTAINS
    325      
     326
    326327     SUBROUTINE body(field_glo)
    327328       REAL :: field_glo(klon_glo*field_size)
    328329         ierr=NF90_GET_VAR(nid_start,varid,field_glo,corners,edges)
    329330         IF (ierr/=NF90_NOERR) THEN
    330            ! La variable exist dans le fichier mais la lecture a echouee. 
     331           ! La variable exist dans le fichier mais la lecture a echouee.
    331332           write(*,*) 'get_field_rgen: Failed reading <'//field_name//'>'
    332333
     
    353354  SUBROUTINE get_var_r0(var_name,var,found)
    354355  ! Get a scalar from input file
    355   IMPLICIT NONE 
     356  IMPLICIT NONE
    356357    CHARACTER(LEN=*),INTENT(IN)  :: var_name
    357358    REAL,INTENT(INOUT)             :: var
     
    359360
    360361    REAL                         :: varout(1)
    361    
     362
    362363    IF (PRESENT(found)) THEN
    363364      CALL Get_var_rgen(var_name,varout,size(varout),found)
     
    366367    ENDIF
    367368    var=varout(1)
    368  
     369
    369370  END SUBROUTINE get_var_r0
    370371
    371372  SUBROUTINE get_var_r1(var_name,var,found)
    372373  ! Get a vector from input file
    373   IMPLICIT NONE 
     374  IMPLICIT NONE
    374375    CHARACTER(LEN=*),INTENT(IN)  :: var_name
    375376    REAL,INTENT(INOUT)             :: var(:)
    376377    LOGICAL,OPTIONAL,INTENT(OUT) :: found
    377    
     378
    378379    IF (PRESENT(found)) THEN
    379380      CALL Get_var_rgen(var_name,var,size(var),found)
     
    381382      CALL Get_var_rgen(var_name,var,size(var))
    382383    ENDIF
    383  
     384
    384385  END SUBROUTINE get_var_r1
    385386
    386387  SUBROUTINE get_var_r2(var_name,var,found)
    387388  ! Get a 2D field from input file
    388   IMPLICIT NONE 
     389  IMPLICIT NONE
    389390    CHARACTER(LEN=*),INTENT(IN)  :: var_name
    390391    REAL,INTENT(OUT)             :: var(:,:)
    391392    LOGICAL,OPTIONAL,INTENT(OUT) :: found
    392    
     393
    393394    IF (PRESENT(found)) THEN
    394395      CALL Get_var_rgen(var_name,var,size(var),found)
     
    396397      CALL Get_var_rgen(var_name,var,size(var))
    397398    ENDIF
    398  
     399
    399400  END SUBROUTINE get_var_r2
    400401
    401402  SUBROUTINE get_var_r3(var_name,var,found)
    402403  ! Get a 3D field frominput file
    403   IMPLICIT NONE 
     404  IMPLICIT NONE
    404405    CHARACTER(LEN=*),INTENT(IN)  :: var_name
    405406    REAL,INTENT(INOUT)             :: var(:,:,:)
    406407    LOGICAL,OPTIONAL,INTENT(OUT) :: found
    407    
     408
    408409    IF (PRESENT(found)) THEN
    409410      CALL Get_var_rgen(var_name,var,size(var),found)
     
    411412      CALL Get_var_rgen(var_name,var,size(var))
    412413    ENDIF
    413  
     414
    414415  END SUBROUTINE get_var_r3
    415416
     
    424425    REAL             :: var(var_size)
    425426    LOGICAL,OPTIONAL :: found
    426    
     427
    427428    LOGICAL :: tmp_found
    428429    INTEGER :: varid
    429430    INTEGER :: ierr
    430    
     431
    431432    IF (is_mpi_root .AND. is_omp_root) THEN
    432  
     433
    433434      ierr=NF90_INQ_VARID(nid_start,var_name,varid)
    434      
     435
    435436      IF (ierr==NF90_NOERR) THEN
    436437        ierr=NF90_GET_VAR(nid_start,varid,var)
     
    443444        tmp_found=.FALSE.
    444445      ENDIF
    445    
    446     ENDIF
    447    
     446
     447    ENDIF
     448
    448449    CALL bcast(tmp_found)
    449450
     
    451452      CALL bcast(var)
    452453    ENDIF
    453    
     454
    454455    IF (PRESENT(found)) THEN
    455456      found=tmp_found
     
    481482  USE comsoil_h_PEM, only:  nsoilmx_PEM
    482483  USE comslope_mod, only: nslope
     484  use layering_mod, only: nb_str_max
    483485  IMPLICIT NONE
    484486    CHARACTER(LEN=*),INTENT(IN) :: filename
     
    490492    nqmx=nqtot
    491493#endif
    492    
     494
    493495    IF (is_master) THEN
    494496      if (.not.already_created) then
     
    526528        CALL abort_physic("open_restartphy","Failed defining index",1)
    527529      ENDIF
    528      
     530
    529531      ierr=NF90_DEF_DIM(nid_restart,"physical_points",klon_glo,idim2)
    530532      IF (ierr/=NF90_NOERR) THEN
     
    533535        CALL abort_physic("open_restartphy","Failed defining physical_points",1)
    534536      ENDIF
    535      
     537
    536538      ierr=NF90_DEF_DIM(nid_restart,"subsurface_layers",nsoilmx_PEM,idim3)
    537539      IF (ierr/=NF90_NOERR) THEN
     
    540542        CALL abort_physic("open_restartphy","Failed defining subsurface_layers",1)
    541543      ENDIF
    542      
     544
    543545      ierr=NF90_DEF_DIM(nid_restart,"nlayer_plus_1",klevp1,idim4)
    544546      IF (ierr/=NF90_NOERR) THEN
     
    547549        CALL abort_physic("open_restartphy","Failed defining nlayer_plus_1",1)
    548550      ENDIF
    549      
     551
    550552      if (nqmx.ne.0) then
    551553        ierr=NF90_DEF_DIM(nid_restart,"number_of_advected_fields",nqmx,idim5)
     
    566568        CALL abort_physic("open_restartphy","Failed defining nlayer",1)
    567569      ENDIF
    568      
     570
    569571      ierr=NF90_DEF_DIM(nid_restart,"Time",NF90_UNLIMITED,idim7)
    570572      IF (ierr/=NF90_NOERR) THEN
     
    588590      ENDIF
    589591
     592      ierr=NF90_DEF_DIM(nid_restart,"nb_str_max",nb_str_max,idim10)
     593      IF (ierr/=NF90_NOERR) THEN
     594        write(*,*)'phyredem: problem defining nb_str_max dimension'
     595        write(*,*)trim(nf90_strerror(ierr))
     596        CALL ABORT
     597      ENDIF
    590598
    591599      ierr=NF90_ENDDEF(nid_restart)
     
    608616      ierr = NF90_CLOSE (nid_restart)
    609617    ENDIF
    610  
     618
    611619  END SUBROUTINE close_restartphy
    612620
     
    618626  REAL,INTENT(IN)                :: field(:)
    619627  REAL,OPTIONAL,INTENT(IN)       :: time
    620  
     628
    621629  IF (present(time)) THEN
    622630    ! if timeindex is present, it is a time-dependent variable
     
    625633    CALL put_field_rgen(field_name,title,field,1)
    626634  ENDIF
    627  
     635
    628636  END SUBROUTINE put_field_r1
    629637
     
    635643  REAL,INTENT(IN)                :: field(:,:)
    636644  REAL,OPTIONAL,INTENT(IN)       :: time
    637  
     645
    638646  IF (present(time)) THEN
    639647    ! if timeindex is present, it is a time-dependent variable
     
    642650    CALL put_field_rgen(field_name,title,field,size(field,2))
    643651  ENDIF
    644  
     652
    645653  END SUBROUTINE put_field_r2
    646654
     
    652660  REAL,INTENT(IN)                :: field(:,:,:)
    653661  REAL,OPTIONAL,INTENT(IN)       :: time
    654  
     662
    655663  IF (present(time)) THEN
    656664    ! if timeindex is present, it is a time-dependent variable
    657665    CALL put_field_rgen(field_name,title,field,size(field,2)*size(field,3),&
    658666                        time)
    659   ELSE 
     667  ELSE
    660668    CALL put_field_rgen(field_name,title,field,size(field,2)*size(field,3))
    661669  ENDIF
    662  
     670
    663671  END SUBROUTINE put_field_r3
    664  
     672
    665673  SUBROUTINE put_field_rgen(field_name,title,field,field_size,time)
    666674  USE netcdf
     
    668676  USE comsoil_h_PEM, only:  nsoilmx_PEM
    669677  USE comslope_mod, ONLY: nslope
     678  use layering_mod, only: nb_str_max
    670679  USE mod_grid_phy_lmdz
    671680  USE mod_phys_lmdz_para
     
    676685  REAL,INTENT(IN)                :: field(klon,field_size)
    677686  REAL,OPTIONAL,INTENT(IN)       :: time
    678  
     687
    679688  REAL                           :: field_glo(klon_glo,field_size)
    680689  INTEGER                        :: ierr
    681690  INTEGER                        :: nvarid
    682    
     691
    683692    CALL gather(field,field_glo)
    684    
     693
    685694    IF (is_master) THEN
    686695
     
    898907        endif ! of if (.not.present(time))
    899908
     909      ELSE IF (field_size == nb_str_max) THEN
     910        ! input is a 2D "stratification" array
     911        if (.not.present(time)) then ! for a time-independent field
     912          ierr = NF90_REDEF(nid_restart)
     913#ifdef NC_DOUBLE
     914          ierr=NF90_DEF_VAR(nid_restart,field_name,NF90_DOUBLE,&
     915                            (/idim2,idim8/),nvarid)
     916#else
     917          ierr=NF90_DEF_VAR(nid_restart,field_name,NF90_FLOAT,&
     918                            (/idim2,idim8/),nvarid)
     919#endif
     920          if (ierr.ne.NF90_NOERR) then
     921            write(*,*)"put_field_rgen error: failed to define"//trim(field_name)
     922            write(*,*)trim(nf90_strerror(ierr))
     923          endif
     924          IF (LEN_TRIM(title) > 0) ierr=NF90_PUT_ATT(nid_restart,nvarid,"title",title)
     925          ierr = NF90_ENDDEF(nid_restart)
     926          ierr = NF90_PUT_VAR(nid_restart,nvarid,field_glo)
     927        else
     928          ! check if the variable has already been defined:
     929          ierr=NF90_INQ_VARID(nid_restart,field_name,nvarid)
     930          if (ierr/=NF90_NOERR) then ! variable not found, define it
     931            ierr=NF90_REDEF(nid_restart)
     932#ifdef NC_DOUBLE
     933            ierr=NF90_DEF_VAR(nid_restart,field_name,NF90_DOUBLE,&
     934                              (/idim2,idim10,idim7/),nvarid)
     935#else
     936            ierr=NF90_DEF_VAR(nid_restart,field_name,NF90_FLOAT,&
     937                              (/idim2,idim10,idim7/),nvarid)
     938#endif
     939           if (ierr.ne.NF90_NOERR) then
     940              write(*,*)"put_field_rgen error: failed to define"//trim(field_name)
     941              write(*,*)trim(nf90_strerror(ierr))
     942            endif
     943            IF (LEN_TRIM(title) > 0) ierr=NF90_PUT_ATT(nid_restart,nvarid,"title",title)
     944            ierr=NF90_ENDDEF(nid_restart)
     945          endif
     946          ! Write the variable
     947          ierr=NF90_PUT_VAR(nid_restart,nvarid,field_glo,&
     948                            start=(/1,1,timeindex/))
     949
     950        endif ! of if (.not.present(time))
     951
    900952      ELSE
    901953        write(*,*) "Error phyredem(put_field_rgen) : wrong dimension for ",trim(field_name)
     
    912964
    913965    ENDIF ! of IF (is_master)
    914    
    915   END SUBROUTINE put_field_rgen 
    916  
     966
     967  END SUBROUTINE put_field_rgen
     968
    917969  SUBROUTINE put_var_r0(var_name,title,var)
    918970  ! Put a scalar in file
     
    922974     REAL,INTENT(IN)             :: var
    923975     REAL                        :: varin(1)
    924      
     976
    925977     varin(1)=var
    926      
     978
    927979     CALL put_var_rgen(var_name,title,varin,size(varin))
    928980
     
    936988     CHARACTER(LEN=*),INTENT(IN) :: title
    937989     REAL,INTENT(IN)             :: var(:)
    938      
     990
    939991     CALL put_var_rgen(var_name,title,var,size(var))
    940992
    941993  END SUBROUTINE put_var_r1
    942  
     994
    943995  SUBROUTINE put_var_r2(var_name,title,var)
    944996  ! Put a 2D field in file
     
    947999     CHARACTER(LEN=*),INTENT(IN) :: title
    9481000     REAL,INTENT(IN)             :: var(:,:)
    949      
     1001
    9501002     CALL put_var_rgen(var_name,title,var,size(var))
    9511003
    952   END SUBROUTINE put_var_r2     
    953  
     1004  END SUBROUTINE put_var_r2
     1005
    9541006  SUBROUTINE put_var_r3(var_name,title,var)
    9551007  ! Put a 3D field in file
     
    9581010     CHARACTER(LEN=*),INTENT(IN) :: title
    9591011     REAL,INTENT(IN)             :: var(:,:,:)
    960      
     1012
    9611013     CALL put_var_rgen(var_name,title,var,size(var))
    9621014
     
    9761028     INTEGER,INTENT(IN)          :: var_size
    9771029     REAL,INTENT(IN)             :: var(var_size)
    978      
     1030
    9791031     INTEGER :: ierr
    9801032     INTEGER :: nvarid
    9811033     INTEGER :: idim1d
    9821034     logical,save :: firsttime=.true.
    983          
     1035
    9841036    IF (is_master) THEN
    9851037
     
    9981050          IF (LEN_TRIM(title) > 0) ierr=NF90_PUT_ATT(nid_restart,nvarid,"title",title)
    9991051          ierr=NF90_ENDDEF(nid_restart)
    1000          
     1052
    10011053          firsttime=.false.
    10021054        endif
     
    10191071        idim1d=idim1
    10201072      ELSEIF (var_size==nsoilmx_PEM) THEN
    1021         ! We know it is an  "mlayer" kind of 1D array
     1073        ! We know it is an "mlayer" kind of 1D array
    10221074        idim1d=idim3
    10231075      ELSEIF (var_size==nslope+1) THEN
    1024         ! We know it is an  "inter slope" kind of 1D array
     1076        ! We know it is an "inter slope" kind of 1D array
    10251077        idim1d=idim9
    1026       ELSE
     1078      ELSEIF (var_name == "nb_str_max") THEN
     1079        ! We know it is a kind of stratification array
     1080        idim1d = idim10
     1081      ELSE
    10271082        write(*,*) "put_var_rgen error : wrong dimension"
    10281083        write(*,*) "  var_size =",var_size
     
    10511106      ENDIF
    10521107    ENDIF ! of IF (is_master)
    1053    
    1054   END SUBROUTINE put_var_rgen     
     1108
     1109  END SUBROUTINE put_var_rgen
    10551110
    10561111END MODULE iostart_PEM
  • trunk/LMDZ.COMMON/libf/evolution/layering_mod.F90

    r3286 r3297  
    1414! Numerical parameter
    1515real, parameter :: eps = epsilon(1.), tol = 1.e2*eps
     16integer         :: nb_str_max
    1617
    1718! Physical parameters
     
    2930type :: stratum
    3031    real               :: thickness          ! Layer thickness [m]
    31     real               :: elevation          ! Layer elevation (top height from the surface) [m]
     32    real               :: top_elevation      ! Layer top_elevation (top height from the surface) [m]
    3233    real               :: co2ice_volfrac     ! CO2 ice volumic fraction
    3334    real               :: h2oice_volfrac     ! H2O ice volumic fraction
     
    4546end type layering
    4647
     48! Array of pointers to "stratum"
     49type ptrarray
     50    type(stratum), pointer :: p
     51end type ptrarray
     52
    4753!=======================================================================
    4854contains
     55! Procedures to manipulate the data structure:
     56!     > print_stratum
     57!     > add_stratum
     58!     > insert_stratum
     59!     > rm_stratum
     60!     > get_stratum
     61!     > ini_layering
     62!     > del_layering
     63!     > print_layering
     64!     > get_nb_str_max
     65!     > stratif2array
     66!     > array2stratif
     67!     > print_stratif
     68! Procedures for the algorithm to evolve the layering:
     69!     > make_layering
     70!     > subl_co2ice_layering
     71!     > subl_h2oice_layering
     72!     > lift_dust_lags
    4973!=======================================================================
    5074! To display a stratum
     
    5882!---- Code
    5983write(*,'(a20,es13.6)') 'Thickness      : ', this%thickness
    60 write(*,'(a20,es13.6)') 'Elevation      : ', this%elevation
    61 write(*,'(a20,es13.6)') 'CO2 ice content: ', this%co2ice_volfrac
    62 write(*,'(a20,es13.6)') 'H2O ice content: ', this%h2oice_volfrac
    63 write(*,'(a20,es13.6)') 'Dust content   : ', this%dust_volfrac
    64 write(*,'(a20,es13.6)') 'Air content    : ', this%air_volfrac
     84write(*,'(a20,es13.6)') 'Top elevation  : ', this%top_elevation
     85write(*,'(a20,es13.6)') 'CO2 ice (m3/m3): ', this%co2ice_volfrac
     86write(*,'(a20,es13.6)') 'H2O ice (m3/m3): ', this%h2oice_volfrac
     87write(*,'(a20,es13.6)') 'Dust (m3/m3)   : ', this%dust_volfrac
     88write(*,'(a20,es13.6)') 'Air (m3/m3)    : ', this%air_volfrac
    6589
    6690END SUBROUTINE print_stratum
    6791
    6892!=======================================================================
    69 ! To display a layering
    70 SUBROUTINE print_lay(this)
    71 
    72 implicit none
    73 
    74 !---- Arguments
    75 type(layering), intent(in) :: this
    76 
    77 !---- Local variables
    78 type(stratum), pointer :: current
    79 integer                :: i
    80 
    81 !---- Code
    82 current => this%top
    83 
    84 i = this%nb_str
    85 do while (associated(current))
    86     write(*,'(a8,i4)') 'Stratum ', i
    87     call print_stratum(current)
    88     write(*,*)
    89     current => current%down
    90     i = i - 1
    91 enddo
    92 
    93 END SUBROUTINE print_lay
    94 
    95 !=======================================================================
    9693! To add a stratum to the top of a layering
    97 SUBROUTINE add_stratum(this,thickness,elevation,co2ice,h2oice,dust,air)
     94SUBROUTINE add_stratum(this,thickness,top_elevation,co2ice,h2oice,dust,air)
    9895
    9996implicit none
     
    10198!---- Arguments
    10299type(layering), intent(inout)  :: this
    103 real, intent(in), optional :: thickness, elevation, co2ice, h2oice, dust, air
     100real, intent(in), optional :: thickness, top_elevation, co2ice, h2oice, dust, air
    104101
    105102!---- Local variables
     
    111108nullify(str%up,str%down)
    112109str%thickness = 1.
    113 str%elevation = 1.
     110str%top_elevation = 1.
    114111str%co2ice_volfrac = 0.
    115112str%h2oice_volfrac = 0.
     
    117114str%air_volfrac = 1.
    118115if (present(thickness)) str%thickness = thickness
    119 if (present(elevation)) str%elevation = elevation
     116if (present(top_elevation)) str%top_elevation = top_elevation
    120117if (present(co2ice)) str%co2ice_volfrac = co2ice
    121118if (present(h2oice)) str%h2oice_volfrac = h2oice
     
    144141!=======================================================================
    145142! To insert a stratum after another one in a layering
    146 SUBROUTINE insert_stratum(this,str_prev,thickness,elevation,co2ice,h2oice,dust,air)
     143SUBROUTINE insert_stratum(this,str_prev,thickness,top_elevation,co2ice,h2oice,dust,air)
    147144
    148145implicit none
     
    151148type(layering),         intent(inout) :: this
    152149type(stratum), pointer, intent(inout) :: str_prev
    153 real, intent(in), optional :: thickness, elevation, co2ice, h2oice, dust, air
     150real, intent(in), optional :: thickness, top_elevation, co2ice, h2oice, dust, air
    154151
    155152!---- Local variables
     
    158155!---- Code
    159156if (.not. associated(str_prev%up)) then ! If str_prev is the top stratum of the layering
    160     call add_stratum(this,thickness,elevation,co2ice,h2oice,dust,air)
     157    call add_stratum(this,thickness,top_elevation,co2ice,h2oice,dust,air)
    161158else
    162159    ! Creation of the stratum
     
    164161    nullify(str%up,str%down)
    165162    str%thickness = 1.
    166     str%elevation = 1.
     163    str%top_elevation = 1.
    167164    str%co2ice_volfrac = 0.
    168165    str%h2oice_volfrac = 0.
     
    170167    str%air_volfrac = 1.
    171168    if (present(thickness)) str%thickness = thickness
    172     if (present(elevation)) str%elevation = elevation
     169    if (present(top_elevation)) str%top_elevation = top_elevation
    173170    if (present(co2ice)) str%co2ice_volfrac = co2ice
    174171    if (present(h2oice)) str%h2oice_volfrac = h2oice
     
    189186    str%up%down => str
    190187
    191     ! Correct the value of elevation for the upper strata
     188    ! Correct the value of top_elevation for the upper strata
    192189    current => str%up
    193190    do while (associated(current))
    194         current%elevation = current%down%elevation + current%thickness
     191        current%top_elevation = current%down%top_elevation + current%thickness
    195192        current => current%up
    196193    enddo
     
    214211!---- Code
    215212! Protect the 3 sub-surface strata from removing
    216 if (str%elevation <= 0.) return
     213if (str%top_elevation <= 0.) return
    217214
    218215! Decrement the number of strata
    219216this%nb_str = this%nb_str - 1
    220217
    221 ! Remove the stratum from the stratification
     218! Remove the stratum from the layering
    222219str%down%up => str%up
    223220if (associated(str%up)) then ! If it is not the last one at the top of the layering
     
    235232
    236233!=======================================================================
     234! To get a specific stratum in a layering
     235FUNCTION get_stratum(lay,i) RESULT(str)
     236
     237implicit none
     238
     239!---- Arguments
     240type(layering), intent(in) :: lay
     241integer,        intent(in) :: i
     242type(stratum), pointer     :: str
     243
     244!---- Local variables
     245integer :: k
     246
     247!---- Code
     248if (i < 1 .or. i > lay%nb_str) error stop 'get_stratum: requested number is beyond the number of strata of the layering!'
     249k = 1
     250str => lay%bottom
     251do while (k /= i)
     252    str => str%up
     253    k = k + 1
     254enddo
     255
     256END FUNCTION get_stratum
     257
     258!=======================================================================
    237259! To initialize the layering
    238260SUBROUTINE ini_layering(this)
     
    279301
    280302!=======================================================================
    281 ! To get a specific stratum in a layering
    282 FUNCTION get_stratum(lay,i) RESULT(str)
    283 
    284 implicit none
    285 
    286 !---- Arguments
    287 type(layering), intent(in) :: lay
    288 integer,        intent(in) :: i
    289 type(stratum), pointer     :: str
    290 
    291 !---- Local variables
    292 integer :: k
    293 
    294 !---- Code
    295 if (i < 1 .or. i > lay%nb_str) error stop 'get_stratum: requested number is beyond the number of strata of the layering!'
    296 k = 1
    297 str => lay%bottom
    298 do while (k /= i)
    299     str => str%up
    300     k = k + 1
    301 enddo
    302 
    303 END FUNCTION get_stratum
    304 
    305 !=======================================================================
    306 ! To sublimate CO2 ice in the layering
    307 SUBROUTINE subl_co2ice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag)
    308 
    309 implicit none
    310 
    311 !---- Arguments
    312 type(layering),         intent(inout) :: this
    313 type(stratum), pointer, intent(inout) :: str
    314 logical,                intent(inout) :: new_lag
    315 real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old
    316 
    317 !---- Local variables
    318 real               :: r_subl, hsubl_dust, h_lag
     303! To display a layering
     304SUBROUTINE print_layering(this)
     305
     306implicit none
     307
     308!---- Arguments
     309type(layering), intent(in) :: this
     310
     311!---- Local variables
    319312type(stratum), pointer :: current
    320 
    321 !---- Code
    322 ! How much dust does CO2 ice sublimation involve to create the lag?
    323 r_subl = h2subl/(1. - co2ice_porosity) &
    324         /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity)))
    325 hsubl_dust = r_subl*str%dust_volfrac*str%thickness
    326 ! Update of properties in the sublimating stratum
    327 str%thickness = str%thickness - h2subl/(1. - co2ice_porosity) - hsubl_dust
    328 str%elevation = str%elevation - h2subl/(1. - co2ice_porosity) - hsubl_dust
    329 str%co2ice_volfrac = (h_co2ice_old - h2subl)/str%thickness
    330 str%h2oice_volfrac = h_h2oice_old/str%thickness
    331 str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness
    332 str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac)
    333 ! Correct the value of elevation for the upper strata
    334 current => str%up
     313integer                :: i
     314
     315!---- Code
     316current => this%top
     317
     318i = this%nb_str
    335319do while (associated(current))
    336     current%elevation = current%down%elevation + current%thickness
    337     current => current%up
    338 enddo
    339 ! Remove the sublimating stratum if there is no ice anymore
    340 if (str%thickness < tol) call rm_stratum(this,str)
    341 ! New stratum = dust lag
    342 h_lag = hsubl_dust/(1. - dry_lag_porosity)
    343 if (h_lag > 0.) then ! Only if the dust lag is building up
    344     if (new_lag) then
    345         call insert_stratum(this,str,h_lag,str%elevation + h_lag,0.,0.,1. - dry_lag_porosity,dry_lag_porosity)
    346         new_lag = .false.
    347     else
    348         str%up%thickness = str%up%thickness + h_lag
    349         str%up%elevation = str%up%elevation + h_lag
    350     endif
    351 endif
    352 
    353 END SUBROUTINE subl_co2ice_layering
    354 
    355 !=======================================================================
    356 ! To sublimate H2O ice in the layering
    357 SUBROUTINE subl_h2oice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag)
    358 
    359 implicit none
    360 
    361 !---- Arguments
    362 type(layering),         intent(inout) :: this
    363 type(stratum), pointer, intent(inout) :: str
    364 logical,                intent(inout) :: new_lag
    365 real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old
    366 
    367 !---- Local variables
    368 real               :: r_subl, hsubl_dust, h_lag
     320    write(*,'(a8,i4)') 'Stratum ', i
     321    call print_stratum(current)
     322    write(*,*)
     323    current => current%down
     324    i = i - 1
     325enddo
     326
     327END SUBROUTINE print_layering
     328
     329!=======================================================================
     330! To get the maximum number of "stratum" in the stratification (layerings)
     331FUNCTION get_nb_str_max(stratif,ngrid,nslope) RESULT(nb_str_max)
     332
     333implicit none
     334
     335!---- Arguments
     336type(layering), dimension(ngrid,nslope), intent(in) :: stratif
     337integer,                                 intent(in) :: ngrid, nslope
     338integer :: nb_str_max
     339
     340!---- Local variables
     341integer :: ig, islope
     342
     343!---- Code
     344nb_str_max = 0
     345do islope = 1,nslope
     346    do ig = 1,ngrid
     347        nb_str_max = max(stratif(ig,islope)%nb_str,nb_str_max)
     348    enddo
     349enddo
     350
     351END FUNCTION get_nb_str_max
     352
     353!=======================================================================
     354! To convert the stratification data structure (layerings) into an array able to be outputted
     355SUBROUTINE stratif2array(stratif,ngrid,nslope,stratif_array)
     356
     357implicit none
     358
     359!---- Arguments
     360integer,                                 intent(in) :: ngrid, nslope
     361type(layering), dimension(ngrid,nslope), intent(in) :: stratif
     362real, dimension(:,:,:,:), allocatable, intent(inout) :: stratif_array
     363
     364!---- Local variables
    369365type(stratum), pointer :: current
    370 
    371 !---- Code
    372 ! How much dust does CO2 ice sublimation involve to create the lag?
    373 r_subl = h2subl/(1. - h2oice_porosity) &
    374         /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity)))
    375 hsubl_dust = r_subl*str%dust_volfrac*str%thickness
    376 ! Update of properties in the sublimating stratum
    377 str%thickness = str%thickness - h2subl/(1. - h2oice_porosity) - hsubl_dust
    378 str%elevation = str%elevation - h2subl/(1. - h2oice_porosity) - hsubl_dust
    379 str%co2ice_volfrac = h_co2ice_old/str%thickness
    380 str%h2oice_volfrac = (h_h2oice_old - h2subl)/str%thickness
    381 str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness
    382 str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac)
    383 ! Correct the value of elevation for the upper strata
    384 current => str%up
    385 do while (associated(current))
    386     current%elevation = current%down%elevation + current%thickness
    387     current => current%up
    388 enddo
    389 ! Remove the sublimating stratum if there is no ice anymore
    390 if (str%thickness < tol) call rm_stratum(this,str)
    391 ! New stratum = dust lag
    392 h_lag = hsubl_dust/(1. - dry_lag_porosity)
    393 if (h_lag > 0.) then ! Only if the dust lag is building up
    394     if (new_lag) then
    395         call insert_stratum(this,str,h_lag,str%elevation + h_lag,0.,0.,1. - dry_lag_porosity,dry_lag_porosity)
    396         new_lag = .false.
    397     else
    398         str%up%thickness = str%up%thickness + h_lag
    399         str%up%elevation = str%up%elevation + h_lag
    400     endif
    401 endif
    402 
    403 END SUBROUTINE subl_h2oice_layering
    404 
    405 !=======================================================================
    406 ! To lift dust in the layering
    407 SUBROUTINE lift_dust_lags(this,str,h2lift)
    408 
    409 implicit none
    410 
    411 !---- Arguments
    412 type(layering),         intent(inout) :: this
    413 type(stratum), pointer, intent(inout) :: str
    414 real, intent(in) :: h2lift
    415 
    416 !---- Code
    417 ! Update of properties in the eroding dust lag
    418 str%thickness = str%thickness - h2lift/(1. - str%air_volfrac)
    419 str%elevation = str%elevation - h2lift/(1. - str%air_volfrac)
    420 ! Remove the eroding dust lag if there is no dust anymore
    421 if (str%thickness < tol) call rm_stratum(this,str)
    422 
    423 END SUBROUTINE lift_dust_lags
     366integer                :: ig, islope, k
     367
     368!---- Code
     369stratif_array = 0.
     370do islope = 1,nslope
     371    do ig = 1,ngrid
     372        current => stratif(ig,islope)%bottom
     373        k = 1
     374        do while (associated(current))
     375            stratif_array(ig,islope,k,1) = current%thickness
     376            stratif_array(ig,islope,k,2) = current%top_elevation
     377            stratif_array(ig,islope,k,3) = current%co2ice_volfrac
     378            stratif_array(ig,islope,k,4) = current%h2oice_volfrac
     379            stratif_array(ig,islope,k,5) = current%dust_volfrac
     380            stratif_array(ig,islope,k,6) = current%air_volfrac
     381            current => current%up
     382            k = k + 1
     383        enddo
     384    enddo
     385enddo
     386
     387END SUBROUTINE stratif2array
     388
     389!=======================================================================
     390! To convert the stratification array into the stratification data structure (layerings)
     391SUBROUTINE array2stratif(stratif_array,ngrid,nslope,stratif)
     392
     393implicit none
     394
     395!---- Arguments
     396integer,                               intent(in) :: ngrid, nslope
     397real, dimension(:,:,:,:), allocatable, intent(in) :: stratif_array
     398type(layering), dimension(ngrid,nslope), intent(inout) :: stratif
     399
     400!---- Local variables
     401type(stratum), pointer :: current
     402integer                :: ig, islope, k
     403
     404!---- Code
     405do islope = 1,nslope
     406    do ig = 1,ngrid
     407        current => stratif(ig,islope)%bottom
     408        do k = 1,3
     409            current%thickness      = stratif_array(ig,islope,k,1)
     410            current%top_elevation  = stratif_array(ig,islope,k,2)
     411            current%co2ice_volfrac = stratif_array(ig,islope,k,3)
     412            current%h2oice_volfrac = stratif_array(ig,islope,k,4)
     413            current%dust_volfrac   = stratif_array(ig,islope,k,5)
     414            current%air_volfrac    = stratif_array(ig,islope,k,6)
     415            current => current%up
     416        enddo
     417        do k = 4,size(stratif_array,3)
     418            if (all(abs(stratif_array(ig,islope,k,:)) < eps)) exit
     419            call add_stratum(stratif(ig,islope),stratif_array(ig,islope,k,1),stratif_array(ig,islope,k,2),stratif_array(ig,islope,k,3),stratif_array(ig,islope,k,4),stratif_array(ig,islope,k,5),stratif_array(ig,islope,k,6))
     420        enddo
     421    enddo
     422enddo
     423
     424END SUBROUTINE array2stratif
     425
     426!=======================================================================
     427! To display a stratification (layerings)
     428SUBROUTINE print_stratif(this,ngrid,nslope)
     429
     430implicit none
     431
     432!---- Arguments
     433integer,                                 intent(in) :: ngrid, nslope
     434type(layering), dimension(ngrid,nslope), intent(in) :: this
     435
     436!---- Local variables
     437integer :: ig, islope
     438
     439!---- Code
     440do ig = 1,ngrid
     441    write(*,'(a10,i4)') 'Grid cell ', ig
     442    do islope = 1,nslope
     443        write(*,'(a13,i1)') 'Slope number ', islope
     444        call print_layering(this(ig,islope))
     445        write(*,*) '~~~~~~~~~~'
     446    enddo
     447    write(*,*) '--------------------'
     448enddo
     449
     450END SUBROUTINE print_stratif
    424451
    425452!=======================================================================
    426453! Layering algorithm
    427 SUBROUTINE make_layering(this,k,htend_co2ice,htend_h2oice,htend_dust,new_str,new_lag1,new_lag2,stopPEM,current1,current2)
     454SUBROUTINE make_layering(this,tend_co2ice,tend_h2oice,tend_dust,new_str,new_lag1,new_lag2,stopPEM,current1,current2)
    428455
    429456implicit none
     
    432459type(layering),         intent(inout) :: this
    433460type(stratum), pointer, intent(inout) :: current1, current2
    434 logical,                intent(inout) :: new_str, new_lag1, new_lag2, stopPEM
    435 real, intent(in) :: htend_co2ice, htend_h2oice, htend_dust
    436 integer,  intent(in) :: k
    437 
    438 !---- Local variables
    439 real :: h_co2ice_old, h_h2oice_old, h_dust_old, thickness, h2subl, h2subl_tot, h2lift, h2lift_tot
    440 
    441 !---- Code
     461logical,                intent(inout) :: new_str, new_lag1, new_lag2
     462integer,                intent(inout) :: stopPEM
     463real,     intent(in) :: tend_co2ice, tend_h2oice, tend_dust
     464
     465!---- Local variables
     466real :: htend_co2ice, htend_h2oice, htend_dust
     467real :: h_co2ice_old, h_h2oice_old, h_dust_old
     468real :: thickness, h2subl, h2subl_tot, h2lift, h2lift_tot
     469
     470!---- Code
     471htend_co2ice = tend_co2ice/rho_co2ice
     472htend_h2oice = tend_h2oice/rho_h2oice
     473htend_dust = tend_dust/rho_dust
     474
    442475if (htend_dust < 0.) then ! Dust lifting
    443476    if (abs(htend_co2ice) > eps .or. abs(htend_h2oice) > eps) error stop 'Situation not managed: dust lifting + CO2/H2O ice condensation/sublimation!'
    444     write(*,'(a5,i3,a)') 'Year ', k, ' -> Dust lifting'
     477    write(*,'(a)') ' Stratification -> Dust lifting'
    445478    h2lift_tot = abs(htend_dust)
    446479    do while (h2lift_tot > 0. .and. associated(current1))
     
    460493            endif
    461494        else ! No, we stop
    462             write(*,'(a5,i3,a)') 'Year ', k, ' -> Dust lifting: no dust lag!'
    463             stopPEM = .true.
     495            write(*,'(a)') ' Stratification -> Dust lifting: no dust lag!'
     496            stopPEM = 7
    464497            exit
    465498        endif
    466499    enddo
    467500    if (h2lift_tot > 0.) then
    468         write(*,'(a5,i3,a)') 'Year ', k, ' -> Not enough dust in the lag layers to complete the lifting!'
    469         stopPEM = .true.
     501        write(*,'(a)') ' Stratification -> Not enough dust in the lag layers to complete the lifting!'
     502        stopPEM = 7
    470503    endif
    471504
     
    474507!------ Dust sedimentation
    475508    if (abs(htend_co2ice) < eps .and. abs(htend_h2oice) < eps) then
    476         write(*,'(a5,i3,a)') 'Year ', k, ' -> Dust sedimentation'
     509        write(*,'(a)') ' Stratification -> Dust sedimentation'
    477510        ! New stratum at the layering top by sedimentation of dust
    478511        thickness = htend_dust/(1. - dry_regolith_porosity)
    479512        if (thickness > 0.) then ! Only if the stratum is builiding up
    480513             if (new_str) then
    481                  call add_stratum(this,thickness,this%top%elevation + thickness,0.,0.,htend_dust/thickness,dry_regolith_porosity)
     514                 call add_stratum(this,thickness,this%top%top_elevation + thickness,0.,0.,htend_dust/thickness,dry_regolith_porosity)
    482515                 new_str = .false.
    483516             else
    484517                 this%top%thickness = this%top%thickness + thickness
    485                  this%top%elevation = this%top%elevation + thickness
     518                 this%top%top_elevation = this%top%top_elevation + thickness
    486519             endif
    487520        endif
     
    489522!------ Condensation of CO2 ice + H2O ice
    490523    else if ((htend_co2ice >= 0. .and. htend_h2oice > 0.) .or. (htend_co2ice > 0. .and. htend_h2oice >= 0.)) then
    491         write(*,'(a5,i3,a)') 'Year ', k, ' -> CO2 and H2O ice condensation'
     524        write(*,'(a)') ' Stratification -> CO2 and H2O ice condensation'
    492525        ! New stratum at the layering top by condensation of CO2 and H2O ice
    493526        thickness = htend_co2ice/(1. - co2ice_porosity) + htend_h2oice/(1. - h2oice_porosity) + htend_dust
    494527        if (thickness > 0.) then ! Only if the stratum is builiding up
    495528             if (new_str) then
    496                  call add_stratum(this,thickness,this%top%elevation + thickness,htend_co2ice/thickness,htend_h2oice/thickness,htend_dust/thickness,1. - (htend_co2ice/thickness + htend_h2oice/thickness + htend_dust/thickness))
     529                 call add_stratum(this,thickness,this%top%top_elevation + thickness,htend_co2ice/thickness,htend_h2oice/thickness,htend_dust/thickness,1. - (htend_co2ice/thickness + htend_h2oice/thickness + htend_dust/thickness))
    497530                 new_str = .false.
    498531             else
    499532                 this%top%thickness = this%top%thickness + thickness
    500                  this%top%elevation = this%top%elevation + thickness
     533                 this%top%top_elevation = this%top%top_elevation + thickness
    501534             endif
    502535        endif
     
    504537!------ Sublimation of CO2 ice + Condensation of H2O ice
    505538    else if (htend_co2ice < 0. .and. htend_h2oice >= 0. ) then
    506         write(*,'(a5,i3,a)') 'Year ', k, ' -> Sublimation of CO2 ice + Condensation of H2O ice'
     539        write(*,'(a)') ' Stratification -> Sublimation of CO2 ice + Condensation of H2O ice'
    507540        ! CO2 ice sublimation in the considered stratum + New stratum for dust lag
    508541        h2subl_tot = abs(htend_co2ice)
     
    528561        enddo
    529562        if (h2subl_tot > 0.) then
    530             write(*,'(a5,i3,a)') 'Year ', k, ' -> Not enough CO2 ice in the layering to complete the sublimation!'
    531             stopPEM = .true.
     563            write(*,'(a)') ' Stratification -> Not enough CO2 ice in the layering to complete the sublimation!'
     564            stopPEM = 7
    532565        endif
    533566        ! New stratum at the layering top by condensation of H2O ice
     
    535568        if (thickness > 0.) then ! Only if the stratum is builiding up
    536569             if (new_str) then
    537                  call add_stratum(this,thickness,this%top%elevation + thickness,0.,htend_h2oice/thickness,htend_dust/thickness,1. - (htend_h2oice/thickness + htend_dust/thickness))
     570                 call add_stratum(this,thickness,this%top%top_elevation + thickness,0.,htend_h2oice/thickness,htend_dust/thickness,1. - (htend_h2oice/thickness + htend_dust/thickness))
    538571                 new_str = .false.
    539572             else
    540573                 this%top%thickness = this%top%thickness + thickness
    541                  this%top%elevation = this%top%elevation + thickness
     574                 this%top%top_elevation = this%top%top_elevation + thickness
    542575             endif
    543576        endif
     
    545578!------ Sublimation of CO2 ice + H2O ice
    546579    else if (htend_co2ice < 0. .and. htend_h2oice < 0.) then
    547         write(*,'(a5,i3,a)') 'Year ', k, ' -> Sublimation of CO2 and H2O ice'
     580        write(*,'(a)') ' Stratification -> Sublimation of CO2 and H2O ice'
    548581        ! CO2 ice sublimation in the considered stratum + New stratum for dust lag
    549582        h2subl_tot = abs(htend_co2ice)
     
    569602        enddo
    570603        if (h2subl_tot > 0.) then
    571             write(*,'(a5,i3,a)') 'Year ', k, ' -> Not enough CO2 ice in the layering to complete the sublimation!'
    572             stopPEM = .true.
     604            write(*,'(a)') ' Stratification -> Not enough CO2 ice in the layering to complete the sublimation!'
     605            stopPEM = 7
    573606        endif
    574607        ! H2O ice sublimation in the considered stratum + New stratum for dust lag
     
    595628        enddo
    596629        if (h2subl_tot > 0.) then
    597             write(*,'(a5,i3,a)') 'Year ', k, ' -> Not enough H2O ice in the layering to complete the sublimation!'
    598             stopPEM = .true.
     630            write(*,'(a)') ' Stratification -> Not enough H2O ice in the layering to complete the sublimation!'
     631            stopPEM = 7
    599632        endif
    600633
     
    607640END SUBROUTINE make_layering
    608641
     642!=======================================================================
     643! To sublimate CO2 ice in the layering
     644SUBROUTINE subl_co2ice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag)
     645
     646implicit none
     647
     648!---- Arguments
     649type(layering),         intent(inout) :: this
     650type(stratum), pointer, intent(inout) :: str
     651logical,                intent(inout) :: new_lag
     652real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old
     653
     654!---- Local variables
     655real                   :: r_subl, hsubl_dust, h_lag
     656type(stratum), pointer :: current
     657
     658!---- Code
     659! How much dust does CO2 ice sublimation involve to create the lag?
     660r_subl = h2subl/(1. - co2ice_porosity) &
     661        /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity)))
     662hsubl_dust = r_subl*str%dust_volfrac*str%thickness
     663! Update of properties in the sublimating stratum
     664str%thickness = str%thickness - h2subl/(1. - co2ice_porosity) - hsubl_dust
     665str%top_elevation = str%top_elevation - h2subl/(1. - co2ice_porosity) - hsubl_dust
     666str%co2ice_volfrac = (h_co2ice_old - h2subl)/str%thickness
     667str%h2oice_volfrac = h_h2oice_old/str%thickness
     668str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness
     669str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac)
     670! Correct the value of top_elevation for the upper strata
     671current => str%up
     672do while (associated(current))
     673    current%top_elevation = current%down%top_elevation + current%thickness
     674    current => current%up
     675enddo
     676! Remove the sublimating stratum if there is no ice anymore
     677if (str%thickness < tol) call rm_stratum(this,str)
     678! New stratum = dust lag
     679h_lag = hsubl_dust/(1. - dry_lag_porosity)
     680if (h_lag > 0.) then ! Only if the dust lag is building up
     681    if (new_lag) then
     682        call insert_stratum(this,str,h_lag,str%top_elevation + h_lag,0.,0.,1. - dry_lag_porosity,dry_lag_porosity)
     683        new_lag = .false.
     684    else
     685        str%up%thickness = str%up%thickness + h_lag
     686        str%up%top_elevation = str%up%top_elevation + h_lag
     687    endif
     688endif
     689
     690END SUBROUTINE subl_co2ice_layering
     691
     692!=======================================================================
     693! To sublimate H2O ice in the layering
     694SUBROUTINE subl_h2oice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag)
     695
     696implicit none
     697
     698!---- Arguments
     699type(layering),         intent(inout) :: this
     700type(stratum), pointer, intent(inout) :: str
     701logical,                intent(inout) :: new_lag
     702real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old
     703
     704!---- Local variables
     705real                   :: r_subl, hsubl_dust, h_lag
     706type(stratum), pointer :: current
     707
     708!---- Code
     709! How much dust does CO2 ice sublimation involve to create the lag?
     710r_subl = h2subl/(1. - h2oice_porosity) &
     711        /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity)))
     712hsubl_dust = r_subl*str%dust_volfrac*str%thickness
     713! Update of properties in the sublimating stratum
     714str%thickness = str%thickness - h2subl/(1. - h2oice_porosity) - hsubl_dust
     715str%top_elevation = str%top_elevation - h2subl/(1. - h2oice_porosity) - hsubl_dust
     716str%co2ice_volfrac = h_co2ice_old/str%thickness
     717str%h2oice_volfrac = (h_h2oice_old - h2subl)/str%thickness
     718str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness
     719str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac)
     720! Correct the value of top_elevation for the upper strata
     721current => str%up
     722do while (associated(current))
     723    current%top_elevation = current%down%top_elevation + current%thickness
     724    current => current%up
     725enddo
     726! Remove the sublimating stratum if there is no ice anymore
     727if (str%thickness < tol) call rm_stratum(this,str)
     728! New stratum = dust lag
     729h_lag = hsubl_dust/(1. - dry_lag_porosity)
     730if (h_lag > 0.) then ! Only if the dust lag is building up
     731    if (new_lag) then
     732        call insert_stratum(this,str,h_lag,str%top_elevation + h_lag,0.,0.,1. - dry_lag_porosity,dry_lag_porosity)
     733        new_lag = .false.
     734    else
     735        str%up%thickness = str%up%thickness + h_lag
     736        str%up%top_elevation = str%up%top_elevation + h_lag
     737    endif
     738endif
     739
     740END SUBROUTINE subl_h2oice_layering
     741
     742!=======================================================================
     743! To lift dust in the layering
     744SUBROUTINE lift_dust_lags(this,str,h2lift)
     745
     746implicit none
     747
     748!---- Arguments
     749type(layering),         intent(inout) :: this
     750type(stratum), pointer, intent(inout) :: str
     751real, intent(in) :: h2lift
     752
     753!---- Code
     754! Update of properties in the eroding dust lag
     755str%thickness = str%thickness - h2lift/(1. - str%air_volfrac)
     756str%top_elevation = str%top_elevation - h2lift/(1. - str%air_volfrac)
     757! Remove the eroding dust lag if there is no dust anymore
     758if (str%thickness < tol) call rm_stratum(this,str)
     759
     760END SUBROUTINE lift_dust_lags
     761
    609762END MODULE layering_mod
  • trunk/LMDZ.COMMON/libf/evolution/pem.F90

    r3287 r3297  
    4646use comsoil_h_PEM,              only: soil_pem, ini_comsoil_h_PEM, end_comsoil_h_PEM, nsoilmx_PEM, &
    4747                                      TI_PEM,                           & ! soil thermal inertia
    48                                       tsoil_PEM, layer_PEM, & ! Soil temp, number of subsurface layers, soil mid layer depths
     48                                      tsoil_PEM, layer_PEM, &             ! Soil temp, number of subsurface layers, soil mid layer depths
    4949                                      fluxgeo                             ! Geothermal flux for the PEM and PCM
    5050use adsorption_mod,             only: regolith_adsorption, adsorption_pem,        & ! Bool to check if adsorption, main subroutine
     
    7070use writediagpem_mod,           only: writediagpem, writediagsoilpem
    7171use co2condens_mod,             only: CO2cond_ps
     72use layering_mod,               only: tend_dust, ptrarray, stratum, layering, ini_layering, del_layering, make_layering, get_nb_str_max, nb_str_max
    7273
    7374#ifndef CPP_STD
     
    126127real               :: time_phys    ! Same as in PCM
    127128real               :: ptimestep    ! Same as in PCM
    128 real               :: ztime_fin    ! Same as in PCM
     129real               :: ztime_fin     ! Same as in PCM
    129130
    130131! Variables to read start.nc
     
    183184real, dimension(:,:),   allocatable :: vmr_co2_PEM_phys ! Physics x Times co2 volume mixing ratio used in the PEM
    184185real, dimension(:,:),   allocatable :: q_co2_PEM_phys   ! Physics x Times co2 mass mixing ratio in the first layer computed in the PEM, first value comes from PCM [kg/kg]
     186
     187! Variables for stratification (layering) evolution
     188type(layering), dimension(:,:), allocatable :: stratif                     ! Layering (linked list of "stratum") for each grid point and slope
     189type(ptrarray), dimension(:,:), allocatable :: current1, current2          ! Current active stratum in the layering
     190logical,        dimension(:,:), allocatable :: new_str, new_lag1, new_lag2 ! Flags for the layering algorithm
    185191
    186192! Variables for slopes
     
    582588deallocate(min_co2_ice,min_h2o_ice)
    583589
     590allocate(stratif(ngrid,nslope))
     591do islope = 1,nslope
     592    do i = 1,ngrid
     593        call ini_layering(stratif(i,islope))
     594    enddo
     595enddo
     596
    584597call pemetat0("startpem.nc",ngrid,nsoilmx,nsoilmx_PEM,nslope,timelen,timestep,TI_PEM,tsoil_PEM,porefillingice_depth, &
    585598              porefillingice_thickness,tsurf_avg_yr1,tsurf_ave,q_co2_PEM_phys,q_h2o_PEM_phys,ps_timeseries,          &
    586599              tsoil_phys_PEM_timeseries,tend_h2o_ice,tend_co2_ice,co2_ice,h2o_ice,global_avg_press_PCM,              &
    587600              watersurf_density_ave,watersoil_density_PEM_ave,co2_adsorbded_phys,delta_co2_adsorbded,                &
    588               h2o_adsorbded_phys,delta_h2o_adsorbded)
     601              h2o_adsorbded_phys,delta_h2o_adsorbded,stratif)
    589602
    590603allocate(co2_ice_ini(ngrid,nslope))
     
    642655year_iter = 0
    643656stopPEM = 0
    644 
    645 do while (year_iter < year_iter_max .and. i_myear < n_myear)
     657allocate(new_str(ngrid,nslope),new_lag1(ngrid,nslope),new_lag2(ngrid,nslope),current1(ngrid,nslope),current2(ngrid,nslope))
     658new_str = .true.
     659new_lag1 = .true.
     660new_lag2 = .true.
     661do islope = 1,nslope
     662    do ig = 1,ngrid
     663        current1(ig,islope)%p => stratif(ig,islope)%top
     664        current2(ig,islope)%p => stratif(ig,islope)%top
     665    enddo
     666enddo
     667
     668do while (year_iter < 10 .and. i_myear < n_myear)
    646669! II.a.1. Compute updated global pressure
    647670    write(*,*) "Recomputing the new pressure..."
     
    725748    call evol_h2o_ice(ngrid,nslope,cell_area,delta_h2o_adsorbded,delta_h2o_icetablesublim,h2o_ice,tend_h2o_ice,stopPEM)
    726749    call evol_co2_ice(ngrid,nslope,co2_ice,tend_co2_ice)
     750    do islope = 1,nslope
     751        do ig = 1,ngrid
     752            call make_layering(stratif(ig,islope),tend_co2_ice(ig,islope),tend_h2o_ice(ig,islope),tend_dust,new_str(ig,islope),new_lag1(ig,islope),new_lag2(ig,islope),stopPEM,current1(ig,islope)%p,current2(ig,islope)%p)
     753        enddo
     754    enddo
    727755
    728756!------------------------
     
    10941122!    III_c Write the "restartpem.nc"
    10951123!------------------------
     1124nb_str_max = get_nb_str_max(stratif,ngrid,nslope) ! Get the maximum number of "stratum" in the stratification (layerings)
    10961125call pemdem0("restartpem.nc",longitude,latitude,cell_area,ngrid,nslope,def_slope,subslope_dist)
    10971126call pemdem1("restartpem.nc",i_myear,nsoilmx_PEM,ngrid,nslope,tsoil_PEM, &
    1098              TI_PEM, porefillingice_depth,porefillingice_thickness,      &
    1099              co2_adsorbded_phys,h2o_adsorbded_phys,h2o_ice)
     1127             TI_PEM,porefillingice_depth,porefillingice_thickness,       &
     1128             co2_adsorbded_phys,h2o_adsorbded_phys,h2o_ice,stratif)
    11001129write(*,*) "restartpem.nc has been written"
    11011130
     
    11071136write(*,*) "LL & RV & JBC: so far, so good!"
    11081137
     1138do islope = 1,nslope
     1139    do i = 1,ngrid
     1140        call del_layering(stratif(i,islope))
     1141    enddo
     1142enddo
     1143deallocate(stratif,new_str,new_lag1,new_lag2,current1,current2)
    11091144deallocate(vmr_co2_PCM,ps_timeseries,tsurf_PCM_timeseries,q_co2_PEM_phys,q_h2o_PEM_phys)
    11101145deallocate(co2_ice_PCM,watersurf_density_ave,watersoil_density_timeseries,Tsurfavg_before_saved)
  • trunk/LMDZ.COMMON/libf/evolution/pemetat0.F90

    r3214 r3297  
    1010                    tsurf_avg_yr1,tsurf_avg_yr2,q_co2,q_h2o,ps_inst,tsoil_inst,tend_h2o_ice,tend_co2_ice,co2_ice,h2o_ice,      &
    1111                    global_avg_pressure,watersurf_avg,watersoil_avg,m_co2_regolith_phys,deltam_co2_regolith_phys,              &
    12                     m_h2o_regolith_phys,deltam_h2o_regolith_phys)
    13 
    14 use iostart_PEM,                only: open_startphy, close_startphy, get_field, get_var
     12                    m_h2o_regolith_phys,deltam_h2o_regolith_phys,stratif)
     13
     14use iostart_PEM,                only: open_startphy, close_startphy, get_field, get_var, inquire_dimension, inquire_dimension_length
    1515use comsoil_h_PEM,              only: soil_pem, layer_PEM, mlayer_PEM, fluxgeo, inertiedat_PEM, ini_huge_h2oice, depth_breccia, depth_bedrock, index_breccia, index_bedrock
    1616use comsoil_h,                  only: volcapa, inertiedat
     
    2323use compute_soiltemp_mod,       only: ini_tsoil_pem, compute_tsoil_pem
    2424use comslope_mod,               only: def_slope_mean, subslope_dist
     25use layering_mod,               only: layering, array2stratif
    2526
    2627#ifndef CPP_STD
     
    3536include "callkeys.h"
    3637
    37 character(len=*),               intent(in) :: filename            ! name of the startfi_PEM.nc
     38character(*),                   intent(in) :: filename            ! name of the startfi_PEM.nc
    3839integer,                        intent(in) :: ngrid               ! # of physical grid points
    3940integer,                        intent(in) :: nsoil_PCM           ! # of vertical grid points in the PCM
     
    5657real, dimension(ngrid,nslope),                   intent(out) :: h2o_ice                  ! h2o ice amount [kg/m^2]
    5758real, dimension(ngrid,nslope),                   intent(out) :: co2_ice                  ! co2 ice amount [kg/m^2]
     59type(layering), dimension(ngrid,nslope),         intent(inout) :: stratif             ! stratification (layerings)
    5860real, dimension(ngrid,nsoil_PEM,nslope),         intent(inout) :: TI_PEM              ! soil (mid-layer) thermal inertia in the PEM grid [SI]
    5961real, dimension(ngrid,nsoil_PEM,nslope),         intent(inout) :: tsoil_PEM           ! soil (mid-layer) temperature [K]
     
    6567real, dimension(ngrid,nsoil_PEM,nslope),         intent(inout) :: watersoil_avg       ! surface water ice density, yearly averaged (kg/m^3)
    6668! local
    67 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_startPEM               ! soil temperature saved in the start [K]
    68 real, dimension(ngrid,nsoil_PEM,nslope) :: TI_startPEM                  ! soil thermal inertia saved in the start [SI]
    69 logical                                 :: found                        ! check if variables are found in the start
    70 logical                                 :: found2                       ! check if variables are found in the start
    71 integer                                 :: iloop, ig, islope, it, isoil ! index for loops
    72 real                                    :: kcond                        ! Thermal conductivity, intermediate variable [SI]
    73 real                                    :: delta                        ! Depth of the interface regolith-breccia, breccia -bedrock [m]
    74 character(2)                            :: num                          ! intermediate string to read PEM start sloped variables
    75 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr1                ! intermediate soil temperature during yr 1 [K]
    76 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr2                ! intermediate soil temperature during yr 2 [K]
    77 logical                                 :: startpem_file                ! boolean to check if we read the startfile or not
     69real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_startPEM                  ! soil temperature saved in the start [K]
     70real, dimension(ngrid,nsoil_PEM,nslope) :: TI_startPEM                     ! soil thermal inertia saved in the start [SI]
     71logical                                 :: found, found2                   ! check if variables are found in the start
     72integer                                 :: iloop, ig, islope, it, isoil, k ! index for loops
     73real                                    :: kcond                           ! Thermal conductivity, intermediate variable [SI]
     74real                                    :: delta                           ! Depth of the interface regolith-breccia, breccia -bedrock [m]
     75character(2)                            :: num                             ! intermediate string to read PEM start sloped variables
     76real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr1                   ! intermediate soil temperature during yr 1 [K]
     77real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr2                   ! intermediate soil temperature during yr 2 [K]
     78logical                                 :: startpem_file                   ! boolean to check if we read the startfile or not
     79real, dimension(:,:,:,:), allocatable   :: stratif_array                   ! Array for stratification (layerings)
     80real                                    :: nb_str_max
    7881
    7982#ifdef CPP_STD
     
    112115    ! open pem initial state file:
    113116    call open_startphy(filename)
     117
     118!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     119    ! Stratification (layerings)
     120    found = inquire_dimension("nb_str_max")
     121    if (.not. found) then
     122        write(*,*) 'Pemetat0: failed loading <nb_str_max>!'
     123        write(*,*) '''nb_str_max'' is set to 10!'
     124        nb_str_max = 10.
     125    else
     126        nb_str_max = inquire_dimension_length('nb_str_max')
     127    endif
     128    allocate(stratif_array(ngrid,nslope,int(nb_str_max),6))
     129    stratif_array = 0.
     130    do islope = 1,nslope
     131        write(num,'(i2.2)') islope
     132        call get_field('stratif_slope'//num//'_thickness',stratif_array(:,islope,:,1),found)
     133        call get_field('stratif_slope'//num//'_top_elevation',stratif_array(:,islope,:,2),found2)
     134        found = found .or. found2
     135        call get_field('stratif_slope'//num//'_co2ice_volfrac',stratif_array(:,islope,:,3),found2)
     136        found = found .or. found2
     137        call get_field('stratif_slope'//num//'_h2oice_volfrac',stratif_array(:,islope,:,4),found2)
     138        found = found .or. found2
     139        call get_field('stratif_slope'//num//'_dust_volfrac',stratif_array(:,islope,:,5),found2)
     140        found = found .or. found2
     141        call get_field('stratif_slope'//num//'_air_volfrac',stratif_array(:,islope,:,6),found2)
     142        found = found .or. found2
     143        if (.not. found) then
     144            write(*,*) 'Pemetat0: failed loading at least one of the properties of <stratif_slope'//num//'>'
     145        endif ! not found
     146    enddo ! islope
     147    call array2stratif(stratif_array,ngrid,nslope,stratif)
     148    deallocate(stratif_array)
    114149
    115150!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     
    320355else !No startfi, let's build all by hand
    321356
     357    write(*,*)'There is no "startpem.nc"!'
     358
     359    ! Stratification (layerings)
     360    write(*,*)'So the stratification (layerings) is initialized with nothing more than the 3 sub-surface strata.'
     361    nb_str_max = 3
     362
    322363    ! h2o ice
    323364    h2o_ice = 0.
    324     write(*,*)'There is no "startpem.nc"!'
    325365    write(*,*)'So ''h2o_ice'' is initialized with default value ''ini_huge_h2oice'' where ''watercaptag'' is true.'
    326366    do ig = 1,ngrid
  • trunk/LMDZ.COMMON/libf/evolution/pemredem.F90

    r3206 r3297  
    5858
    5959SUBROUTINE pemdem1(filename,i_myear,nsoil_PEM,ngrid,nslope,tsoil_slope_PEM,inertiesoil_slope_PEM, &
    60                    ice_table_depth,ice_table_thickness,m_co2_regolith,m_h2o_regolith,h2o_ice)
     60                   ice_table_depth,ice_table_thickness,m_co2_regolith,m_h2o_regolith,h2o_ice,stratif)
    6161
    6262! write time-dependent variable to restart file
     
    6464use comsoil_h_PEM, only: inertiedat_PEM, soil_pem
    6565use time_evol_mod, only: year_bp_ini, convert_years
     66use layering_mod,  only: layering, nb_str_max, stratif2array, print_layering
    6667
    6768implicit none
     
    7980real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: m_co2_regolith, m_h2o_regolith
    8081real, dimension(ngrid,nslope),           intent(in) :: h2o_ice
     82type(layering), dimension(ngrid,nslope), intent(in) :: stratif ! Stratification (layerings)
    8183
    82 integer       :: islope
    83 character(2)  :: num
    84 real          :: Year ! Year of the simulation
     84integer                               :: islope
     85character(2)                          :: num
     86real                                  :: Year          ! Year of the simulation
     87real, dimension(:,:,:,:), allocatable :: stratif_array ! Array for stratification (layerings)
    8588
    8689! Open file
     
    9295call put_var("Time","Year of simulation",Year)
    9396call put_field('h2o_ice','h2o_ice',h2o_ice,Year)
     97
     98allocate(stratif_array(ngrid,nslope,nb_str_max,6))
     99call stratif2array(stratif,ngrid,nslope,stratif_array)
     100do islope = 1,nslope
     101    write(num,fmt='(i2.2)') islope
     102    call put_field('stratif_slope'//num//'_thickness','Layering thickness',stratif_array(:,islope,:,1),Year)
     103    call put_field('stratif_slope'//num//'_top_elevation','Layering top elevation',stratif_array(:,islope,:,2),Year)
     104    call put_field('stratif_slope'//num//'_co2ice_volfrac','Layering CO2 ice volume fraction',stratif_array(:,islope,:,3),Year)
     105    call put_field('stratif_slope'//num//'_h2oice_volfrac','Layering H2O ice volume fraction',stratif_array(:,islope,:,4),Year)
     106    call put_field('stratif_slope'//num//'_dust_volfrac','Layering dust volume fraction',stratif_array(:,islope,:,5),Year)
     107    call put_field('stratif_slope'//num//'_air_volfrac','Layering air volume fraction',stratif_array(:,islope,:,6),Year)
     108enddo
     109deallocate(stratif_array)
    94110
    95111if (soil_pem) then
Note: See TracChangeset for help on using the changeset viewer.