Changeset 3297
- Timestamp:
- Apr 8, 2024, 3:49:41 PM (8 months ago)
- Location:
- trunk/LMDZ.COMMON
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/arch/arch-gfortran.fcm
r3180 r3297 1 %COMPILER gfortran2 %LINK gfortran1 %COMPILER mpif90 2 %LINK mpif90 3 3 %AR ar 4 4 %MAKE make … … 7 7 %CPP_DEF LAPACK 8 8 %FPP_DEF NC_DOUBLE 9 %BASE_FFLAGS - c -fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -fno-align-commons -fallow-argument-mismatch10 %PROD_FFLAGS -O 311 %DEV_FFLAGS -O 12 %DEBUG_FFLAGS -f fpe-trap=invalid,zero,overflow -fbounds-check -g3 -O0 -fstack-protector-all -finit-real=snan -fbacktrace9 %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 13 13 %C_COMPILER gcc 14 %C_OPTIM -O 315 %MPI_FFLAGS 14 %C_OPTIM -O2 15 %MPI_FFLAGS -I/usr/lib/x86_64-linux-gnu/openmpi/include 16 16 %OMP_FFLAGS 17 %BASE_LD 18 %MPI_LD 17 %BASE_LD -pg 18 %MPI_LD -lmpi 19 19 %OMP_LD -
trunk/LMDZ.COMMON/arch/arch-gfortran.path
r3180 r3297 1 1 ROOT=$PWD 2 NETCDF="$HOME/netcdf4hdf5" 2 3 3 4 NETCDF_LIBDIR="-L$NETCDF/lib" -
trunk/LMDZ.COMMON/libf/evolution/changelog.txt
r3296 r3297 265 265 == 08/04/2024 == JBC 266 266 Correction 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 269 Integration 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 38 38 call execute_command_line('sed -i "1s/.*/'//trim(ich1)//' '//trim(ich2)//' '//trim(fch)//'/" info_PEM.txt',cmdstat = cstat) 39 39 if (cstat > 0) then 40 error stop 'info_PEM: command exec tion failed!'40 error stop 'info_PEM: command execution failed!' 41 41 else if (cstat < 0) then 42 42 error stop 'info_PEM: command execution not supported!' -
trunk/LMDZ.COMMON/libf/evolution/iostart_PEM.F90
r3206 r3297 2 2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3 3 !!! 4 !!! Purpose: Read and write specific netcdf for the PEM 5 !!! 6 !!! 4 !!! Purpose: Read and write specific netcdf for the PEM 5 !!! 6 !!! 7 7 !!! Author: LL, inspired by iostart from the PCM 8 8 !!! … … 13 13 INTEGER,SAVE :: nid_start ! NetCDF file identifier for startfi.nc file 14 14 INTEGER,SAVE :: nid_restart ! NetCDF file identifier for restartfi.nc file 15 15 16 16 ! 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 26 27 INTEGER,SAVE :: timeindex ! current time index (for time-dependent fields) 27 28 INTEGER,PARAMETER :: length=100 ! size of tab_cntrl array 28 29 29 30 INTERFACE get_field 30 31 MODULE PROCEDURE Get_field_r1,Get_field_r2,Get_field_r3 31 32 END INTERFACE get_field 32 33 33 34 INTERFACE get_var 34 35 MODULE PROCEDURE get_var_r0,Get_var_r1,Get_var_r2,Get_var_r3 … … 48 49 PUBLIC inquire_field, inquire_field_ndims 49 50 PUBLIC open_startphy,close_startphy,open_restartphy,close_restartphy 50 51 51 52 CONTAINS 52 53 … … 66 67 ENDIF 67 68 ENDIF 68 69 69 70 CALL bcast(nid_start) ! tell all procs about nid_start 70 71 71 72 END SUBROUTINE open_startphy 72 73 … … 93 94 INTEGER :: varid 94 95 INTEGER :: ierr 95 96 96 97 IF (is_master) THEN 97 98 ierr=NF90_INQ_VARID(nid_start,Field_name,varid) … … 109 110 110 111 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 112 113 USE netcdf, only: nf90_inq_varid, nf90_inquire_variable, & 113 114 NF90_NOERR, nf90_strerror … … 118 119 INTEGER :: varid 119 120 INTEGER :: ierr 120 121 121 122 IF (is_master) THEN 122 123 ierr=nf90_inq_varid(nid_start,Field_name,varid) … … 145 146 INTEGER :: varid 146 147 INTEGER :: ierr 147 148 148 149 IF (is_master) THEN 149 150 ierr=NF90_INQ_DIMID(nid_start,Field_name,varid) … … 169 170 INTEGER :: varid 170 171 INTEGER :: ierr 171 172 172 173 IF (is_master) THEN 173 174 ierr=nf90_inq_dimid(nid_start,Field_name,varid) … … 194 195 CHARACTER(LEN=*),INTENT(IN) :: Field_name 195 196 REAL,INTENT(INOUT) :: Field(:) 196 LOGICAL,INTENT(OUT),OPTIONAL :: found 197 LOGICAL,INTENT(OUT),OPTIONAL :: found 197 198 INTEGER,INTENT(IN),OPTIONAL :: timeindex ! time index of sought data 198 199 … … 211 212 CALL Get_field_rgen(field_name,field,1,corners,edges) 212 213 ENDIF 213 214 214 215 END SUBROUTINE Get_Field_r1 215 216 216 217 SUBROUTINE Get_Field_r2(field_name,field,found,timeindex) 217 218 ! For a "3D" horizontal-vertical field … … 220 221 CHARACTER(LEN=*),INTENT(IN) :: Field_name 221 222 REAL,INTENT(INOUT) :: Field(:,:) 222 LOGICAL,INTENT(OUT),OPTIONAL :: found 223 LOGICAL,INTENT(OUT),OPTIONAL :: found 223 224 INTEGER,INTENT(IN),OPTIONAL :: timeindex ! time index of sought data 224 225 … … 232 233 corners(3)=timeindex 233 234 endif 234 235 235 236 IF (PRESENT(found)) THEN 236 237 CALL Get_field_rgen(field_name,field,size(field,2),& … … 241 242 ENDIF 242 243 243 244 244 245 END SUBROUTINE Get_Field_r2 245 246 246 247 SUBROUTINE Get_Field_r3(field_name,field,found,timeindex) 247 248 ! for a "4D" field surf/alt/?? … … 250 251 CHARACTER(LEN=*),INTENT(IN) :: Field_name 251 252 REAL,INTENT(INOUT) :: Field(:,:,:) 252 LOGICAL,INTENT(OUT),OPTIONAL :: found 253 LOGICAL,INTENT(OUT),OPTIONAL :: found 253 254 INTEGER,INTENT(IN),OPTIONAL :: timeindex ! time index of sought data 254 255 … … 263 264 corners(4)=timeindex 264 265 endif 265 266 266 267 IF (PRESENT(found)) THEN 267 268 CALL Get_field_rgen(field_name,field,size(field,2)*size(field,3),& … … 271 272 corners,edges) 272 273 ENDIF 273 274 274 275 END SUBROUTINE Get_Field_r3 275 276 276 277 SUBROUTINE Get_field_rgen(field_name,field,field_size, & 277 278 corners,edges,found) … … 287 288 INTEGER,INTENT(IN) :: edges(4) 288 289 LOGICAL,OPTIONAL :: found 289 290 290 291 REAL :: field_glo(klon_glo,field_size) 291 292 LOGICAL :: tmp_found 292 293 INTEGER :: varid 293 294 INTEGER :: ierr 294 295 295 296 IF (is_master) THEN 296 297 297 298 ierr=NF90_INQ_VARID(nid_start,Field_name,varid) 298 299 299 300 IF (ierr==NF90_NOERR) THEN 300 301 CALL body(field_glo) … … 303 304 tmp_found=.FALSE. 304 305 ENDIF 305 306 ENDIF 307 306 307 ENDIF 308 308 309 CALL bcast(tmp_found) 309 310 … … 311 312 CALL scatter(field_glo,field) 312 313 ENDIF 313 314 314 315 IF (PRESENT(found)) THEN 315 316 found=tmp_found … … 320 321 ENDIF 321 322 ENDIF 322 323 323 324 324 325 CONTAINS 325 326 326 327 SUBROUTINE body(field_glo) 327 328 REAL :: field_glo(klon_glo*field_size) 328 329 ierr=NF90_GET_VAR(nid_start,varid,field_glo,corners,edges) 329 330 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. 331 332 write(*,*) 'get_field_rgen: Failed reading <'//field_name//'>' 332 333 … … 353 354 SUBROUTINE get_var_r0(var_name,var,found) 354 355 ! Get a scalar from input file 355 IMPLICIT NONE 356 IMPLICIT NONE 356 357 CHARACTER(LEN=*),INTENT(IN) :: var_name 357 358 REAL,INTENT(INOUT) :: var … … 359 360 360 361 REAL :: varout(1) 361 362 362 363 IF (PRESENT(found)) THEN 363 364 CALL Get_var_rgen(var_name,varout,size(varout),found) … … 366 367 ENDIF 367 368 var=varout(1) 368 369 369 370 END SUBROUTINE get_var_r0 370 371 371 372 SUBROUTINE get_var_r1(var_name,var,found) 372 373 ! Get a vector from input file 373 IMPLICIT NONE 374 IMPLICIT NONE 374 375 CHARACTER(LEN=*),INTENT(IN) :: var_name 375 376 REAL,INTENT(INOUT) :: var(:) 376 377 LOGICAL,OPTIONAL,INTENT(OUT) :: found 377 378 378 379 IF (PRESENT(found)) THEN 379 380 CALL Get_var_rgen(var_name,var,size(var),found) … … 381 382 CALL Get_var_rgen(var_name,var,size(var)) 382 383 ENDIF 383 384 384 385 END SUBROUTINE get_var_r1 385 386 386 387 SUBROUTINE get_var_r2(var_name,var,found) 387 388 ! Get a 2D field from input file 388 IMPLICIT NONE 389 IMPLICIT NONE 389 390 CHARACTER(LEN=*),INTENT(IN) :: var_name 390 391 REAL,INTENT(OUT) :: var(:,:) 391 392 LOGICAL,OPTIONAL,INTENT(OUT) :: found 392 393 393 394 IF (PRESENT(found)) THEN 394 395 CALL Get_var_rgen(var_name,var,size(var),found) … … 396 397 CALL Get_var_rgen(var_name,var,size(var)) 397 398 ENDIF 398 399 399 400 END SUBROUTINE get_var_r2 400 401 401 402 SUBROUTINE get_var_r3(var_name,var,found) 402 403 ! Get a 3D field frominput file 403 IMPLICIT NONE 404 IMPLICIT NONE 404 405 CHARACTER(LEN=*),INTENT(IN) :: var_name 405 406 REAL,INTENT(INOUT) :: var(:,:,:) 406 407 LOGICAL,OPTIONAL,INTENT(OUT) :: found 407 408 408 409 IF (PRESENT(found)) THEN 409 410 CALL Get_var_rgen(var_name,var,size(var),found) … … 411 412 CALL Get_var_rgen(var_name,var,size(var)) 412 413 ENDIF 413 414 414 415 END SUBROUTINE get_var_r3 415 416 … … 424 425 REAL :: var(var_size) 425 426 LOGICAL,OPTIONAL :: found 426 427 427 428 LOGICAL :: tmp_found 428 429 INTEGER :: varid 429 430 INTEGER :: ierr 430 431 431 432 IF (is_mpi_root .AND. is_omp_root) THEN 432 433 433 434 ierr=NF90_INQ_VARID(nid_start,var_name,varid) 434 435 435 436 IF (ierr==NF90_NOERR) THEN 436 437 ierr=NF90_GET_VAR(nid_start,varid,var) … … 443 444 tmp_found=.FALSE. 444 445 ENDIF 445 446 ENDIF 447 446 447 ENDIF 448 448 449 CALL bcast(tmp_found) 449 450 … … 451 452 CALL bcast(var) 452 453 ENDIF 453 454 454 455 IF (PRESENT(found)) THEN 455 456 found=tmp_found … … 481 482 USE comsoil_h_PEM, only: nsoilmx_PEM 482 483 USE comslope_mod, only: nslope 484 use layering_mod, only: nb_str_max 483 485 IMPLICIT NONE 484 486 CHARACTER(LEN=*),INTENT(IN) :: filename … … 490 492 nqmx=nqtot 491 493 #endif 492 494 493 495 IF (is_master) THEN 494 496 if (.not.already_created) then … … 526 528 CALL abort_physic("open_restartphy","Failed defining index",1) 527 529 ENDIF 528 530 529 531 ierr=NF90_DEF_DIM(nid_restart,"physical_points",klon_glo,idim2) 530 532 IF (ierr/=NF90_NOERR) THEN … … 533 535 CALL abort_physic("open_restartphy","Failed defining physical_points",1) 534 536 ENDIF 535 537 536 538 ierr=NF90_DEF_DIM(nid_restart,"subsurface_layers",nsoilmx_PEM,idim3) 537 539 IF (ierr/=NF90_NOERR) THEN … … 540 542 CALL abort_physic("open_restartphy","Failed defining subsurface_layers",1) 541 543 ENDIF 542 544 543 545 ierr=NF90_DEF_DIM(nid_restart,"nlayer_plus_1",klevp1,idim4) 544 546 IF (ierr/=NF90_NOERR) THEN … … 547 549 CALL abort_physic("open_restartphy","Failed defining nlayer_plus_1",1) 548 550 ENDIF 549 551 550 552 if (nqmx.ne.0) then 551 553 ierr=NF90_DEF_DIM(nid_restart,"number_of_advected_fields",nqmx,idim5) … … 566 568 CALL abort_physic("open_restartphy","Failed defining nlayer",1) 567 569 ENDIF 568 570 569 571 ierr=NF90_DEF_DIM(nid_restart,"Time",NF90_UNLIMITED,idim7) 570 572 IF (ierr/=NF90_NOERR) THEN … … 588 590 ENDIF 589 591 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 590 598 591 599 ierr=NF90_ENDDEF(nid_restart) … … 608 616 ierr = NF90_CLOSE (nid_restart) 609 617 ENDIF 610 618 611 619 END SUBROUTINE close_restartphy 612 620 … … 618 626 REAL,INTENT(IN) :: field(:) 619 627 REAL,OPTIONAL,INTENT(IN) :: time 620 628 621 629 IF (present(time)) THEN 622 630 ! if timeindex is present, it is a time-dependent variable … … 625 633 CALL put_field_rgen(field_name,title,field,1) 626 634 ENDIF 627 635 628 636 END SUBROUTINE put_field_r1 629 637 … … 635 643 REAL,INTENT(IN) :: field(:,:) 636 644 REAL,OPTIONAL,INTENT(IN) :: time 637 645 638 646 IF (present(time)) THEN 639 647 ! if timeindex is present, it is a time-dependent variable … … 642 650 CALL put_field_rgen(field_name,title,field,size(field,2)) 643 651 ENDIF 644 652 645 653 END SUBROUTINE put_field_r2 646 654 … … 652 660 REAL,INTENT(IN) :: field(:,:,:) 653 661 REAL,OPTIONAL,INTENT(IN) :: time 654 662 655 663 IF (present(time)) THEN 656 664 ! if timeindex is present, it is a time-dependent variable 657 665 CALL put_field_rgen(field_name,title,field,size(field,2)*size(field,3),& 658 666 time) 659 ELSE 667 ELSE 660 668 CALL put_field_rgen(field_name,title,field,size(field,2)*size(field,3)) 661 669 ENDIF 662 670 663 671 END SUBROUTINE put_field_r3 664 672 665 673 SUBROUTINE put_field_rgen(field_name,title,field,field_size,time) 666 674 USE netcdf … … 668 676 USE comsoil_h_PEM, only: nsoilmx_PEM 669 677 USE comslope_mod, ONLY: nslope 678 use layering_mod, only: nb_str_max 670 679 USE mod_grid_phy_lmdz 671 680 USE mod_phys_lmdz_para … … 676 685 REAL,INTENT(IN) :: field(klon,field_size) 677 686 REAL,OPTIONAL,INTENT(IN) :: time 678 687 679 688 REAL :: field_glo(klon_glo,field_size) 680 689 INTEGER :: ierr 681 690 INTEGER :: nvarid 682 691 683 692 CALL gather(field,field_glo) 684 693 685 694 IF (is_master) THEN 686 695 … … 898 907 endif ! of if (.not.present(time)) 899 908 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 900 952 ELSE 901 953 write(*,*) "Error phyredem(put_field_rgen) : wrong dimension for ",trim(field_name) … … 912 964 913 965 ENDIF ! of IF (is_master) 914 915 END SUBROUTINE put_field_rgen 916 966 967 END SUBROUTINE put_field_rgen 968 917 969 SUBROUTINE put_var_r0(var_name,title,var) 918 970 ! Put a scalar in file … … 922 974 REAL,INTENT(IN) :: var 923 975 REAL :: varin(1) 924 976 925 977 varin(1)=var 926 978 927 979 CALL put_var_rgen(var_name,title,varin,size(varin)) 928 980 … … 936 988 CHARACTER(LEN=*),INTENT(IN) :: title 937 989 REAL,INTENT(IN) :: var(:) 938 990 939 991 CALL put_var_rgen(var_name,title,var,size(var)) 940 992 941 993 END SUBROUTINE put_var_r1 942 994 943 995 SUBROUTINE put_var_r2(var_name,title,var) 944 996 ! Put a 2D field in file … … 947 999 CHARACTER(LEN=*),INTENT(IN) :: title 948 1000 REAL,INTENT(IN) :: var(:,:) 949 1001 950 1002 CALL put_var_rgen(var_name,title,var,size(var)) 951 1003 952 END SUBROUTINE put_var_r2 953 1004 END SUBROUTINE put_var_r2 1005 954 1006 SUBROUTINE put_var_r3(var_name,title,var) 955 1007 ! Put a 3D field in file … … 958 1010 CHARACTER(LEN=*),INTENT(IN) :: title 959 1011 REAL,INTENT(IN) :: var(:,:,:) 960 1012 961 1013 CALL put_var_rgen(var_name,title,var,size(var)) 962 1014 … … 976 1028 INTEGER,INTENT(IN) :: var_size 977 1029 REAL,INTENT(IN) :: var(var_size) 978 1030 979 1031 INTEGER :: ierr 980 1032 INTEGER :: nvarid 981 1033 INTEGER :: idim1d 982 1034 logical,save :: firsttime=.true. 983 1035 984 1036 IF (is_master) THEN 985 1037 … … 998 1050 IF (LEN_TRIM(title) > 0) ierr=NF90_PUT_ATT(nid_restart,nvarid,"title",title) 999 1051 ierr=NF90_ENDDEF(nid_restart) 1000 1052 1001 1053 firsttime=.false. 1002 1054 endif … … 1019 1071 idim1d=idim1 1020 1072 ELSEIF (var_size==nsoilmx_PEM) THEN 1021 ! We know it is an 1073 ! We know it is an "mlayer" kind of 1D array 1022 1074 idim1d=idim3 1023 1075 ELSEIF (var_size==nslope+1) THEN 1024 ! We know it is an 1076 ! We know it is an "inter slope" kind of 1D array 1025 1077 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 1027 1082 write(*,*) "put_var_rgen error : wrong dimension" 1028 1083 write(*,*) " var_size =",var_size … … 1051 1106 ENDIF 1052 1107 ENDIF ! of IF (is_master) 1053 1054 END SUBROUTINE put_var_rgen 1108 1109 END SUBROUTINE put_var_rgen 1055 1110 1056 1111 END MODULE iostart_PEM -
trunk/LMDZ.COMMON/libf/evolution/layering_mod.F90
r3286 r3297 14 14 ! Numerical parameter 15 15 real, parameter :: eps = epsilon(1.), tol = 1.e2*eps 16 integer :: nb_str_max 16 17 17 18 ! Physical parameters … … 29 30 type :: stratum 30 31 real :: thickness ! Layer thickness [m] 31 real :: elevation ! Layerelevation (top height from the surface) [m]32 real :: top_elevation ! Layer top_elevation (top height from the surface) [m] 32 33 real :: co2ice_volfrac ! CO2 ice volumic fraction 33 34 real :: h2oice_volfrac ! H2O ice volumic fraction … … 45 46 end type layering 46 47 48 ! Array of pointers to "stratum" 49 type ptrarray 50 type(stratum), pointer :: p 51 end type ptrarray 52 47 53 !======================================================================= 48 54 contains 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 49 73 !======================================================================= 50 74 ! To display a stratum … … 58 82 !---- Code 59 83 write(*,'(a20,es13.6)') 'Thickness : ', this%thickness 60 write(*,'(a20,es13.6)') ' Elevation : ', this%elevation61 write(*,'(a20,es13.6)') 'CO2 ice content: ', this%co2ice_volfrac62 write(*,'(a20,es13.6)') 'H2O ice content: ', this%h2oice_volfrac63 write(*,'(a20,es13.6)') 'Dust content: ', this%dust_volfrac64 write(*,'(a20,es13.6)') 'Air content: ', this%air_volfrac84 write(*,'(a20,es13.6)') 'Top elevation : ', this%top_elevation 85 write(*,'(a20,es13.6)') 'CO2 ice (m3/m3): ', this%co2ice_volfrac 86 write(*,'(a20,es13.6)') 'H2O ice (m3/m3): ', this%h2oice_volfrac 87 write(*,'(a20,es13.6)') 'Dust (m3/m3) : ', this%dust_volfrac 88 write(*,'(a20,es13.6)') 'Air (m3/m3) : ', this%air_volfrac 65 89 66 90 END SUBROUTINE print_stratum 67 91 68 92 !======================================================================= 69 ! To display a layering70 SUBROUTINE print_lay(this)71 72 implicit none73 74 !---- Arguments75 type(layering), intent(in) :: this76 77 !---- Local variables78 type(stratum), pointer :: current79 integer :: i80 81 !---- Code82 current => this%top83 84 i = this%nb_str85 do while (associated(current))86 write(*,'(a8,i4)') 'Stratum ', i87 call print_stratum(current)88 write(*,*)89 current => current%down90 i = i - 191 enddo92 93 END SUBROUTINE print_lay94 95 !=======================================================================96 93 ! To add a stratum to the top of a layering 97 SUBROUTINE add_stratum(this,thickness, elevation,co2ice,h2oice,dust,air)94 SUBROUTINE add_stratum(this,thickness,top_elevation,co2ice,h2oice,dust,air) 98 95 99 96 implicit none … … 101 98 !---- Arguments 102 99 type(layering), intent(inout) :: this 103 real, intent(in), optional :: thickness, elevation, co2ice, h2oice, dust, air100 real, intent(in), optional :: thickness, top_elevation, co2ice, h2oice, dust, air 104 101 105 102 !---- Local variables … … 111 108 nullify(str%up,str%down) 112 109 str%thickness = 1. 113 str% elevation = 1.110 str%top_elevation = 1. 114 111 str%co2ice_volfrac = 0. 115 112 str%h2oice_volfrac = 0. … … 117 114 str%air_volfrac = 1. 118 115 if (present(thickness)) str%thickness = thickness 119 if (present( elevation)) str%elevation =elevation116 if (present(top_elevation)) str%top_elevation = top_elevation 120 117 if (present(co2ice)) str%co2ice_volfrac = co2ice 121 118 if (present(h2oice)) str%h2oice_volfrac = h2oice … … 144 141 !======================================================================= 145 142 ! To insert a stratum after another one in a layering 146 SUBROUTINE insert_stratum(this,str_prev,thickness, elevation,co2ice,h2oice,dust,air)143 SUBROUTINE insert_stratum(this,str_prev,thickness,top_elevation,co2ice,h2oice,dust,air) 147 144 148 145 implicit none … … 151 148 type(layering), intent(inout) :: this 152 149 type(stratum), pointer, intent(inout) :: str_prev 153 real, intent(in), optional :: thickness, elevation, co2ice, h2oice, dust, air150 real, intent(in), optional :: thickness, top_elevation, co2ice, h2oice, dust, air 154 151 155 152 !---- Local variables … … 158 155 !---- Code 159 156 if (.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) 161 158 else 162 159 ! Creation of the stratum … … 164 161 nullify(str%up,str%down) 165 162 str%thickness = 1. 166 str% elevation = 1.163 str%top_elevation = 1. 167 164 str%co2ice_volfrac = 0. 168 165 str%h2oice_volfrac = 0. … … 170 167 str%air_volfrac = 1. 171 168 if (present(thickness)) str%thickness = thickness 172 if (present( elevation)) str%elevation =elevation169 if (present(top_elevation)) str%top_elevation = top_elevation 173 170 if (present(co2ice)) str%co2ice_volfrac = co2ice 174 171 if (present(h2oice)) str%h2oice_volfrac = h2oice … … 189 186 str%up%down => str 190 187 191 ! Correct the value of elevation for the upper strata188 ! Correct the value of top_elevation for the upper strata 192 189 current => str%up 193 190 do while (associated(current)) 194 current% elevation = current%down%elevation + current%thickness191 current%top_elevation = current%down%top_elevation + current%thickness 195 192 current => current%up 196 193 enddo … … 214 211 !---- Code 215 212 ! Protect the 3 sub-surface strata from removing 216 if (str% elevation <= 0.) return213 if (str%top_elevation <= 0.) return 217 214 218 215 ! Decrement the number of strata 219 216 this%nb_str = this%nb_str - 1 220 217 221 ! Remove the stratum from the stratification218 ! Remove the stratum from the layering 222 219 str%down%up => str%up 223 220 if (associated(str%up)) then ! If it is not the last one at the top of the layering … … 235 232 236 233 !======================================================================= 234 ! To get a specific stratum in a layering 235 FUNCTION get_stratum(lay,i) RESULT(str) 236 237 implicit none 238 239 !---- Arguments 240 type(layering), intent(in) :: lay 241 integer, intent(in) :: i 242 type(stratum), pointer :: str 243 244 !---- Local variables 245 integer :: k 246 247 !---- Code 248 if (i < 1 .or. i > lay%nb_str) error stop 'get_stratum: requested number is beyond the number of strata of the layering!' 249 k = 1 250 str => lay%bottom 251 do while (k /= i) 252 str => str%up 253 k = k + 1 254 enddo 255 256 END FUNCTION get_stratum 257 258 !======================================================================= 237 259 ! To initialize the layering 238 260 SUBROUTINE ini_layering(this) … … 279 301 280 302 !======================================================================= 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 304 SUBROUTINE print_layering(this) 305 306 implicit none 307 308 !---- Arguments 309 type(layering), intent(in) :: this 310 311 !---- Local variables 319 312 type(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 313 integer :: i 314 315 !---- Code 316 current => this%top 317 318 i = this%nb_str 335 319 do 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 325 enddo 326 327 END SUBROUTINE print_layering 328 329 !======================================================================= 330 ! To get the maximum number of "stratum" in the stratification (layerings) 331 FUNCTION get_nb_str_max(stratif,ngrid,nslope) RESULT(nb_str_max) 332 333 implicit none 334 335 !---- Arguments 336 type(layering), dimension(ngrid,nslope), intent(in) :: stratif 337 integer, intent(in) :: ngrid, nslope 338 integer :: nb_str_max 339 340 !---- Local variables 341 integer :: ig, islope 342 343 !---- Code 344 nb_str_max = 0 345 do islope = 1,nslope 346 do ig = 1,ngrid 347 nb_str_max = max(stratif(ig,islope)%nb_str,nb_str_max) 348 enddo 349 enddo 350 351 END FUNCTION get_nb_str_max 352 353 !======================================================================= 354 ! To convert the stratification data structure (layerings) into an array able to be outputted 355 SUBROUTINE stratif2array(stratif,ngrid,nslope,stratif_array) 356 357 implicit none 358 359 !---- Arguments 360 integer, intent(in) :: ngrid, nslope 361 type(layering), dimension(ngrid,nslope), intent(in) :: stratif 362 real, dimension(:,:,:,:), allocatable, intent(inout) :: stratif_array 363 364 !---- Local variables 369 365 type(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 366 integer :: ig, islope, k 367 368 !---- Code 369 stratif_array = 0. 370 do 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 385 enddo 386 387 END SUBROUTINE stratif2array 388 389 !======================================================================= 390 ! To convert the stratification array into the stratification data structure (layerings) 391 SUBROUTINE array2stratif(stratif_array,ngrid,nslope,stratif) 392 393 implicit none 394 395 !---- Arguments 396 integer, intent(in) :: ngrid, nslope 397 real, dimension(:,:,:,:), allocatable, intent(in) :: stratif_array 398 type(layering), dimension(ngrid,nslope), intent(inout) :: stratif 399 400 !---- Local variables 401 type(stratum), pointer :: current 402 integer :: ig, islope, k 403 404 !---- Code 405 do 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 422 enddo 423 424 END SUBROUTINE array2stratif 425 426 !======================================================================= 427 ! To display a stratification (layerings) 428 SUBROUTINE print_stratif(this,ngrid,nslope) 429 430 implicit none 431 432 !---- Arguments 433 integer, intent(in) :: ngrid, nslope 434 type(layering), dimension(ngrid,nslope), intent(in) :: this 435 436 !---- Local variables 437 integer :: ig, islope 438 439 !---- Code 440 do 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(*,*) '--------------------' 448 enddo 449 450 END SUBROUTINE print_stratif 424 451 425 452 !======================================================================= 426 453 ! Layering algorithm 427 SUBROUTINE make_layering(this, k,htend_co2ice,htend_h2oice,htend_dust,new_str,new_lag1,new_lag2,stopPEM,current1,current2)454 SUBROUTINE make_layering(this,tend_co2ice,tend_h2oice,tend_dust,new_str,new_lag1,new_lag2,stopPEM,current1,current2) 428 455 429 456 implicit none … … 432 459 type(layering), intent(inout) :: this 433 460 type(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 461 logical, intent(inout) :: new_str, new_lag1, new_lag2 462 integer, intent(inout) :: stopPEM 463 real, intent(in) :: tend_co2ice, tend_h2oice, tend_dust 464 465 !---- Local variables 466 real :: htend_co2ice, htend_h2oice, htend_dust 467 real :: h_co2ice_old, h_h2oice_old, h_dust_old 468 real :: thickness, h2subl, h2subl_tot, h2lift, h2lift_tot 469 470 !---- Code 471 htend_co2ice = tend_co2ice/rho_co2ice 472 htend_h2oice = tend_h2oice/rho_h2oice 473 htend_dust = tend_dust/rho_dust 474 442 475 if (htend_dust < 0.) then ! Dust lifting 443 476 if (abs(htend_co2ice) > eps .or. abs(htend_h2oice) > eps) error stop 'Situation not managed: dust lifting + CO2/H2O ice condensation/sublimation!' 444 write(*,'(a 5,i3,a)') 'Year ', k, '-> Dust lifting'477 write(*,'(a)') ' Stratification -> Dust lifting' 445 478 h2lift_tot = abs(htend_dust) 446 479 do while (h2lift_tot > 0. .and. associated(current1)) … … 460 493 endif 461 494 else ! No, we stop 462 write(*,'(a 5,i3,a)') 'Year ', k, '-> Dust lifting: no dust lag!'463 stopPEM = .true.495 write(*,'(a)') ' Stratification -> Dust lifting: no dust lag!' 496 stopPEM = 7 464 497 exit 465 498 endif 466 499 enddo 467 500 if (h2lift_tot > 0.) then 468 write(*,'(a 5,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 470 503 endif 471 504 … … 474 507 !------ Dust sedimentation 475 508 if (abs(htend_co2ice) < eps .and. abs(htend_h2oice) < eps) then 476 write(*,'(a 5,i3,a)') 'Year ', k, '-> Dust sedimentation'509 write(*,'(a)') ' Stratification -> Dust sedimentation' 477 510 ! New stratum at the layering top by sedimentation of dust 478 511 thickness = htend_dust/(1. - dry_regolith_porosity) 479 512 if (thickness > 0.) then ! Only if the stratum is builiding up 480 513 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) 482 515 new_str = .false. 483 516 else 484 517 this%top%thickness = this%top%thickness + thickness 485 this%top% elevation = this%top%elevation + thickness518 this%top%top_elevation = this%top%top_elevation + thickness 486 519 endif 487 520 endif … … 489 522 !------ Condensation of CO2 ice + H2O ice 490 523 else if ((htend_co2ice >= 0. .and. htend_h2oice > 0.) .or. (htend_co2ice > 0. .and. htend_h2oice >= 0.)) then 491 write(*,'(a 5,i3,a)') 'Year ', k, '-> CO2 and H2O ice condensation'524 write(*,'(a)') ' Stratification -> CO2 and H2O ice condensation' 492 525 ! New stratum at the layering top by condensation of CO2 and H2O ice 493 526 thickness = htend_co2ice/(1. - co2ice_porosity) + htend_h2oice/(1. - h2oice_porosity) + htend_dust 494 527 if (thickness > 0.) then ! Only if the stratum is builiding up 495 528 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)) 497 530 new_str = .false. 498 531 else 499 532 this%top%thickness = this%top%thickness + thickness 500 this%top% elevation = this%top%elevation + thickness533 this%top%top_elevation = this%top%top_elevation + thickness 501 534 endif 502 535 endif … … 504 537 !------ Sublimation of CO2 ice + Condensation of H2O ice 505 538 else if (htend_co2ice < 0. .and. htend_h2oice >= 0. ) then 506 write(*,'(a 5,i3,a)') 'Year ', k, '-> Sublimation of CO2 ice + Condensation of H2O ice'539 write(*,'(a)') ' Stratification -> Sublimation of CO2 ice + Condensation of H2O ice' 507 540 ! CO2 ice sublimation in the considered stratum + New stratum for dust lag 508 541 h2subl_tot = abs(htend_co2ice) … … 528 561 enddo 529 562 if (h2subl_tot > 0.) then 530 write(*,'(a 5,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 532 565 endif 533 566 ! New stratum at the layering top by condensation of H2O ice … … 535 568 if (thickness > 0.) then ! Only if the stratum is builiding up 536 569 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)) 538 571 new_str = .false. 539 572 else 540 573 this%top%thickness = this%top%thickness + thickness 541 this%top% elevation = this%top%elevation + thickness574 this%top%top_elevation = this%top%top_elevation + thickness 542 575 endif 543 576 endif … … 545 578 !------ Sublimation of CO2 ice + H2O ice 546 579 else if (htend_co2ice < 0. .and. htend_h2oice < 0.) then 547 write(*,'(a 5,i3,a)') 'Year ', k, '-> Sublimation of CO2 and H2O ice'580 write(*,'(a)') ' Stratification -> Sublimation of CO2 and H2O ice' 548 581 ! CO2 ice sublimation in the considered stratum + New stratum for dust lag 549 582 h2subl_tot = abs(htend_co2ice) … … 569 602 enddo 570 603 if (h2subl_tot > 0.) then 571 write(*,'(a 5,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 573 606 endif 574 607 ! H2O ice sublimation in the considered stratum + New stratum for dust lag … … 595 628 enddo 596 629 if (h2subl_tot > 0.) then 597 write(*,'(a 5,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 599 632 endif 600 633 … … 607 640 END SUBROUTINE make_layering 608 641 642 !======================================================================= 643 ! To sublimate CO2 ice in the layering 644 SUBROUTINE subl_co2ice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag) 645 646 implicit none 647 648 !---- Arguments 649 type(layering), intent(inout) :: this 650 type(stratum), pointer, intent(inout) :: str 651 logical, intent(inout) :: new_lag 652 real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old 653 654 !---- Local variables 655 real :: r_subl, hsubl_dust, h_lag 656 type(stratum), pointer :: current 657 658 !---- Code 659 ! How much dust does CO2 ice sublimation involve to create the lag? 660 r_subl = h2subl/(1. - co2ice_porosity) & 661 /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity))) 662 hsubl_dust = r_subl*str%dust_volfrac*str%thickness 663 ! Update of properties in the sublimating stratum 664 str%thickness = str%thickness - h2subl/(1. - co2ice_porosity) - hsubl_dust 665 str%top_elevation = str%top_elevation - h2subl/(1. - co2ice_porosity) - hsubl_dust 666 str%co2ice_volfrac = (h_co2ice_old - h2subl)/str%thickness 667 str%h2oice_volfrac = h_h2oice_old/str%thickness 668 str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness 669 str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac) 670 ! Correct the value of top_elevation for the upper strata 671 current => str%up 672 do while (associated(current)) 673 current%top_elevation = current%down%top_elevation + current%thickness 674 current => current%up 675 enddo 676 ! Remove the sublimating stratum if there is no ice anymore 677 if (str%thickness < tol) call rm_stratum(this,str) 678 ! New stratum = dust lag 679 h_lag = hsubl_dust/(1. - dry_lag_porosity) 680 if (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 688 endif 689 690 END SUBROUTINE subl_co2ice_layering 691 692 !======================================================================= 693 ! To sublimate H2O ice in the layering 694 SUBROUTINE subl_h2oice_layering(this,str,h2subl,h_co2ice_old,h_h2oice_old,h_dust_old,new_lag) 695 696 implicit none 697 698 !---- Arguments 699 type(layering), intent(inout) :: this 700 type(stratum), pointer, intent(inout) :: str 701 logical, intent(inout) :: new_lag 702 real, intent(in) :: h2subl, h_co2ice_old, h_h2oice_old, h_dust_old 703 704 !---- Local variables 705 real :: r_subl, hsubl_dust, h_lag 706 type(stratum), pointer :: current 707 708 !---- Code 709 ! How much dust does CO2 ice sublimation involve to create the lag? 710 r_subl = h2subl/(1. - h2oice_porosity) & 711 /(str%thickness*(str%co2ice_volfrac/(1. - co2ice_porosity) + str%h2oice_volfrac/(1. - h2oice_porosity))) 712 hsubl_dust = r_subl*str%dust_volfrac*str%thickness 713 ! Update of properties in the sublimating stratum 714 str%thickness = str%thickness - h2subl/(1. - h2oice_porosity) - hsubl_dust 715 str%top_elevation = str%top_elevation - h2subl/(1. - h2oice_porosity) - hsubl_dust 716 str%co2ice_volfrac = h_co2ice_old/str%thickness 717 str%h2oice_volfrac = (h_h2oice_old - h2subl)/str%thickness 718 str%dust_volfrac = (h_dust_old - hsubl_dust)/str%thickness 719 str%air_volfrac = 1. - (str%co2ice_volfrac + str%h2oice_volfrac + str%dust_volfrac) 720 ! Correct the value of top_elevation for the upper strata 721 current => str%up 722 do while (associated(current)) 723 current%top_elevation = current%down%top_elevation + current%thickness 724 current => current%up 725 enddo 726 ! Remove the sublimating stratum if there is no ice anymore 727 if (str%thickness < tol) call rm_stratum(this,str) 728 ! New stratum = dust lag 729 h_lag = hsubl_dust/(1. - dry_lag_porosity) 730 if (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 738 endif 739 740 END SUBROUTINE subl_h2oice_layering 741 742 !======================================================================= 743 ! To lift dust in the layering 744 SUBROUTINE lift_dust_lags(this,str,h2lift) 745 746 implicit none 747 748 !---- Arguments 749 type(layering), intent(inout) :: this 750 type(stratum), pointer, intent(inout) :: str 751 real, intent(in) :: h2lift 752 753 !---- Code 754 ! Update of properties in the eroding dust lag 755 str%thickness = str%thickness - h2lift/(1. - str%air_volfrac) 756 str%top_elevation = str%top_elevation - h2lift/(1. - str%air_volfrac) 757 ! Remove the eroding dust lag if there is no dust anymore 758 if (str%thickness < tol) call rm_stratum(this,str) 759 760 END SUBROUTINE lift_dust_lags 761 609 762 END MODULE layering_mod -
trunk/LMDZ.COMMON/libf/evolution/pem.F90
r3287 r3297 46 46 use comsoil_h_PEM, only: soil_pem, ini_comsoil_h_PEM, end_comsoil_h_PEM, nsoilmx_PEM, & 47 47 TI_PEM, & ! soil thermal inertia 48 tsoil_PEM, layer_PEM, & ! Soil temp, number of subsurface layers, soil mid layer depths48 tsoil_PEM, layer_PEM, & ! Soil temp, number of subsurface layers, soil mid layer depths 49 49 fluxgeo ! Geothermal flux for the PEM and PCM 50 50 use adsorption_mod, only: regolith_adsorption, adsorption_pem, & ! Bool to check if adsorption, main subroutine … … 70 70 use writediagpem_mod, only: writediagpem, writediagsoilpem 71 71 use co2condens_mod, only: CO2cond_ps 72 use layering_mod, only: tend_dust, ptrarray, stratum, layering, ini_layering, del_layering, make_layering, get_nb_str_max, nb_str_max 72 73 73 74 #ifndef CPP_STD … … 126 127 real :: time_phys ! Same as in PCM 127 128 real :: ptimestep ! Same as in PCM 128 real :: ztime_fin ! Same as in PCM129 real :: ztime_fin ! Same as in PCM 129 130 130 131 ! Variables to read start.nc … … 183 184 real, dimension(:,:), allocatable :: vmr_co2_PEM_phys ! Physics x Times co2 volume mixing ratio used in the PEM 184 185 real, 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 188 type(layering), dimension(:,:), allocatable :: stratif ! Layering (linked list of "stratum") for each grid point and slope 189 type(ptrarray), dimension(:,:), allocatable :: current1, current2 ! Current active stratum in the layering 190 logical, dimension(:,:), allocatable :: new_str, new_lag1, new_lag2 ! Flags for the layering algorithm 185 191 186 192 ! Variables for slopes … … 582 588 deallocate(min_co2_ice,min_h2o_ice) 583 589 590 allocate(stratif(ngrid,nslope)) 591 do islope = 1,nslope 592 do i = 1,ngrid 593 call ini_layering(stratif(i,islope)) 594 enddo 595 enddo 596 584 597 call pemetat0("startpem.nc",ngrid,nsoilmx,nsoilmx_PEM,nslope,timelen,timestep,TI_PEM,tsoil_PEM,porefillingice_depth, & 585 598 porefillingice_thickness,tsurf_avg_yr1,tsurf_ave,q_co2_PEM_phys,q_h2o_PEM_phys,ps_timeseries, & 586 599 tsoil_phys_PEM_timeseries,tend_h2o_ice,tend_co2_ice,co2_ice,h2o_ice,global_avg_press_PCM, & 587 600 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) 589 602 590 603 allocate(co2_ice_ini(ngrid,nslope)) … … 642 655 year_iter = 0 643 656 stopPEM = 0 644 645 do while (year_iter < year_iter_max .and. i_myear < n_myear) 657 allocate(new_str(ngrid,nslope),new_lag1(ngrid,nslope),new_lag2(ngrid,nslope),current1(ngrid,nslope),current2(ngrid,nslope)) 658 new_str = .true. 659 new_lag1 = .true. 660 new_lag2 = .true. 661 do 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 666 enddo 667 668 do while (year_iter < 10 .and. i_myear < n_myear) 646 669 ! II.a.1. Compute updated global pressure 647 670 write(*,*) "Recomputing the new pressure..." … … 725 748 call evol_h2o_ice(ngrid,nslope,cell_area,delta_h2o_adsorbded,delta_h2o_icetablesublim,h2o_ice,tend_h2o_ice,stopPEM) 726 749 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 727 755 728 756 !------------------------ … … 1094 1122 ! III_c Write the "restartpem.nc" 1095 1123 !------------------------ 1124 nb_str_max = get_nb_str_max(stratif,ngrid,nslope) ! Get the maximum number of "stratum" in the stratification (layerings) 1096 1125 call pemdem0("restartpem.nc",longitude,latitude,cell_area,ngrid,nslope,def_slope,subslope_dist) 1097 1126 call 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) 1100 1129 write(*,*) "restartpem.nc has been written" 1101 1130 … … 1107 1136 write(*,*) "LL & RV & JBC: so far, so good!" 1108 1137 1138 do islope = 1,nslope 1139 do i = 1,ngrid 1140 call del_layering(stratif(i,islope)) 1141 enddo 1142 enddo 1143 deallocate(stratif,new_str,new_lag1,new_lag2,current1,current2) 1109 1144 deallocate(vmr_co2_PCM,ps_timeseries,tsurf_PCM_timeseries,q_co2_PEM_phys,q_h2o_PEM_phys) 1110 1145 deallocate(co2_ice_PCM,watersurf_density_ave,watersoil_density_timeseries,Tsurfavg_before_saved) -
trunk/LMDZ.COMMON/libf/evolution/pemetat0.F90
r3214 r3297 10 10 tsurf_avg_yr1,tsurf_avg_yr2,q_co2,q_h2o,ps_inst,tsoil_inst,tend_h2o_ice,tend_co2_ice,co2_ice,h2o_ice, & 11 11 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 14 use iostart_PEM, only: open_startphy, close_startphy, get_field, get_var, inquire_dimension, inquire_dimension_length 15 15 use comsoil_h_PEM, only: soil_pem, layer_PEM, mlayer_PEM, fluxgeo, inertiedat_PEM, ini_huge_h2oice, depth_breccia, depth_bedrock, index_breccia, index_bedrock 16 16 use comsoil_h, only: volcapa, inertiedat … … 23 23 use compute_soiltemp_mod, only: ini_tsoil_pem, compute_tsoil_pem 24 24 use comslope_mod, only: def_slope_mean, subslope_dist 25 use layering_mod, only: layering, array2stratif 25 26 26 27 #ifndef CPP_STD … … 35 36 include "callkeys.h" 36 37 37 character( len=*),intent(in) :: filename ! name of the startfi_PEM.nc38 character(*), intent(in) :: filename ! name of the startfi_PEM.nc 38 39 integer, intent(in) :: ngrid ! # of physical grid points 39 40 integer, intent(in) :: nsoil_PCM ! # of vertical grid points in the PCM … … 56 57 real, dimension(ngrid,nslope), intent(out) :: h2o_ice ! h2o ice amount [kg/m^2] 57 58 real, dimension(ngrid,nslope), intent(out) :: co2_ice ! co2 ice amount [kg/m^2] 59 type(layering), dimension(ngrid,nslope), intent(inout) :: stratif ! stratification (layerings) 58 60 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: TI_PEM ! soil (mid-layer) thermal inertia in the PEM grid [SI] 59 61 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: tsoil_PEM ! soil (mid-layer) temperature [K] … … 65 67 real, dimension(ngrid,nsoil_PEM,nslope), intent(inout) :: watersoil_avg ! surface water ice density, yearly averaged (kg/m^3) 66 68 ! 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 69 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_startPEM ! soil temperature saved in the start [K] 70 real, dimension(ngrid,nsoil_PEM,nslope) :: TI_startPEM ! soil thermal inertia saved in the start [SI] 71 logical :: found, found2 ! check if variables are found in the start 72 integer :: iloop, ig, islope, it, isoil, k ! index for loops 73 real :: kcond ! Thermal conductivity, intermediate variable [SI] 74 real :: delta ! Depth of the interface regolith-breccia, breccia -bedrock [m] 75 character(2) :: num ! intermediate string to read PEM start sloped variables 76 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr1 ! intermediate soil temperature during yr 1 [K] 77 real, dimension(ngrid,nsoil_PEM,nslope) :: tsoil_tmp_yr2 ! intermediate soil temperature during yr 2 [K] 78 logical :: startpem_file ! boolean to check if we read the startfile or not 79 real, dimension(:,:,:,:), allocatable :: stratif_array ! Array for stratification (layerings) 80 real :: nb_str_max 78 81 79 82 #ifdef CPP_STD … … 112 115 ! open pem initial state file: 113 116 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) 114 149 115 150 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! … … 320 355 else !No startfi, let's build all by hand 321 356 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 322 363 ! h2o ice 323 364 h2o_ice = 0. 324 write(*,*)'There is no "startpem.nc"!'325 365 write(*,*)'So ''h2o_ice'' is initialized with default value ''ini_huge_h2oice'' where ''watercaptag'' is true.' 326 366 do ig = 1,ngrid -
trunk/LMDZ.COMMON/libf/evolution/pemredem.F90
r3206 r3297 58 58 59 59 SUBROUTINE 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) 61 61 62 62 ! write time-dependent variable to restart file … … 64 64 use comsoil_h_PEM, only: inertiedat_PEM, soil_pem 65 65 use time_evol_mod, only: year_bp_ini, convert_years 66 use layering_mod, only: layering, nb_str_max, stratif2array, print_layering 66 67 67 68 implicit none … … 79 80 real, dimension(ngrid,nsoil_PEM,nslope), intent(in) :: m_co2_regolith, m_h2o_regolith 80 81 real, dimension(ngrid,nslope), intent(in) :: h2o_ice 82 type(layering), dimension(ngrid,nslope), intent(in) :: stratif ! Stratification (layerings) 81 83 82 integer :: islope 83 character(2) :: num 84 real :: Year ! Year of the simulation 84 integer :: islope 85 character(2) :: num 86 real :: Year ! Year of the simulation 87 real, dimension(:,:,:,:), allocatable :: stratif_array ! Array for stratification (layerings) 85 88 86 89 ! Open file … … 92 95 call put_var("Time","Year of simulation",Year) 93 96 call put_field('h2o_ice','h2o_ice',h2o_ice,Year) 97 98 allocate(stratif_array(ngrid,nslope,nb_str_max,6)) 99 call stratif2array(stratif,ngrid,nslope,stratif_array) 100 do 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) 108 enddo 109 deallocate(stratif_array) 94 110 95 111 if (soil_pem) then
Note: See TracChangeset
for help on using the changeset viewer.