diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3381f063..e8edae433 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,18 @@ name: CI -on: [push, pull_request] +on: + push: + branches: + - master + - main + + pull_request: jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get install -y --no-install-recommends gfortran libhdf5-openmpi-dev libopenmpi-dev - name: Install ED2 @@ -14,52 +20,26 @@ jobs: cd ED/build ./install.sh -g -p travisci -k A - name: Upload compiled ED2 binary - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: ed2-binary path: ED/build/ed_2.2-dbg - test-umbs-bg: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Retrieve compiled binary - uses: actions/download-artifact@v1 - with: - name: ed2-binary - - name: Install dependencies - run: sudo apt-get install -y --no-install-recommends gfortran libhdf5-openmpi-dev libopenmpi-dev - - name: Run ED2 - working-directory: ./EDTS/ - run: | - chmod +x "$GITHUB_WORKSPACE"/ed2-binary/ed_2.2-dbg - ./run-test.sh umbs.bg "$GITHUB_WORKSPACE/ed2-binary/ed_2.2-dbg" - - test-tonzi: + tests: needs: build runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Retrieve compiled binary - uses: actions/download-artifact@v1 - with: - name: ed2-binary - - name: Install dependencies - run: sudo apt-get install -y --no-install-recommends gfortran libhdf5-openmpi-dev libopenmpi-dev - - name: Run ED2 - working-directory: ./EDTS/ - run: | - chmod +x "$GITHUB_WORKSPACE"/ed2-binary/ed_2.2-dbg - ./run-test.sh tonzi "$GITHUB_WORKSPACE/ed2-binary/ed_2.2-dbg" + strategy: + fail-fast: false + matrix: + name: + - umbs.bg + - tonzi + - tonzi.harvest - test-tonzi-harvest: - needs: build - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Retrieve compiled binary - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4 with: name: ed2-binary - name: Install dependencies @@ -67,5 +47,5 @@ jobs: - name: Run ED2 working-directory: ./EDTS/ run: | - chmod +x "$GITHUB_WORKSPACE"/ed2-binary/ed_2.2-dbg - ./run-test.sh tonzi.harvest "$GITHUB_WORKSPACE/ed2-binary/ed_2.2-dbg" + chmod +x "$GITHUB_WORKSPACE"/ed_2.2-dbg + ./run-test.sh ${{ matrix.name }} "$GITHUB_WORKSPACE/ed_2.2-dbg" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 824ab0ab9..c6117af85 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,7 +1,7 @@ name: Docker # This will run when: -# - when new code is pushed to master to push the tags latest. +# - when new code is pushed to master/main to push the tags latest. # - when a pull request is created and updated to make sure the # Dockerfile is still valid. @@ -19,77 +19,189 @@ on: push: branches: - master + - main + + release: + types: + - published pull_request: -# Certain actions will only run when this is the master repo. +# Certain actions will only run when this is the master/main repo. env: - MASTER_REPO: EDModel/ED2 - DOCKERHUB_ORG: pecan + MAIN_REPO: EDmodel/ED2 + DOCKERHUB_ORG: edmodel jobs: docker: runs-on: ubuntu-latest + permissions: + packages: write + + strategy: + fail-fast: false + matrix: + include: + - name: gnu + PLATFORM: "linux/amd64,linux/arm64" + - name: intel + PLATFORM: "linux/amd64" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + + # free up space + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: false + swap-storage: true # calculate some variables that are used later - - name: github branch + - name: version information run: | - BRANCH=${GITHUB_REF##*/} - if [ "$BRANCH" == "master" ]; then - TAGS="latest" + # find out what the BRANCH is, in case of a PR we will use the PR- + if [ "${{ github.event.release.target_commitish }}" != "" ]; then + BRANCH="${{ github.event.release.target_commitish }}" + elif [[ $GITHUB_REF =~ pull ]]; then + BRANCH="$(echo $GITHUB_REF | sed 's#refs/pull/\([0-9]*\)/merge#PR-\1#')" else - TAGS="$BRANCH" + BRANCH=${GITHUB_REF##*/} fi - echo "TAGS=${TAGS}" >> $GITHUB_ENV - echo "GITHUB_BRANCH=${BRANCH}" >> $GITHUB_ENV - # build the docker image, this will always run to make sure - # the Dockerfile still works. - - name: Build image - uses: elgohr/Publish-Docker-Github-Action@2.22 - env: - BRANCH: ${{ env.GITHUB_BRANCH }} - BUILDNUMBER: ${{ github.run_number }} - GITSHA1: ${{ github.sha }} + # calculate the version and all tags + if [ "$BRANCH" == "main" -o "$BRANCH" == "master" ]; then + VERSION="latest" + tags="${{ matrix.name }}" + if [ "${{ matrix.name }}" == "intel" ]; then + tags="${tags} latest" + fi + else + VERSION="${{ matrix.name }}-$BRANCH" + tags="${{ matrix.name }}-$BRANCH" + fi + + # should we push to dockerhub, and is there a README + DOCKERHUB_PUSH="false" + DOCKERHUB_README="false" + if [ "${{ github.repository }}" == "${{ env.MAIN_REPO }}" ]; then + if [ "${{ secrets.DOCKERHUB_USERNAME }}" != "" -a "${{ secrets.DOCKERHUB_PASSWORD }}" != "" ]; then + DOCKERHUB_PUSH="true" + if [ -e "README.md" ]; then + DOCKERHUB_README="true" + fi + fi + fi + + # create a list of all images to be pushed + REPO="${{ github.repository_owner }}" + REPO="${REPO,,}" + IMAGE="${{ github.event.repository.name }}" + IMAGE="${IMAGE,,}" + DEV_IMAGES="" + IMAGES="" + for tag in ${tags}; do + if [ "$DOCKERHUB_PUSH" == "true" ]; then + DEV_IMAGES="${DEV_IMAGES}${{ env.DOCKERHUB_ORG }}/${IMAGE}-dev:${tag}," + IMAGES="${IMAGES}${{ env.DOCKERHUB_ORG }}/${IMAGE}:${tag}," + fi + DEV_IMAGES="${DEV_IMAGES}ghcr.io/${REPO}/${IMAGE}-dev:${tag}," + IMAGES="${IMAGES}ghcr.io/${REPO}/${IMAGE}:${tag}," + done + IMAGES="${IMAGES%,*}" + + # save the results in env + echo "BRANCH=${BRANCH}" + echo "VERSION=${VERSION}" + echo "DOCKERHUB_README=${DOCKERHUB_README}" + echo "DOCKERHUB_PUSH=${DOCKERHUB_PUSH}" + echo "IMAGES=${IMAGES}" + + echo "BRANCH=${BRANCH}" >> $GITHUB_ENV + echo "VERSION=${VERSION}" >> $GITHUB_ENV + echo "DOCKERHUB_README=${DOCKERHUB_README}" >> $GITHUB_ENV + echo "DOCKERHUB_PUSH=${DOCKERHUB_PUSH}" >> $GITHUB_ENV + echo "DEV_IMAGES=${DEV_IMAGES}" >> $GITHUB_ENV + echo "IMAGES=${IMAGES}" >> $GITHUB_ENV + + # setup docker build + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Inspect Builder + run: | + echo "Name: ${{ steps.buildx.outputs.name }}" + echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}" + echo "Status: ${{ steps.buildx.outputs.status }}" + echo "Flags: ${{ steps.buildx.outputs.flags }}" + echo "Platforms: ${{ steps.buildx.outputs.platforms }}" + + # login to registries + - name: Login to DockerHub + if: env.DOCKERHUB_PUSH == 'true' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 with: - registry: docker.pkg.github.com - name: ${{ github.repository_owner }}/${{ github.event.repository.name }}/ed + registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - tags: "${{ env.TAGS }}" - buildargs: BRANCH,BUILDNUMBER,GITSHA1 - no_push: true - - # this will publish to github container registry - - name: Publish to GitHub - if: github.event_name == 'push' && github.repository == env.MASTER_REPO - uses: elgohr/Publish-Docker-Github-Action@2.22 - env: - BRANCH: ${{ env.GITHUB_BRANCH }} - BUILDNUMBER: ${{ github.run_number }} - GITSHA1: ${{ github.sha }} + + - name: DF + run: df -h . + + # build the dev docker images + - name: Build and push docker + uses: docker/build-push-action@v6 with: - registry: ghcr.io - name: ${{ github.repository_owner }}/ed - username: ${{ secrets.GHCR_USERNAME }} - password: ${{ secrets.GHCR_PASSWORD }} - tags: "${{ env.TAGS }}" - buildargs: BRANCH,BUILDNUMBER,GITSHA1 - - # this will publish to the pecan dockerhub repo - - name: Publish to Docker Hub - if: github.event_name == 'push' && github.repository == env.MASTER_REPO - uses: elgohr/Publish-Docker-Github-Action@2.22 - env: - BRANCH: ${{ env.GITHUB_BRANCH }} - BUILDNUMBER: ${{ github.run_number }} - GITSHA1: ${{ github.sha }} + push: true + platforms: ${{ matrix.PLATFORM }} + file: Dockerfile.${{ matrix.name }} + target: build + cache-from: type=gha,scope=ed-${{ matrix.name }}-build + cache-to: type=gha,scope=ed-${{ matrix.name }}-build,mode=max + tags: ${{ env.DEV_IMAGES }} + build-args: | + BRANCH: ${{ env.BRANCH }} + VERSION=${{ env.VERSION }} + BUILDNUMBER=${{ github.run_number }} + GITSHA1=${{ github.sha }} + + # build the docker images + - name: Build and push docker + uses: docker/build-push-action@v6 with: - name: ${{ env.DOCKERHUB_ORG }}/ed - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - tags: "${{ env.TAGS }}" - buildargs: BRANCH,BUILDNUMBER,GITSHA1 + push: true + platforms: ${{ matrix.PLATFORM }} + file: Dockerfile.${{ matrix.name }} + cache-from: type=gha,scope=ed-${{ matrix.name }}-build + cache-to: type=gha,scope=ed-${{ matrix.name }}-build,mode=max + tags: ${{ env.IMAGES }} + build-args: | + BRANCH: ${{ env.BRANCH }} + VERSION=${{ env.VERSION }} + BUILDNUMBER=${{ github.run_number }} + GITSHA1=${{ github.sha }} + + # this will update the README of the dockerhub repo + - name: Docker Hub Description + if: env.DOCKERHUB_README == 'true' + uses: peter-evans/dockerhub-description@v4 + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} + DOCKERHUB_REPOSITORY: ${{ env.DOCKERHUB_ORG }}/${{ github.event.repository.name }} + README_FILEPATH: README.md diff --git a/BRAMS/Template/RAMSIN b/BRAMS/Template/RAMSIN index 0e9b47465..e7e1c90ca 100644 --- a/BRAMS/Template/RAMSIN +++ b/BRAMS/Template/RAMSIN @@ -1545,14 +1545,17 @@ $MODEL_OPTIONS ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. ! ! For regional runs, it is wise to use options 1 or 2, especially for ! ! long runs. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is 0. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, ! + ! use flat bedrock, otherwise assume free drainage. This option is ! + ! morerelevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Zero flux from the bottom of the bottommost layer. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of ! ! the bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction ! ! is controlled by variable SLDRAIN. In the future options 0, 1, and ! ! 2 may be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! ! is always at saturation. ! !------------------------------------------------------------------------------------! ISOILBC = 1, @@ -2033,7 +2036,7 @@ $ED2_INFO ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -2041,6 +2044,10 @@ $ED2_INFO ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! IED_INIT_MODE = 5, !---------------------------------------------------------------------------------------! @@ -2347,13 +2354,19 @@ $ED2_INFO ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! IALLOM = 3, !---------------------------------------------------------------------------------------! @@ -2425,10 +2438,25 @@ $ED2_INFO ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! IPHEN_SCHEME = 2, !---------------------------------------------------------------------------------------! @@ -3000,6 +3028,7 @@ $ED2_INFO ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! @@ -3019,6 +3048,7 @@ $ED2_INFO SL_MINDBH_HARVEST = 35.0,35.0,35.0, SL_BIOMASS_HARVEST = 0., SL_SKID_REL_AREA = 0.6, + SL_SKID_DBH_THRESH = 30., SL_SKID_S_GTHARV = 1.00, SL_SKID_S_LTHARV = 0.60, SL_FELLING_S_LTHARV = 0.35, diff --git a/BRAMS/run/RAMSIN b/BRAMS/run/RAMSIN index dd87f6b44..53041269d 100644 --- a/BRAMS/run/RAMSIN +++ b/BRAMS/run/RAMSIN @@ -1552,14 +1552,17 @@ $MODEL_OPTIONS ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. ! ! For regional runs, it is wise to use options 1 or 2, especially for ! ! long runs. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is 0. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, ! + ! use flat bedrock, otherwise assume free drainage. This option is ! + ! morerelevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Zero flux from the bottom of the bottommost layer. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of ! ! the bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction ! ! is controlled by variable SLDRAIN. In the future options 0, 1, and ! ! 2 may be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! ! is always at saturation. ! !------------------------------------------------------------------------------------! ISOILBC = 1, @@ -2050,7 +2053,7 @@ $ED2_INFO ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -2058,6 +2061,10 @@ $ED2_INFO ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! IED_INIT_MODE = 5, !---------------------------------------------------------------------------------------! @@ -2365,13 +2372,19 @@ $ED2_INFO ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! IALLOM = 3, !---------------------------------------------------------------------------------------! @@ -2443,10 +2456,25 @@ $ED2_INFO ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! IPHEN_SCHEME = 2, !---------------------------------------------------------------------------------------! @@ -3018,6 +3046,7 @@ $ED2_INFO ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! @@ -3037,6 +3066,7 @@ $ED2_INFO SL_MINDBH_HARVEST = 35.0,35.0,35.0, SL_BIOMASS_HARVEST = 0., SL_SKID_REL_AREA = 0.6, + SL_SKID_DBH_THRESH = 30., SL_SKID_S_GTHARV = 1.00, SL_SKID_S_LTHARV = 0.60, SL_FELLING_S_LTHARV = 0.35, diff --git a/BRAMS/src/core/local_proc.F90 b/BRAMS/src/core/local_proc.F90 index e538cb55a..f01819257 100644 --- a/BRAMS/src/core/local_proc.F90 +++ b/BRAMS/src/core/local_proc.F90 @@ -325,6 +325,9 @@ subroutine master_putdxt(master_num) use rpara, only : & nmachs, & ! INTENT(IN) machnum ! INTENT(IN) +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -333,10 +336,6 @@ subroutine master_putdxt(master_num) real :: dxtmax(maxgrds) integer :: master_num,ierr -#if defined(RAMS_MPI) - include 'mpif.h' -#endif - ! Calculating DXTMAX do ifm = 1,ngrids nn2 = nnxp(ifm) @@ -367,10 +366,10 @@ subroutine master_putcflmax(master_num) nmachs, & ! INTENT(IN) machnum, & ! INTENT(IN) mainnum ! intent(in) - #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none integer :: master_num,ierr #if defined(RAMS_MPI) @@ -387,11 +386,11 @@ subroutine node_getdxt(dxtmax_local) use io_params, only : & maxgrds ! INTENT(IN) use node_mod, only: master_num - implicit none - #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none + real, intent(out) :: dxtmax_local(maxgrds) integer :: ierr #if defined(RAMS_MPI) @@ -413,12 +412,12 @@ subroutine node_getcflmax() cflxy, & ! INTENT(OUT) cflz ! INTENT(OUT) use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none -#if defined(RAMS_MPI) - include 'mpif.h' -#endif integer :: ierr #if defined(RAMS_MPI) diff --git a/BRAMS/src/core/model.F90 b/BRAMS/src/core/model.F90 index b7e7f2bac..f61570550 100644 --- a/BRAMS/src/core/model.F90 +++ b/BRAMS/src/core/model.F90 @@ -265,6 +265,9 @@ subroutine par_model(master_num) ptimes ! INTENT(IN) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none ! +------------------------------------------------------------------ @@ -284,9 +287,6 @@ subroutine par_model(master_num) !MLO integer :: ierr, master_num -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !ALF real :: dxtmax_local(maxgrds) diff --git a/BRAMS/src/core/rammain.F90 b/BRAMS/src/core/rammain.F90 index fd6c98910..fe4a86f4c 100644 --- a/BRAMS/src/core/rammain.F90 +++ b/BRAMS/src/core/rammain.F90 @@ -16,6 +16,9 @@ program main ! invoking master/slave processes or full model process ! destroy processes ! +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -65,7 +68,6 @@ program main ! For MPI interface integer :: ierr #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif ! Get input arguments (required by C interface of MPI_Init) diff --git a/BRAMS/src/core/rams_master.F90 b/BRAMS/src/core/rams_master.F90 index 8eba33de1..1722160e0 100644 --- a/BRAMS/src/core/rams_master.F90 +++ b/BRAMS/src/core/rams_master.F90 @@ -38,6 +38,9 @@ subroutine rams_master(ipara, nslaves, master_num, name_name) use mem_radiate, only: ISWRTYP, ILWRTYP ! Intent(in) use mem_leaf, only : isfcl ! Intent(in) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -63,7 +66,6 @@ subroutine rams_master(ipara, nslaves, master_num, name_name) integer :: ierr #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !MLO] diff --git a/BRAMS/src/core/rnode.F90 b/BRAMS/src/core/rnode.F90 index 6604df513..c00c9c903 100644 --- a/BRAMS/src/core/rnode.F90 +++ b/BRAMS/src/core/rnode.F90 @@ -78,13 +78,16 @@ subroutine rams_node() use mem_leaf, only: isfcl ! intent(in) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif + implicit none ! Local Variables: #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: isendflg,isendlite,isendmean,isendboth,nt,npass,icm,ifm,nfeed real :: wstart,totcpu,t1,w1,t6,w6 @@ -385,13 +388,15 @@ subroutine init_params(init) use mem_oda use mem_radiate, only: ISWRTYP, ILWRTYP ! Intent(in) use mem_leaf , only: isfcl ! Intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer, intent(in) :: init #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif integer :: ierr @@ -438,6 +443,9 @@ subroutine init_fields(init) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims , only : ndim_types +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -473,7 +481,6 @@ subroutine init_fields(init) !----- Include modules. ----------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! diff --git a/BRAMS/src/ed2/edcp_driver.F90 b/BRAMS/src/ed2/edcp_driver.F90 index ffa40b50d..8c8c6dee8 100644 --- a/BRAMS/src/ed2/edcp_driver.F90 +++ b/BRAMS/src/ed2/edcp_driver.F90 @@ -11,6 +11,7 @@ subroutine ed_coup_driver() , edgrid_g ! ! subroutine use ed_init , only : read_obstime ! ! subroutine use ed_misc_coms , only : fast_diagnostics & ! intent(in) + , current_time & ! intent(in) , iyeara & ! intent(in) , imontha & ! intent(in) , idatea & ! intent(in) @@ -47,6 +48,9 @@ subroutine ed_coup_driver() use budget_utils , only : ed_init_budget ! ! sub-routine use ed_type_init , only : ed_init_viable ! ! sub-routine use soil_respiration , only : zero_litter_inputs ! ! sub-routine +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Local variables. ----------------------------------------------------------------! @@ -63,17 +67,14 @@ subroutine ed_coup_driver() integer :: jd2 integer :: ierr integer :: igr - integer :: ping + integer :: ping + logical :: new_day real :: wtime1 real :: wtime2 real :: wtime_start ! wall time real :: cputime1 !----- External function. --------------------------------------------------------------! real , external :: walltime ! wall time - !----- MPI header. ---------------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/BRAMS/src/ed2/edcp_init.F90 b/BRAMS/src/ed2/edcp_init.F90 index c5dc646ad..d87e7ad34 100644 --- a/BRAMS/src/ed2/edcp_init.F90 +++ b/BRAMS/src/ed2/edcp_init.F90 @@ -20,11 +20,11 @@ subroutine master_ed_init(iparallel) , allocate_edglobals & ! subroutine , allocate_edtype & ! subroutine , edgrid_g ! ! intent(inout) - implicit none - !------Included variables. -------------------------------------------------------------! + !------MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: iparallel !----- Local variables. ----------------------------------------------------------------! @@ -108,11 +108,11 @@ subroutine node_ed_init , allocate_edglobals & ! sub-routine , allocate_edtype & ! sub-routine , edgrid_g ! ! structure - implicit none - !------Included variables. -------------------------------------------------------------! + !------MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! integer :: ifm integer :: ierr @@ -181,12 +181,11 @@ subroutine copy_in_bramsmpi(master_num_b,mchnum_b,mynum_b,nmachs_b,machs_b,ipara use grid_coms , only : ngrids & ! intent(out) , nnxp & ! intent(out) , nnyp ! ! intent(out) - - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + + implicit none !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: master_num_b integer , intent(in) :: mchnum_b @@ -267,11 +266,11 @@ subroutine init_master_work(ipara) , allocate_edglobals & ! sub-routine , allocate_edtype ! ! sub-routine use mem_polygons , only : maxsite ! ! intent(in) - implicit none - !----- Included variables. -------------------------------------------------------------! + !----- MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: ipara !----- Local variables. ----------------------------------------------------------------! @@ -510,11 +509,10 @@ subroutine init_node_work() , allocate_edglobals & ! sub-routine , allocate_edtype ! ! sub-routine use mem_polygons , only : maxsite ! ! sub-routine - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! integer :: ifm integer :: nm diff --git a/BRAMS/src/ed2/edcp_load_namelist.f90 b/BRAMS/src/ed2/edcp_load_namelist.f90 index 1275b834a..e4d72e97c 100644 --- a/BRAMS/src/ed2/edcp_load_namelist.f90 +++ b/BRAMS/src/ed2/edcp_load_namelist.f90 @@ -109,12 +109,13 @@ subroutine read_ednl(iunit,filename) , sl_mindbh_harvest & ! intent(out) , sl_biomass_harvest & ! intent(out) , sl_skid_rel_area & ! intent(out) + , sl_skid_dbh_thresh & ! intent(out) , sl_skid_s_gtharv & ! intent(out) , sl_skid_s_ltharv & ! intent(out) , sl_felling_s_ltharv & ! intent(out) , cl_fseeds_harvest & ! intent(out) , cl_fstorage_harvest & ! intent(out) - , cl_fleaf_harvest ! ! intent(out) + , cl_fleaf_harvest & ! intent(out) , lu_database & ! intent(out) , plantation_file & ! intent(out) , lu_rescale_file & ! intent(out) @@ -305,13 +306,14 @@ subroutine read_ednl(iunit,filename) ,lwidth_grass,lwidth_bltree,lwidth_nltree,q10_c3,q10_c4,thetacrit & ,quantum_efficiency_t,n_plant_lim,n_decomp_lim,include_fire,sl_pft & ,sl_prob_harvest,sl_mindbh_harvest,sl_biomass_harvest & - ,sl_skid_rel_area,sl_skid_s_gtharv,sl_skid_s_ltharv & - ,sl_felling_s_ltharv,cl_fseeds_harvest,cl_fstorage_harvest & - ,cl_fleaf_harvest,icanturb,include_these_pft,pasture_stock & - ,agri_stock,plantation_stock,pft_1st_check,ifusion,maxpatch & - ,maxcohort,min_patch_area,treefall_disturbance_rate,time2canopy & - ,iprintpolys,npvars,printvars,pfmtstr,ipmin,ipmax,imetrad,iphenys1 & - ,iphenysf,iphenyf1,iphenyff,iedcnfgf,event_file,phenpath + ,sl_skid_rel_area,sl_skid_dbh_thresh,sl_skid_s_gtharv & + ,sl_skid_s_ltharv,sl_felling_s_ltharv,cl_fseeds_harvest & + ,cl_fstorage_harvest,cl_fleaf_harvest,icanturb,include_these_pft & + ,pasture_stock,agri_stock,plantation_stock,pft_1st_check,ifusion & + ,maxpatch,maxcohort,min_patch_area,treefall_disturbance_rate & + ,time2canopy,iprintpolys,npvars,printvars,pfmtstr,ipmin,ipmax & + ,imetrad,iphenys1,iphenysf,iphenyf1,iphenyff,iedcnfgf,event_file & + ,phenpath !----- Initialise some database variables with a non-sense path. -----------------------! islcolflg (:) = undef_integer diff --git a/BRAMS/src/ed2/edcp_mpiutils.F90 b/BRAMS/src/ed2/edcp_mpiutils.F90 index 2ee522ff8..22fa675af 100644 --- a/BRAMS/src/ed2/edcp_mpiutils.F90 +++ b/BRAMS/src/ed2/edcp_mpiutils.F90 @@ -184,6 +184,7 @@ subroutine masterput_ednl(mainnum) , sl_mindbh_harvest & ! intent(in) , sl_biomass_harvest & ! intent(in) , sl_skid_rel_area & ! intent(in) + , sl_skid_dbh_thresh & ! intent(in) , sl_skid_s_gtharv & ! intent(in) , sl_skid_s_ltharv & ! intent(in) , sl_felling_s_ltharv & ! intent(in) @@ -234,11 +235,10 @@ subroutine masterput_ednl(mainnum) , idetailed & ! intent(in) , patch_keep ! ! intent(in) use fusion_fission_coms , only : ifusion ! ! intent(in) - implicit none - !----- Standard common blocks. ---------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: mainnum !----- Local variables. ----------------------------------------------------------------! @@ -386,6 +386,7 @@ subroutine masterput_ednl(mainnum) call MPI_Bcast(sl_mindbh_harvest ,n_pft,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_biomass_harvest , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_rel_area , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) + call MPI_Bcast(sl_skid_dbh_thresh , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_gtharv , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_ltharv , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_felling_s_ltharv, 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) @@ -710,6 +711,7 @@ subroutine nodeget_ednl(master_num) , sl_mindbh_harvest & ! intent(out) , sl_biomass_harvest & ! intent(out) , sl_skid_rel_area & ! intent(out) + , sl_skid_dbh_thresh & ! intent(out) , sl_skid_s_gtharv & ! intent(out) , sl_skid_s_ltharv & ! intent(out) , sl_felling_s_ltharv & ! intent(out) @@ -760,11 +762,10 @@ subroutine nodeget_ednl(master_num) , idetailed & ! intent(out) , patch_keep ! ! intent(out) use fusion_fission_coms , only : ifusion ! ! intent(out) - implicit none - !----- Standard common blocks. ---------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: master_num !----- Local variables. ----------------------------------------------------------------! @@ -913,6 +914,7 @@ subroutine nodeget_ednl(master_num) call MPI_Bcast(sl_mindbh_harvest ,n_pft,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_biomass_harvest , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_rel_area , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) + call MPI_Bcast(sl_skid_dbh_thresh , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_gtharv , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_ltharv , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_felling_s_ltharv, 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) diff --git a/BRAMS/src/io/error_mess.F90 b/BRAMS/src/io/error_mess.F90 index 1e868e3b2..276496f8c 100644 --- a/BRAMS/src/io/error_mess.F90 +++ b/BRAMS/src/io/error_mess.F90 @@ -6,11 +6,11 @@ subroutine abort_run(reason,subr,file) ! being frozen. ! !------------------------------------------------------------------------------------------! use node_mod, only: nmachs,mynum - implicit none - character(len=*), intent(in) :: reason,subr,file #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none + character(len=*), intent(in) :: reason,subr,file write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' @@ -49,12 +49,12 @@ subroutine opspec_mess(reason,opssub) ! This is just a first warning to be given in the standard output. Since the namelist ! ! may have more than one error, I list all the problems, then the model will stop. ! !------------------------------------------------------------------------------------------! +#if defined(RAMS_MPI) + use mpi +#endif implicit none character(len=*), intent(in) :: reason,opssub -#if defined(RAMS_MPI) - include 'mpif.h' -#endif write (unit=*,fmt='(a)') ' ' write (unit=*,fmt='(a)') '----------------------------------------------------------------------------' write (unit=*,fmt='(3(a,1x))') '>>>> ',trim(opssub),' error! in your namelist!' diff --git a/BRAMS/src/lib/numutils.f90 b/BRAMS/src/lib/numutils.f90 index 3feb04109..aadaf4a6c 100644 --- a/BRAMS/src/lib/numutils.f90 +++ b/BRAMS/src/lib/numutils.f90 @@ -1811,7 +1811,7 @@ end function expected !==========================================================================================! !==========================================================================================! -! This function simply computes f(x) = exp (-x²). Just to make errorfun neater. ! +! This function simply computes f(x) = exp (-x^2). Just to make errorfun neater. ! !------------------------------------------------------------------------------------------! real function expmsq(x) implicit none @@ -2219,7 +2219,6 @@ end subroutine diagon - !==========================================================================================! !==========================================================================================! ! EIFUN8 -- This function computes the exponential integral function, defined by ! @@ -2228,35 +2227,49 @@ end subroutine diagon ! | exp(t) ! ! Ei(x) = | -------- dt ! ! _| t ! -! 0 ! +! -Inf ! ! ! -! This function is based on: ! +! This function checks for two approaches: series expansion, which typically works ! +! best when x is small, and the asymptotic expansion, which typically works best when x is ! +! large. The approach selects the smallest result (in absolute numbers) as the most ! +! accurate method. Both the series expansion and the asymptotic expansion are provided in ! +! AS72. This approach also checks for some other edge cases, and ignores the results when ! +! the value is very negative. ! ! ! -! Press, W. H., S. A. Teukolsky, W. T. Vetterling, B. P. Flannery: 1992. Numerical recipes ! -! in Fortran 77. Cambridge University Press, section 6.3 p. 215-219. ! +! Reference: ! +! ! +! Abramowitz, M., and I. A. Stegun, Eds., 1972: Handbook of mathematical functions with ! +! formulas, graphs, and mathematical tables. 10th ed., No. 55, Applied Mathematics ! +! Series, National Bureau of Standards, Washington, DC, USA (AS72). ! ! ! -! with the difference that we also solve for negative numbers. Zero cannot be solved, so ! -! if this happens, or if the sought number would lead to infinity, we stop the model. ! !------------------------------------------------------------------------------------------! real(kind=8) function eifun8(x) - use rconstants, only : euler_gam8 & ! intent(in) - , lnexp_min8 & ! intent(in) - , lnexp_max8 & ! intent(in) - , tiny_num8 ! ! intent(in) + use rconstants, only : euler_gam8 & ! intent(in) + , lnexp_min8 & ! intent(in) + , lnexp_max8 & ! intent(in) + , tiny_num8 & ! intent(in) + , almost_zero8 ! ! intent(in) implicit none !----- Arguments. ----------------------------------------------------------------------! real(kind=8), intent(in) :: x !----- Local variables. ----------------------------------------------------------------! - real(kind=8) :: sum - real(kind=8) :: term - real(kind=8) :: fact - real(kind=8) :: prev - real(kind=8) :: diter - integer :: iter + real(kind=8) :: usum + real(kind=8) :: uxk + real(kind=8) :: uxkm1 + real(kind=8) :: vsum + real(kind=8) :: vxkm1 + real(kind=8) :: vxk + real(kind=8) :: ei_series + real(kind=8) :: ei_asymptote + integer :: k !----- Local constants. ----------------------------------------------------------------! - real(kind=8), parameter :: powerlim = 1.5d+01 - real(kind=8), parameter :: converge = 1.0d-7 - integer , parameter :: maxiter = 100 + real(kind=8), parameter :: discard8 = 1.0d+36 + integer , parameter :: maxiter = 100 + !----- Polynomial coefficients. --------------------------------------------------------! + real(kind=8), dimension(4), parameter :: apoly = (/ 8.5733287401d+00, 1.8059015973d+01 & + , 8.6347608925d+00, 2.6777373430d-01 /) + real(kind=8), dimension(4), parameter :: bpoly = (/ 9.5733223454d+00, 2.5632956149d+01 & + , 2.1099653083d+01, 3.9584969228d+00 /) !---------------------------------------------------------------------------------------! @@ -2266,63 +2279,157 @@ real(kind=8) function eifun8(x) if (x == 0.d0) then !------------------------------------------------------------------------------------! ! Zero. This is a singularity and the user should never call it in this case. ! - ! That's sad, but we ought to quit this run and tell the user why the run crashed. ! - !------------------------------------------------------------------------------------! - call abort_run('Exponential integral cannot be solved for x = 0.' & - ,'eifun8','numutils.f90') - elseif (x >= lnexp_max8) then - !----- Huge value, crash because this is iminent over-flow. -------------------------! - write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x - write(unit=*,fmt='(a,1x,es12.5)') 'Maximum acceptable X =',lnexp_max8 - call abort_run('Exponential integral cannot be solved for x = 0.' & - ,'eifun8','numutils.f90') - elseif (abs(x) <= lnexp_min8) then - !----- Huge negative number, the result can be rounded to zero. ---------------------! + !------------------------------------------------------------------------------------! + stop 'Exponential integral cannot be solved for x = 0.' + !------------------------------------------------------------------------------------! + elseif (x <= lnexp_min8) then + !------------------------------------------------------------------------------------! + ! Huge negative value, the result can be set to zero. ! + !------------------------------------------------------------------------------------! eifun8 = 0.d0 - elseif (abs(x) <= tiny_num8) then - !----- The number is too close to zero, bypass iterative methods. -------------------! - eifun8 = euler_gam8 + log(abs(x)) - elseif (abs(x) <= powerlim) then - !------------------------------------------------------------------------------------! - ! Input x is small, so we use the power method. ! - !------------------------------------------------------------------------------------! - fact = 1.d0 - sum = 0.d0 - powerloop: do iter=1,maxiter - diter = dble(iter) - fact = fact * x / diter - term = fact / diter - sum = sum + term - !----- If the term is tiny, we have reached convergence, quit the loop. ----------! - if (abs(term) < converge * abs(sum)) exit powerloop - end do powerloop - eifun8 = euler_gam8 + log(abs(x)) + sum + !------------------------------------------------------------------------------------! + elseif (x <= -1.d0) then + !------------------------------------------------------------------------------------! + ! For negative values less than -1.0, we use the polynomial approximation ! + ! (Equation 5.1.56 of AS72), by taking that Ei(x) = - E1(-x). ! + !------------------------------------------------------------------------------------! + eifun8 = exp(x)/x & + * ( x * ( x * ( x * ( x - apoly(1) ) + apoly(2) ) - apoly(3) ) + apoly(4) ) & + / ( x * ( x * ( x * ( x - bpoly(1) ) + bpoly(2) ) - bpoly(3) ) + bpoly(4) ) + !------------------------------------------------------------------------------------! else !------------------------------------------------------------------------------------! - ! Input x is large, so we use the asymptotic approximation. ! - !------------------------------------------------------------------------------------! - sum = 0.d0 - term = 1.d0 - asymploop: do iter=1,maxiter - diter = dble(iter) - prev = term - term = term * diter / x - if (abs(term) < converge) then - !----- The term is tiny, we have reached convergence, quit the loop. ----------! - exit asymploop - elseif (abs(term) >= abs(prev)) then - !------------------------------------------------------------------------------! - ! Series is diverging, we are probably reaching round-off errors, we better ! - ! stop now. ! - !------------------------------------------------------------------------------! - sum = sum - prev - exit asymploop + ! Find both the series expansion and the asymptotic expansion, and pick the one ! + ! with the lowest absolute value. ! + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Series expansion: Equation 5.1.11 of AS72, by taking that Ei(x) = - E1(-x). ! + ! ! + ! Inf ! + ! Ei(x) = gamma + ln(x) + SUM u(x,k), ! + ! k=1 ! + ! ! + ! where u(x,k) = [ (-1)^k * (-x)^k / (k * k!) ] ! + ! ! + ! To efficiently compute the terms inside the summation, we use that: ! + ! ! + ! u(x,k) = x * (k -1) / k^2 * u(x,k-1), for k >= 2. ! + !------------------------------------------------------------------------------------! + uxk = x + usum = uxk + do_expansion: do k = 2, maxiter + !----- Update the current summation term. ----------------------------------------! + uxkm1 = uxk + uxk = x * dble( k - 1 ) / dble( k * k ) * uxkm1 + !----- Check for degenerate or very large estimate. ------------------------------! + if ( abs(uxk) > discard8 .or. abs(usum) > discard8) then + usum = sign(discard8,usum) + exit do_expansion + end if + !----- Check for convergence. ----------------------------------------------------! + if ( any(abs(uxk) <= [ almost_zero8 * abs(usum), tiny_num8] ) ) exit do_expansion + !----- Update summation. ---------------------------------------------------------! + usum = usum + uxk + !---------------------------------------------------------------------------------! + end do do_expansion + !----- Find the series solution. ----------------------------------------------------! + if ( abs(usum) == discard8) then + ei_series = sign(discard8,usum) + else + ei_series = euler_gam8 + log(abs(x)) + usum + end if + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Asymptote expansion: Equation 5.1.51 of AS72 by taking AS72's n=1 and ! + ! Ei(x) = -E1(-x)). ! + ! ! + ! Inf ! + ! Ei(x) = exp(x) / x * SUM v(x,k), ! + ! k=0 ! + ! ! + ! where v(x,k) = k! / x^k ! + ! ! + ! To efficiently compute the terms inside the summation, we use that: ! + ! ! + ! v(x,k) = k / x * v(x,n -1), for k >= 1. ! + !------------------------------------------------------------------------------------! + vxk = 1.d0 + vsum = vxk + do_asymptote: do k=1,maxiter + !----- Update the current summation term. ----------------------------------------! + vxkm1 = vxk + vxk = vxkm1 * dble(k) / x + !---------------------------------------------------------------------------------! + ! This method can become degenerate for low x or lead to exceedinly large ! + ! values, in these cases, halt evaluation. ! + !---------------------------------------------------------------------------------! + if ( abs(vxkm1) < abs(vxk) .or. abs(vsum) > discard8) then + vsum = sign(discard8,vsum) + exit do_asymptote + end if + !----- Check for convergence. ----------------------------------------------------! + if ( any(abs(vxk) <= [ almost_zero8 * abs(vsum), tiny_num8] ) ) exit do_asymptote + !----- Update summation. ---------------------------------------------------------! + vsum = vsum + vxk + !---------------------------------------------------------------------------------! + end do do_asymptote + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! If the solution became degenerate, skip value. ! + !------------------------------------------------------------------------------------! + if (abs(vsum) == discard8) then + ei_asymptote = sign(discard8,vsum) + else + ei_asymptote = exp(x) * vsum / x + end if + !------------------------------------------------------------------------------------! + + + + + + !------------------------------------------------------------------------------------! + ! Pick the lowest absolute value as long as the sign is reasonable. ! + !------------------------------------------------------------------------------------! + if (all(abs([ei_series,ei_asymptote]) == discard8)) then + !----- Huge value, crash because this is iminent over-flow. ----------------------! + write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x + stop 'Exponential integral cannot be solved for large absolute x.' + !---------------------------------------------------------------------------------! + elseif (x < 0.d0) then + !---------------------------------------------------------------------------------! + ! Exponential integral is negative when x is negative, however, for some ! + ! values between -15 < x < -14, the solutions become numerically unstable. Check ! + ! for the most reasonable estimate. ! + !---------------------------------------------------------------------------------! + if (ei_series > 0.d0 .and. ei_asymptote > 0.d0) then + write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x + write(unit=*,fmt='(a,1x,es12.5)') 'Series expansion estimate = ',ei_series + write(unit=*,fmt='(a,1x,es12.5)') 'Asymptote expansion estimate = ',ei_asymptote + stop 'Exponential integral failed solving, another method might be needed.' + elseif (ei_series > 0.d0) then + eifun8 = ei_asymptote + elseif (ei_asymptote > 0.d0) then + eifun8 = ei_series + elseif (abs(ei_series) < abs(ei_asymptote)) then + eifun8 = ei_series else - sum = sum + term + eifun8 = ei_asymptote end if - end do asymploop - eifun8 = exp(x) * (1.d0 + sum) / x + !---------------------------------------------------------------------------------! + elseif (abs(ei_series) < abs(ei_asymptote)) then + eifun8 = ei_series + else + eifun8 = ei_asymptote + end if + !------------------------------------------------------------------------------------! end if + !---------------------------------------------------------------------------------------! return end function eifun8 @@ -2335,8 +2442,17 @@ end function eifun8 !==========================================================================================! !==========================================================================================! -! Heapsort is a robust and efficient sorting algorithm. For more details, check ! -! The Numerical Recipes Book (chapter 8). ! +! Heapsort is a robust and efficient sorting algorithm introduced by W64. The algorithm ! +! implemented here is built from the Wikipedia heapsort pseudocode, which is in turn based ! +! on K97. ! +! ! +! Williams, JWJ (1964). Algorithm 232 - Heapsort, Commun. ACM 7, 347-348. ! +! doi:10.1145/512274.512284 (W64). ! +! ! +! Knuth, D (1997). The Art of Computer Programming - volume 3: sort and searching. ! +! section 5.2.3. Sorting by selection (p. 144-155). ISBN 978-0-201-89685-5 (K97). ! +! ! +! Wikipedia link: https://en.wikipedia.org/wiki/Heapsort ! !------------------------------------------------------------------------------------------! subroutine heapsort(nx,xi,increase,xo) implicit none @@ -2346,11 +2462,12 @@ subroutine heapsort(nx,xi,increase,xo) logical , intent(in) :: increase ! Sort from small to large? real , dimension(nx), intent(out) :: xo ! Output vector !----- Local variables. ----------------------------------------------------------------! - integer :: i ! Counter - integer :: ir ! Index of selected data - integer :: j ! Index of selected data - integer :: l ! Index of selected data - real :: aux ! Placeholder + integer :: i ! Counter (inner loop) + integer :: ilwr ! Lower index (inner loop) + integer :: iupr ! Upper index (inner loop) + integer :: olwr ! Lower index (outer loop) + integer :: oupr ! Upper index (outer loop) + real :: aux ! Placeholder for element swapping !---------------------------------------------------------------------------------------! @@ -2369,13 +2486,13 @@ subroutine heapsort(nx,xi,increase,xo) !---------------------------------------------------------------------------------------! - ! The index l will be decremented from its initial value down to 1 during the ! - ! "hiring" (heap creation) phase. Once it reaches 1, the index ir will be decremented ! - ! from its initial value down to 1 during the "retirement-and-promotion" (heap ! - ! selection) phase. ! + ! Set initial guess of lower index ilwr to half the size of the vector and iupr to ! + ! the size of the vector. During the heap setting stage, ilwr will be reduced until it ! + ! becomes 0, and then we start decreasing iupr until it becomes 1, at which point the ! + ! vector becomes sorted. ! !---------------------------------------------------------------------------------------! - l = nx/2 + 1 - ir = nx + olwr = nx/2 + 1 + oupr = nx+1 !---------------------------------------------------------------------------------------! @@ -2384,79 +2501,74 @@ subroutine heapsort(nx,xi,increase,xo) !---------------------------------------------------------------------------------------! outer_loop: do !------------------------------------------------------------------------------------! - ! Check whether we are in the hiring phase or in the retirement-and-promotion ! + ! Exit outer loop if we reach the upper bound has already reached 1. ! + !------------------------------------------------------------------------------------! + if (oupr == 2) exit outer_loop + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Check whether we are in the heap setting phase or in the retirement-and-promotion ! ! phase. ! !------------------------------------------------------------------------------------! - if (l > 1) then - !---------------------------------------------------------------------------------! - ! Still in hiring phase. ! - !---------------------------------------------------------------------------------! - l = l - 1 - aux = xo(l) + if (olwr > 1) then + !----- Heap construction. --------------------------------------------------------! + olwr = olwr - 1 !---------------------------------------------------------------------------------! else !---------------------------------------------------------------------------------! - ! In the retirement-and-promotion phase. ! + ! Heap extraction. ! !---------------------------------------------------------------------------------! - !----- Clear a space at end of array. --------------------------------------------! - aux = xo(ir) - !----- Retire the top of the heap into it. ---------------------------------------! - xo(ir) = xo(1) - !----- Decrease the size of the corporation. -------------------------------------! - ir = ir -1 - !----- Check how we are doing with promotions. -----------------------------------! - if (ir == 1) then - !----- Done with the last promotion. The least competent worker of all! ------! - xo(1) = aux - !------------------------------------------------------------------------------! - - !------------------------------------------------------------------------------! - ! Time to leave the loop (and the sub-routine). ! - !------------------------------------------------------------------------------! - exit outer_loop - !------------------------------------------------------------------------------! - end if + !----- Shift upper side down one step. -------------------------------------------! + oupr = oupr -1 + !----- Swap indices. -------------------------------------------------------------! + aux = xo(oupr) + xo(oupr) = xo(1) + xo(1) = aux !---------------------------------------------------------------------------------! end if !------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! - ! Whether in hiring phase or promotion phase, we here set up to sift down element ! - ! aux to its proper level. ! + ! Sift down step. ! !------------------------------------------------------------------------------------! - i = l - j = l+1 + i = olwr inner_loop: do - if (j > ir) exit inner_loop + !----- Find the lower and right elements. ----------------------------------------! + ilwr = 2 * i + iupr = ilwr + 1 + !---------------------------------------------------------------------------------! - !----- Compare to the better underling. ------------------------------------------! - if (j < ir) then - if(xo(j) < xo(j+1)) j = j + 1 + !----- Make sure we do not exceed the heap size. ---------------------------------! + if (iupr > oupr) exit inner_loop + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Test whether there is an upper element that is larger, and swap the order. ! + ! Make sure that the elements are bounded before testing vector elements, to ! + ! avoid segmentation violation. ! + !---------------------------------------------------------------------------------! + if (iupr < oupr) then + if (xo(ilwr) < xo(ilwr+1)) ilwr = ilwr + 1 end if !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Check whether to demote aux or not. ! + ! Test whether or not to swap elements. ! !---------------------------------------------------------------------------------! - if (aux < xo(j)) then - !----- Demote aux. ------------------------------------------------------------! - xo(i) = xo(j) - i = j - j = j + j - !------------------------------------------------------------------------------! + if (xo(i) < xo(ilwr)) then + aux = xo(i) + xo(i) = xo(ilwr) + xo(ilwr) = aux + i = ilwr else - !----- This is aux's level. Set j to terminate the sift-down. ----------------! - j = ir + 1 - !------------------------------------------------------------------------------! + exit inner_loop end if !---------------------------------------------------------------------------------! end do inner_loop !------------------------------------------------------------------------------------! - - !----- Put aux into its slot. -------------------------------------------------------! - xo(i) = aux - !------------------------------------------------------------------------------------! end do outer_loop !---------------------------------------------------------------------------------------! @@ -2597,11 +2709,17 @@ end function fquant_mask !==========================================================================================! !==========================================================================================! ! Sub-routine that solves the quadratic equation ( a * x**2 + b * x + c = 0). ! -! This is an extension of the Numeric Recipes in Fortran 90 to account for the trivial ! -! cases and for checking when the discriminant is negative. ! +! We test whether or not this is a trivial case that does not require solving the full ! +! equation. For the full equation, we use the approach by H02 to avoid floating point ! +! issues when solving roots. We further check whether or not the discriminant is negative. ! +! ! ! The subroutine also requires a "undef" flag to be passed, which will flag cases ! ! in which one or both solutions are not valid. This is an argument so the solver can be ! ! used when either the largest or the smallest root is sought. ! +! ! +! Higham, N. J., 2002: Accuracy and Stability of Numerical Algorithms. 2nd ed., Society ! +! for Industrial and Applied Mathematics, Philadelphia, PA, United States, ! +! doi:10.1137/1.9780898718027 (H02). ! !------------------------------------------------------------------------------------------! subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) use rconstants, only : tiny_num @@ -2615,7 +2733,6 @@ subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) real(kind=4), intent(out) :: root2 !----- Internal variables. -------------------------------------------------------------! real(kind=4) :: discr - real(kind=4) :: qfact logical :: a_offzero logical :: b_offzero logical :: c_offzero @@ -2650,13 +2767,13 @@ subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Find the q factor as in the numerical recipes, which allows for a more ! - ! robust solution. This is safe whenever b or c are non-zero, as q cannot be ! - ! zero in these cases. + ! Follow H02's approach to find the largest root (absolute value) from the ! + ! traditional quadratic equation, then derive the second root from the first one. ! + ! This is safe whenever b or c are non-zero. ! + !---------------------------------------------------------------------------------! + root1 = - (bquad + sign(sqrt(discr),bquad)) / ( 2. * aquad ) + root2 = cquad / ( aquad * root1 ) !---------------------------------------------------------------------------------! - qfact = - 0.5 * (bquad + sign(sqrt(discr),bquad)) - root1 = qfact / aquad - root2 = cquad / qfact else !----- Negative discriminant, return invalid roots. ------------------------------! root1 = undef @@ -2708,11 +2825,17 @@ end subroutine solve_quadratic !==========================================================================================! !==========================================================================================! ! Sub-routine that solves the quadratic equation ( a * x**2 + b * x + c = 0). ! -! This is an extension of the Numeric Recipes in Fortran 90 to account for the trivial ! -! cases and for checking when the discriminant is negative. ! +! We test whether or not this is a trivial case that does not require solving the full ! +! equation. For the full equation, we use the approach by H02 to avoid floating point ! +! issues when solving roots. We further check whether or not the discriminant is negative. ! +! ! ! The subroutine also requires a "undef" flag to be passed, which will flag cases ! ! in which one or both solutions are not valid. This is an argument so the solver can be ! ! used when either the largest or the smallest root is sought. ! +! ! +! Higham, N. J., 2002: Accuracy and Stability of Numerical Algorithms. 2nd ed., Society ! +! for Industrial and Applied Mathematics, Philadelphia, PA, United States, ! +! doi:10.1137/1.9780898718027 (H02). ! !------------------------------------------------------------------------------------------! subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) use rconstants, only : tiny_num8 @@ -2726,7 +2849,6 @@ subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) real(kind=8), intent(out) :: root2 !----- Internal variables. -------------------------------------------------------------! real(kind=8) :: discr - real(kind=8) :: qfact logical :: a_offzero logical :: b_offzero logical :: c_offzero @@ -2761,13 +2883,13 @@ subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Find the q factor as in the numerical recipes, which allows for a more ! - ! robust solution. This is safe whenever b or c are non-zero, as q cannot be ! - ! zero in these cases. + ! Follow H02's approach to find the largest root (absolute value) from the ! + ! traditional quadratic equation, then derive the second root from the first one. ! + ! This is safe whenever b or c are non-zero. ! + !---------------------------------------------------------------------------------! + root1 = - (bquad + sign(sqrt(discr),bquad)) / ( 2.d0 * aquad ) + root2 = cquad / ( aquad * root1 ) !---------------------------------------------------------------------------------! - qfact = - 5.d-1 * (bquad + sign(sqrt(discr),bquad)) - root1 = qfact / aquad - root2 = cquad / qfact else !----- Negative discriminant, return invalid roots. ------------------------------! root1 = undef @@ -2812,6 +2934,11 @@ end subroutine solve_quadratic8 !==========================================================================================! !==========================================================================================! + return +end subroutine solve_quadratic8 +!==========================================================================================! +!==========================================================================================! + diff --git a/BRAMS/src/lib/therm_lib.f90 b/BRAMS/src/lib/therm_lib.f90 index ebe933f6a..9c7624f01 100644 --- a/BRAMS/src/lib/therm_lib.f90 +++ b/BRAMS/src/lib/therm_lib.f90 @@ -110,6 +110,17 @@ module therm_lib !=======================================================================================! + + + !=======================================================================================! + !=======================================================================================! + ! Weighting factor for atmospheric ThetaV (as opposed to canopy air space ThetaV). ! + !---------------------------------------------------------------------------------------! + real(kind=4), parameter :: fthva_rp = 0.5 + !=======================================================================================! + !=======================================================================================! + + contains @@ -2501,14 +2512,19 @@ real(kind=4) function reducedpress(pres,thetaref,shvref,zref,thetacan,shvcan,zca real(kind=4), intent(in) :: zcan ! Height at canopy level [ m] !------Local variables. -------------------------------------------------------------! real(kind=4) :: pinc ! Pressure increment [ Pa^R/cp] + real(kind=4) :: thvref ! Reference virtual pot. temperature [ K] + real(kind=4) :: thvcan ! CAS virtual pot. temperature [ K] real(kind=4) :: thvbar ! Average virtual pot. temperature [ K] !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! ! First we compute the average virtual potential temperature between the canopy ! - ! top and the reference level. ! + ! top and the reference level. Because of the equation below, we average the ! + ! inverse of the potential temperature. ! !------------------------------------------------------------------------------------! - thvbar = 0.5 * (thetaref * (1. + epim1 * shvref) + thetacan * (1. + epim1 * shvcan)) + thvref = thetaref * (1.0 + epim1 * shvref) + thvcan = thetacan * (1.0 + epim1 * shvcan) + thvbar = thvref * thvcan / ( ( 1.0 - fthva_rp ) * thvref + fthva_rp * thvcan ) !------------------------------------------------------------------------------------! diff --git a/BRAMS/src/lib/therm_lib8.f90 b/BRAMS/src/lib/therm_lib8.f90 index 76ed12f4d..eb03e5461 100644 --- a/BRAMS/src/lib/therm_lib8.f90 +++ b/BRAMS/src/lib/therm_lib8.f90 @@ -15,8 +15,9 @@ module therm_lib8 , maxfpo4 => maxfpo & ! intent(in) , maxit4 => maxit & ! intent(in) , maxlev4 => maxlev & ! intent(in) - , newthermo4 => newthermo ! ! intent(in) - + , newthermo4 => newthermo & ! intent(in) + , fthva_rp4 => fthva_rp ! ! intent(in) + !---------------------------------------------------------------------------------------! ! Relative tolerance for iterative methods. The smaller the value, the more ! ! accurate the result, but it will slow down the run. Notice that we are using the ! @@ -116,6 +117,17 @@ module therm_lib8 !=======================================================================================! + + + !=======================================================================================! + !=======================================================================================! + ! Weighting factor for atmospheric ThetaV (as opposed to canopy air space ThetaV). ! + !---------------------------------------------------------------------------------------! + real(kind=4), parameter :: fthva_rp8 = dble(fthva_rp4) + !=======================================================================================! + !=======================================================================================! + + contains @@ -2505,15 +2517,21 @@ real(kind=8) function reducedpress8(pres,thetaref,shvref,zref,thetacan,shvcan,zc real(kind=8), intent(in) :: zcan ! Height at canopy level [ m] !------Local variables. -------------------------------------------------------------! real(kind=8) :: pinc ! Pressure increment [ Pa^R/cp] + real(kind=8) :: thvref ! Reference virtual pot. temperature [ K] + real(kind=8) :: thvcan ! CAS virtual pot. temperature [ K] real(kind=8) :: thvbar ! Average virtual pot. temperature [ K] !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! First we compute the average virtual potential temperature between the canopy ! - ! top and the reference level. ! + ! top and the reference level. Because of the equation below, we average the ! + ! inverse of the potential temperature. ! !------------------------------------------------------------------------------------! - thvbar = 5.d-1 * ( thetaref * (1.d0 + epim18 * shvref) & - + thetacan * (1.d0 + epim18 * shvcan) ) + thvref = thetaref * (1.d0 + epim18 * shvref) + thvcan = thetacan * (1.d0 + epim18 * shvcan) + thvbar = thvref * thvcan / ( ( 1.d0 - fthva_rp8 ) * thvref + fthva_rp8 * thvcan ) !------------------------------------------------------------------------------------! diff --git a/BRAMS/src/mpi/mpass_advec.F90 b/BRAMS/src/mpi/mpass_advec.F90 index 540945520..111187a2f 100644 --- a/BRAMS/src/mpi/mpass_advec.F90 +++ b/BRAMS/src/mpi/mpass_advec.F90 @@ -36,6 +36,9 @@ subroutine node_sendadv(iaflag) use mem_cuparm , only : nclouds ! ! intent(in) use grid_dims , only : maxgrds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -59,7 +62,6 @@ subroutine node_sendadv(iaflag) !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -220,12 +222,14 @@ subroutine node_getadv(iaflag) use mem_scratch use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: iaflag diff --git a/BRAMS/src/mpi/mpass_cyclic.F90 b/BRAMS/src/mpi/mpass_cyclic.F90 index a9e5cea5e..71a9628b7 100644 --- a/BRAMS/src/mpi/mpass_cyclic.F90 +++ b/BRAMS/src/mpi/mpass_cyclic.F90 @@ -49,10 +49,10 @@ subroutine node_cycinit(nzp,nxp,nyp,npvar,nmachs,ibnd,jbnd,mynum) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims, only : ndim_types - implicit none #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none integer :: nmachs,mynum,icypts,nzp,nxp,nyp,icycpts,iadd,mdn,msn,ndn,nsn & ,ibnd,jbnd,nm,maxijrecv_cyc integer, dimension(ndim_types) :: npvar @@ -282,12 +282,14 @@ subroutine node_sendcyclic(isflag) use grid_dims use mem_cuparm, only: nclouds use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Included variables --------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: isflag @@ -479,13 +481,13 @@ subroutine node_getcyclic(isflag) use grid_dims use mem_cuparm, only : nclouds use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Included variables --------------------------------------------------------------! include 'interface.h' -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: isflag !----- Local variables -----------------------------------------------------------------! diff --git a/BRAMS/src/mpi/mpass_dtl.F90 b/BRAMS/src/mpi/mpass_dtl.F90 index d4236305b..c929f11f1 100644 --- a/BRAMS/src/mpi/mpass_dtl.F90 +++ b/BRAMS/src/mpi/mpass_dtl.F90 @@ -23,12 +23,12 @@ subroutine master_getcflcpu() use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none include 'interface.h' -#if defined(RAMS_MPI) -include 'mpif.h' -#endif integer :: ngr,nm,k real, save, allocatable :: buff1(:),buff2(:) integer, save :: ncall=0 @@ -69,12 +69,14 @@ subroutine node_putcflcpu(totcpu,totwall) use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif real :: totcpu,totwall integer :: ierr @@ -94,12 +96,12 @@ subroutine master_putdtsched(isendflg,isendlite,isendmean & ,isendboth,ntsend) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none -#if defined(RAMS_MPI) -include 'mpif.h' -#endif integer :: ierr integer :: isendflg,isendlite,isendmean,isendboth,ntsend @@ -135,13 +137,15 @@ subroutine node_getdtsched(isendflg,isendlite,isendmean,isendboth) use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer :: isendflg,isendlite,isendmean,isendboth,ntsend #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr diff --git a/BRAMS/src/mpi/mpass_feed.F90 b/BRAMS/src/mpi/mpass_feed.F90 index 8b318aa7a..a9462ebee 100644 --- a/BRAMS/src/mpi/mpass_feed.F90 +++ b/BRAMS/src/mpi/mpass_feed.F90 @@ -56,13 +56,15 @@ subroutine node_sendfeed(ngr) use grid_dims , only: & maxgrds ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer :: ngr #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr,ipos @@ -255,12 +257,14 @@ subroutine node_getfeed(icm,ifm) nypmax, & ! intent(in) nzpmax, & ! intent(in) maxgrds ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr,ipos diff --git a/BRAMS/src/mpi/mpass_full.F90 b/BRAMS/src/mpi/mpass_full.F90 index 166db5138..54a01a54f 100644 --- a/BRAMS/src/mpi/mpass_full.F90 +++ b/BRAMS/src/mpi/mpass_full.F90 @@ -32,12 +32,14 @@ subroutine master_sendinit() use io_params use rpara use mem_aerad, only: nwave +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants. ----------------------------------------------------------------! @@ -194,12 +196,14 @@ subroutine node_getinit() use mem_grid use io_params use mem_aerad, only: nwave +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants. ----------------------------------------------------------------! @@ -407,11 +411,13 @@ subroutine node_sendall() use grid_dims use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants -----------------------------------------------------------------! @@ -534,11 +540,13 @@ subroutine master_getall() use mem_cuparm , only: nclouds ! ! intent(in) use mem_aerad , only: nwave ! ! intent(in) use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants -----------------------------------------------------------------! diff --git a/BRAMS/src/mpi/mpass_init.F90 b/BRAMS/src/mpi/mpass_init.F90 index bb809fe5e..76e524e79 100644 --- a/BRAMS/src/mpi/mpass_init.F90 +++ b/BRAMS/src/mpi/mpass_init.F90 @@ -21,12 +21,14 @@ subroutine masterput_processid(nproc,taskids,master_num) use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, dimension(*), intent(in) :: taskids @@ -165,11 +167,13 @@ subroutine masterput_nl(master_num) , ribmax & ! intent(in) , leaf_maxwhc & ! intent(in) , min_patch_area ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -498,12 +502,14 @@ subroutine masterput_gridinit(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if (RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -550,11 +556,13 @@ subroutine masterput_grid_dimens(master_num) use mem_grid use cyclic_mod use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Arguments -----------------------------------------------------------------------! @@ -640,12 +648,14 @@ subroutine masterput_gridset(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -702,13 +712,15 @@ subroutine masterput_misc(master_num) use rpara use mem_cuparm use ref_sounding +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: master_num @@ -777,12 +789,14 @@ subroutine masterput_cofnest(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -841,12 +855,14 @@ subroutine masterput_micphys(master_num) use micphys use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -900,12 +916,14 @@ subroutine nodeget_processid(init) use grid_dims use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: init @@ -1033,11 +1051,13 @@ subroutine nodeget_nl , ribmax & ! intent(out) , leaf_maxwhc & ! intent(out) , min_patch_area ! ! intent(out) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm,ierr @@ -1363,12 +1383,14 @@ subroutine nodeget_gridinit use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm,ierr @@ -1413,12 +1435,14 @@ subroutine nodeget_grid_dimens() use mem_grid use node_mod use cyclic_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm @@ -1525,12 +1549,14 @@ subroutine nodeget_gridset use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1586,12 +1612,14 @@ subroutine nodeget_misc use mem_cuparm use ref_sounding use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1659,12 +1687,14 @@ subroutine nodeget_cofnest use mem_grid use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1722,12 +1752,14 @@ subroutine nodeget_micphys use micphys use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr diff --git a/BRAMS/src/mpi/mpass_lbc.F90 b/BRAMS/src/mpi/mpass_lbc.F90 index 177b1f712..d39cc79d0 100644 --- a/BRAMS/src/mpi/mpass_lbc.F90 +++ b/BRAMS/src/mpi/mpass_lbc.F90 @@ -36,6 +36,9 @@ subroutine node_sendlbc() use mem_cuparm , only : nclouds ! ! intent(in) use grid_dims , only : maxgrds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Local variables. ----------------------------------------------------------------! @@ -56,7 +59,6 @@ subroutine node_sendlbc() !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -168,12 +170,14 @@ subroutine node_getlbc() use mem_scratch use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables. ----------------------------------------------------------------! #if defined(RAMS_MPI) diff --git a/BRAMS/src/mpi/mpass_nest.F90 b/BRAMS/src/mpi/mpass_nest.F90 index f4f323dda..6951b21bf 100644 --- a/BRAMS/src/mpi/mpass_nest.F90 +++ b/BRAMS/src/mpi/mpass_nest.F90 @@ -27,10 +27,12 @@ subroutine node_sendnbc(ifm,icm) use var_tables use mem_basic use grid_dims, only: maxgrds +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr,ipos integer :: nm,i1,i2,j1,j2,k1,k2,ng,itype,mtp,iptr,nv @@ -249,11 +251,13 @@ subroutine node_getnbc(ifm,icm) use mem_scratch use mem_basic use mem_nestb +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr,ipos #if defined(RAMS_MPI) diff --git a/BRAMS/src/mpi/mpass_oda.F90 b/BRAMS/src/mpi/mpass_oda.F90 index f03f1c892..f204789ba 100644 --- a/BRAMS/src/mpi/mpass_oda.F90 +++ b/BRAMS/src/mpi/mpass_oda.F90 @@ -24,6 +24,9 @@ subroutine masterput_oda(master_num) use grid_dims use mem_oda use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -33,7 +36,6 @@ subroutine masterput_oda(master_num) ! +------------------------------------------------------------------ #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ns integer :: master_num @@ -137,11 +139,13 @@ subroutine nodeget_oda() use node_mod use mem_oda +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr integer :: ns diff --git a/BRAMS/src/mpi/mpass_st.F90 b/BRAMS/src/mpi/mpass_st.F90 index 92a54c5cc..129061c4b 100644 --- a/BRAMS/src/mpi/mpass_st.F90 +++ b/BRAMS/src/mpi/mpass_st.F90 @@ -35,13 +35,15 @@ subroutine node_sendst(isflag) use mem_scratch use mem_basic +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: isflag @@ -215,12 +217,14 @@ subroutine node_getst(isflag) use node_mod use mem_scratch use mem_basic +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: isflag diff --git a/BRAMS/src/mpi/paral.F90 b/BRAMS/src/mpi/paral.F90 index 3a3e5b351..88c91be62 100644 --- a/BRAMS/src/mpi/paral.F90 +++ b/BRAMS/src/mpi/paral.F90 @@ -25,13 +25,15 @@ subroutine node_sendanl(vtype) use var_tables use mem_scratch use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! character(len=*) , intent(in) :: vtype @@ -120,12 +122,14 @@ subroutine master_getanl(vtype) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! character(len=*) , intent(in) :: vtype diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..26a45ee07 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# ED2 Community Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +ed2_core@googlegroups.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index cfce22303..000000000 --- a/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -# ---------------------------------------------------------------------- -# BUILD MODEL BINARY -# ---------------------------------------------------------------------- -FROM debian:buster-slim AS builder - -# Some variables that can be used to set control the docker build -ARG MODEL_VERSION="2.2.0" -ARG BINARY_VERSION="2.2" - -# specify fortran compiler -ENV FC_TYPE=GNU - -# install dependencies -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - curl \ - gfortran \ - git \ - libhdf5-dev \ - libopenmpi-dev \ - && rm -rf /var/lib/apt/lists/* - -# download, unzip and build ed2 -COPY . /src/ -WORKDIR /src/ED/build -RUN ./install.sh -g -p docker && mv ed_*-opt ed - -######################################################################## - -# ---------------------------------------------------------------------- -# BUILD PECAN FOR MODEL -# ---------------------------------------------------------------------- -FROM debian:buster-slim - -# ---------------------------------------------------------------------- -# INSTALL MODEL SPECIFIC PIECES -# ---------------------------------------------------------------------- - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - libhdf5-103 \ - libopenmpi3 \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /data - -# Some variables that can be used to set control the docker build -ARG MODEL_VERSION="2.2.0" -ENV MODEL_VERSION="${MODEL_VERSION}" - -# COPY model binary -COPY --from=builder /src/ED/build/ed /usr/local/bin/ed - - diff --git a/Dockerfile.gnu b/Dockerfile.gnu new file mode 100644 index 000000000..fac933349 --- /dev/null +++ b/Dockerfile.gnu @@ -0,0 +1,50 @@ +# ---------------------------------------------------------------------- +# Build ED2 model +# ---------------------------------------------------------------------- +FROM ubuntu:22.04 AS build + +# Some variables that can be used to set control the docker build +ARG ED2_KIND=E + +# environment variables controlling the build +ENV FC_TYPE=GNU \ + ED2_KIND=${ED2_KIND} \ + TZ=America/Chicago \ + DEBIAN_FRONTEND=noninteractive + +# install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + gfortran \ + libhdf5-openmpi-dev \ + && rm -rf /var/lib/apt/lists/* + +# copy the source only, this prevents a full rebuild in case of changes to Dockerfile or non source files +COPY BRAMS /ED2/BRAMS +COPY ED /ED2/ED +COPY EDR /ED2/EDR +COPY RAPP /ED2/RAPP +COPY Ramspost /ED2/Ramspost + +WORKDIR /ED2/ED/build +RUN ./install.sh -k ${ED2_KIND} -g -p docker.gnu +RUN if [ -e ed_*-opt ]; then mv ed_*-opt ed2; else mv ed_*-dbg ed2; fi + +######################################################################## + +# ---------------------------------------------------------------------- +# Minimal image with just ED2 model +# ---------------------------------------------------------------------- +FROM ubuntu:22.04 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + libhdf5-openmpi-103 \ + libgomp1 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /data +COPY --from=build /ED2/ED/build/ed2 /usr/bin + +CMD ["/usr/bin/ed2"] diff --git a/Dockerfile.intel b/Dockerfile.intel new file mode 100644 index 000000000..5b42d6dbf --- /dev/null +++ b/Dockerfile.intel @@ -0,0 +1,46 @@ +# ---------------------------------------------------------------------- +# Build ED2 model +# ---------------------------------------------------------------------- +FROM intel/oneapi-hpckit:2023.1.0-devel-ubuntu22.04 AS build + +# Some variables that can be used to set control the docker build +ARG ED2_KIND=E + +# environment variables controlling the build +ENV ED2_KIND=${ED2_KIND} + +# compile HDF5 with intel +RUN wget -q https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.9/src/CMake-hdf5-1.10.9.tar.gz && \ + tar xf CMake-hdf5-1.10.9.tar.gz && \ + cd CMake-hdf5-1.10.9 && \ + sed -e 's/^#*\(.*BUILD_FORTRAN:BOOL=ON.*\)/\1/' \ + -e 's/^#*\(.*BUILD_FORTRAN:BOOL=OFF.*\)/#\1/' \ + -e 's/^#*\(.*intel.cmake.*\)/\1/' \ + -i HDF5options.cmake && \ + ctest -S HDF5config.cmake,BUILD_GENERATOR=Unix,INSTALLDIR=/opt/hdf5 -C Release -V -O hdf5.log && \ + ./HDF5-1.10.9-Linux.sh --skip-license --exclude-subdir --prefix=/opt && \ + cd && \ + rm -rf CMake-hdf5-1.10.9.tar.gz CMake-hdf5-1.10.9 + +# copy the source only, this prevents a full rebuild in case of changes to Dockerfile or non source files +COPY BRAMS /ED2/BRAMS +COPY ED /ED2/ED +COPY EDR /ED2/EDR +COPY RAPP /ED2/RAPP +COPY Ramspost /ED2/Ramspost + +WORKDIR /ED2/ED/build +RUN ./install.sh -k ${ED2_KIND} -g -p docker.intel +RUN if [ -e ed_*-opt ]; then mv ed_*-opt ed2; else mv ed_*-dbg ed2; fi + +######################################################################## + +# ---------------------------------------------------------------------- +# Minimal image with just ED2 model +# ---------------------------------------------------------------------- +FROM ubuntu:22.04 + +WORKDIR /data +COPY --from=build /ED2/ED/build/ed2 /usr/bin + +CMD ["/usr/bin/ed2"] diff --git a/ED/Template/Template/ED2IN b/ED/Template/Template/ED2IN index 63504ddd5..6e81666a7 100644 --- a/ED/Template/Template/ED2IN +++ b/ED/Template/Template/ED2IN @@ -414,7 +414,7 @@ $ED_NL ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -422,6 +422,10 @@ $ED_NL ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! NL%IED_INIT_MODE = myinitmode !---------------------------------------------------------------------------------------! @@ -715,14 +719,17 @@ $ED_NL !---------------------------------------------------------------------------------------! ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. Choose ! ! the option according to the site characteristics. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, use ! + ! flat bedrock, otherwise assume free drainage. This option is more ! + ! relevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! ! bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction is ! ! controlled by variable SLDRAIN. In the future options 0, 1, and 2 may ! ! be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! ! always at saturation. ! !---------------------------------------------------------------------------------------! NL%ISOILBC = mysoilbc @@ -882,13 +889,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = myallom !---------------------------------------------------------------------------------------! @@ -959,10 +972,25 @@ $ED_NL ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = myiphen !---------------------------------------------------------------------------------------! @@ -1550,6 +1578,7 @@ $ED_NL ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! @@ -1569,6 +1598,7 @@ $ED_NL NL%SL_MINDBH_HARVEST = mydbhharv NL%SL_BIOMASS_HARVEST = mybioharv NL%SL_SKID_REL_AREA = myskidarea + NL%SL_SKID_DBH_THRESH = myskiddbhthresh NL%SL_SKID_S_GTHARV = myskidlarge NL%SL_SKID_S_LTHARV = myskidsmall NL%SL_FELLING_S_LTHARV = myfellingsmall diff --git a/ED/Template/Template/emptyepost.sh b/ED/Template/Template/emptyepost.sh deleted file mode 100755 index 44654274e..000000000 --- a/ED/Template/Template/emptyepost.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -rm -fvr epost -mkdir epost diff --git a/ED/Template/Template/gen_obstimes.r b/ED/Template/Template/gen_obstimes.r new file mode 100644 index 000000000..40df2d2b1 --- /dev/null +++ b/ED/Template/Template/gen_obstimes.r @@ -0,0 +1,194 @@ +#----- This should be called before anything else, don't define stuff before this line. ---# +rm(list=ls()) +graphics.off() +#------------------------------------------------------------------------------------------# + + +#----- The user-defined variable section. -------------------------------------------------# +main = "pathhere" +histomain = "pathhere" +srcdir = "thisrscpath" +polyg = "thispoly" +queue = "thisqueue" +yeara = thisyeara +montha = thismontha +datea = thisdatea +timea = thistimea +yearz = thisyearz +monthz = thismonthz +datez = thisdatez +timez = thistimez +lon = thislon +lat = thislat +#------------------------------------------------------------------------------------------# + + +#----- List periods. ----------------------------------------------------------------------# +n = 0 +period = list() +n = n + 1 +period[[n]] = list( todaya = "01/01/2003" + , todayz = "12/31/2010" + , times = c("01:30:00","13:30:00") + )#end list +n = n + 1 +period[[n]] = list( todaya = "01/01/2011" + , todayz = "12/31/2018" + , times = c("06:00:00","18:00:00") + )#end list +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +# No need to change anything beyond this point unless you are developing the script. # +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric years. # +#------------------------------------------------------------------------------------------# +numyears <<- function(when){ + yrs = years(when) + lyrs = levels(yrs) + yrout = as.numeric(lyrs[match(yrs,lyrs)]) + return(yrout) +}#end function +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric months. # +#------------------------------------------------------------------------------------------# +nummonths <<- function(when){ + mos = months(when) + lmos = levels(mos) + moout = match(mos,lmos) + return(moout) +}#end function +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric days. # +#------------------------------------------------------------------------------------------# +numdays <<- function(when){ + dys = days(when) + ldys = levels(dys) + dyout = match(dys,ldys) + return(dyout) +} #end function +#==========================================================================================# +#==========================================================================================# + + +#----- Output path. -----------------------------------------------------------------------# +output = file.path(main,polyg) +#------------------------------------------------------------------------------------------# + + +#----- Load some useful scripts and packages. ---------------------------------------------# +isok = require(chron) +isok = require(data.table) +#------------------------------------------------------------------------------------------# + + + +#----- Find the standard output files. ----------------------------------------------------# +whena = chron(paste(montha,datea,yeara,sep="/")) +whenz = chron(paste(monthz,datez,yearz,sep="/")) +#------------------------------------------------------------------------------------------# + + +#----- Find the time offset, and round it to the nearest half-hour. -----------------------# +offutc = round( 2. * lon / 15.) / 2. +#------------------------------------------------------------------------------------------# + + +#----- Find number of periods. ------------------------------------------------------------# +nperiod = length(period) +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Expand the times for all days. # +#------------------------------------------------------------------------------------------# +when = NULL +for (p in sequence(nperiod)){ + #----- Current period. -----------------------------------------------------------------# + todaya = chron(period[[p]]$todaya) + todayz = chron(period[[p]]$todayz) + times = period[[p]]$times + #---------------------------------------------------------------------------------------# + + + #------ List of dates and times. -------------------------------------------------------# + today = chron(seq(from=as.numeric(todaya),to=as.numeric(todayz),by=1)) + ntoday = length(today) + ntimes = length(times) + #---------------------------------------------------------------------------------------# + + + #------- Append times from this period. ------------------------------------------------# + when.now = chron(rep(today,each=ntimes),rep(times,times=ntoday)) + offutc / 24 + when.now = when.now[(when.now >= whena) & (when.now <= whenz)] + #---------------------------------------------------------------------------------------# + + #------ Append time. -------------------------------------------------------------------# + when = chron(c(when,when.now)) + #---------------------------------------------------------------------------------------# +}#end for (p in sequence(nperiod)) +#------------------------------------------------------------------------------------------# + + + + +#----- Write the data sets. ---------------------------------------------------------------# +datum = data.table( Year = sprintf("%4.4i",numyears (when)) + , Month = sprintf("%2.2i",nummonths(when)) + , Date = sprintf("%2.2i",numdays (when)) + , Hour = sprintf("%2.2i",hours (when)) + , Minute = sprintf("%2.2i",minutes (when)) + , Second = sprintf("%2.2i",seconds (when)) + , stringsAsFactors = FALSE + )#end data.table +#------------------------------------------------------------------------------------------# + + + + +#----- Write observation times. -----------------------------------------------------------# +obstab = file.path(main,polyg,paste0(polyg,"_obstimes.txt")) +dummy = write.table( x = format(datum) + , file = obstab + , append = FALSE + , quote = FALSE + , row.names = FALSE + , col.names = TRUE + )#end write.table +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/mled b/ED/Template/Template/mled deleted file mode 100755 index b80a599a1..000000000 Binary files a/ED/Template/Template/mled and /dev/null differ diff --git a/ED/Template/Template/monthly_ascii.r b/ED/Template/Template/monthly_ascii.r new file mode 100644 index 000000000..2756cca1a --- /dev/null +++ b/ED/Template/Template/monthly_ascii.r @@ -0,0 +1,456 @@ + +#----- Paths. -----------------------------------------------------------------------------# +here = "thispath" # Current directory. +there = "thatpath" # Directory where analyses/history are +srcdir = "thisrscpath" # Source directory. +outroot = "thisoutroot" # Directory for figures +#------------------------------------------------------------------------------------------# + + +#----- Time options. ----------------------------------------------------------------------# +monthbeg = thismontha # First month to use +yearbeg = thisyeara # First year to consider +yearend = thisyearz # Maximum year to consider +reload.data = TRUE # Should I reload partially loaded data? +sasmonth.short = c(2,5,8,11) # Months for SAS plots (short runs) +sasmonth.long = 5 # Months for SAS plots (long runs) +nyears.long = 15 # Runs longer than this are considered long runs. +#------------------------------------------------------------------------------------------# + + + +#----- Name of the simulations. -----------------------------------------------------------# +myplaces = c("thispoly") +#------------------------------------------------------------------------------------------# + + + +#----- Plot options. ----------------------------------------------------------------------# +outform = thisoutform # Formats for output file. Supported formats are: + # - "X11" - for printing on screen + # - "quartz" - for printing on Mac OS screen + # - "eps" - for postscript printing + # - "png" - for PNG printing + # - "tif" - for TIFF printing + # - "pdf" - for PDF printing +depth = 96 # PNG resolution, in pixels per inch +paper = "letter" # Paper size, to define the plot shape +ptsz = 16 # Font size. +lwidth = 2.5 # Line width +plotgrid = TRUE # Should I plot the grid in the background? +sasfixlimits = FALSE # Use a fixed scale for size and age-structure + # plots? (FALSE will set a suitable scale for + # each plot) +fcgrid = TRUE # Include a grid on the filled contour plots? +ncolshov = 200 # Target number of colours for Hovmoller diagrams. +hovgrid = TRUE # Include a grid on the Hovmoller plots? +legwhere = "topleft" # Where should I place the legend? +inset = 0.01 # Inset between legend and edge of plot region. +scalleg = 0.40 # Expand y limits by this relative amount to fit + # the legend +cex.main = 0.8 # Scale coefficient for the title +theta = 315. # Azimuth for perspective projection +phi = 30. # Vertical angle for perspective projection +ltheta = -210. # Azimuth angle for light +shade = 0.125 # Shade intensity +expz = 0.5 # Expansion factor for Z axis +cexmin = 0.5 # Minimum "head" size of the lollipop +cexmax = 3.0 # Maximum "head" size of the lollipop +ylnudge = 0.05 # Nudging factor for ylimit +ptype = "l" # Type of plot +ptyped = "p" # Type of plot +ptypeb = "o" # Type of plot +drought.mark = mydroughtmark # Put a background to highlight droughts? +drought.yeara = mydroughtyeara # First year that has drought +drought.yearz = mydroughtyearz # Last year that has drought +months.drought = mymonthsdrought # Months with drought +ibackground = mybackground # Background settings (check load_everything.r) +#------------------------------------------------------------------------------------------# + + + +#------ Miscellaneous settings. -----------------------------------------------------------# +slz.min = -5.0 # The deepest depth that trees access water. +idbh.type = myidbhtype # Type of DBH class + # 1 -- Every 10 cm until 100cm; > 100cm + # 2 -- 0-10; 10-20; 20-35; 35-50; 50-70; > 70 (cm) + # 3 -- 0-10; 10-35; 35-55; > 55 (cm) +klight = myklight # Weighting factor for maximum carbon balance +corr.growth.storage = mycorrection # Correction factor to be applied to growth and + # storage respiration +iallom = myallom # Allometry to use +isoil.hydro = myslhydro # Soil hydrology method +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# NO NEED TO CHANGE ANYTHING BEYOND THIS POINT UNLESS YOU ARE DEVELOPING THE CODE... # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + + +#----- Load some packages and scripts. ----------------------------------------------------# +source(file.path(srcdir,"load.everything.r")) +#------------------------------------------------------------------------------------------# + + +#----- Set how many formats we must output. -----------------------------------------------# +outform = tolower(outform) +nout = length (outform) +#------------------------------------------------------------------------------------------# + + +#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# +options(locatorBell=FALSE) +#------------------------------------------------------------------------------------------# + + +#----- Load observations. -----------------------------------------------------------------# +obsrfile = file.path(srcdir,"LBA_MIP.v9.RData") +load(file=obsrfile) + +#----- Define plot window size ------------------------------------------------------------# +size = plotsize(proje=FALSE,paper=paper) +#------------------------------------------------------------------------------------------# + + + +#---- Create the main output directory in case there is none. -----------------------------# +if (! file.exists(outroot)) dir.create(outroot) +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Big place loop starts here... # +#------------------------------------------------------------------------------------------# +for (place in myplaces){ + + #----- Retrieve default information about this place and set up some variables. --------# + thispoi = locations(where=place,here=there,yearbeg=yearbeg,yearend=yearend + ,monthbeg=monthbeg) + inpref = thispoi$pathin + outmain = file.path(outroot,place) + outcsv = file.path(outmain,"csv_month") + lieu = thispoi$lieu + iata = thispoi$iata + suffix = thispoi$iata + yeara = thispoi$yeara + yearz = thispoi$yearz + meszz = thispoi$monz + + #---------------------------------------------------------------------------------------# + # Make sure we only deal with full years. # + #---------------------------------------------------------------------------------------# + if (monthbeg > 1) yeara = yeara + 1 + if (meszz < 12) yearz = yearz - 1 + monthbeg = 1 + meszz = 12 + if (yeara > yearz){ + cat(" - Yeara: ",yeara,"\n") + cat(" - Yearz: ",yearz,"\n") + cat(" - Prefix: ",inpref,"\n") + cat(" - Invalid years, will not process data...","\n") + q("no") + }#end if + #---------------------------------------------------------------------------------------# + + + #----- Create the directories in case they don't exist. --------------------------------# + if (! file.exists(outmain)) dir.create(outmain) + if (! file.exists(outcsv )) dir.create(outcsv ) + #---------------------------------------------------------------------------------------# + + + + #----- Decide how frequently the cohort-level variables should be saved. ---------------# + if ((yearend - yearbeg + 1) <= nyears.long){ + sasmonth = sasmonth.short + plot.ycomp = TRUE + }else{ + sasmonth = sasmonth.long + plot.ycomp = FALSE + }#end if + #---------------------------------------------------------------------------------------# + + + + + #----- Print a banner to entretain the user. -------------------------------------------# + cat(" + Post-processing output from ",lieu,"...","\n") + + + #---------------------------------------------------------------------------------------# + # Flush all variables that will hold the data. # + #---------------------------------------------------------------------------------------# + ntimes = (yearz-yeara-1)*12+meszz+(12-monthbeg+1) + nyears = yearz-yeara+1 + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Make the RData file name, then we check whether we must read the files again # + # or use the stored RData. Notice that the path is the same for plot_ycomp.r and # + # plot_monthly, so you don't need to read in the data twice. # + #---------------------------------------------------------------------------------------# + path.data = file.path(here,place,"rdata_month") + if (! file.exists(path.data)) dir.create(path.data) + ed22.rdata = file.path(path.data,paste(place,"RData",sep=".")) + ed22.status = file.path(path.data,paste("status_",place,".txt",sep="")) + if (reload.data && file.exists(ed22.rdata)){ + #----- Load the modelled dataset. ---------------------------------------------------# + cat(" - Loading previous session...","\n") + load(ed22.rdata) + tresume = datum$ntimes + 1 + if (ntimes > datum$ntimes){ + datum = update.monthly( new.ntimes = ntimes + , old.datum = datum + , montha = monthbeg + , yeara = yeara + , inpref = inpref + , slz.min = slz.min + )#end update.monthly + }#end if + #------------------------------------------------------------------------------------# + }else{ + cat(" - Starting new session...","\n") + tresume = 1 + datum = create.monthly( ntimes = ntimes + , montha = monthbeg + , yeara = yeara + , inpref = inpref + , slz.min = slz.min + )#end create.monthly + }#end if + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check whether we have anything to update. # + #---------------------------------------------------------------------------------------# + complete = tresume > ntimes + #---------------------------------------------------------------------------------------# + + + + #----- Copy some dimensions to scalars. ------------------------------------------------# + nzg = datum$nzg + nzs = datum$nzs + ndcycle = datum$ndcycle + isoilflg = datum$isoilflg + slz = datum$slz + slxsand = datum$slxsand + slxclay = datum$slxclay + ntext = datum$ntext + soil.prop = datum$soil.prop + dslz = datum$dslz + soil.depth = datum$soil.depth + soil.dry = datum$soil.dry + soil.poro = datum$soil.poro + ka = datum$ka + kz = datum$kz + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Loop over all times in case there is anything new to be read. # + #---------------------------------------------------------------------------------------# + if (! complete){ + + #------------------------------------------------------------------------------------# + # This function will read the files. # + #------------------------------------------------------------------------------------# + datum = read.q.files(datum=datum,ntimes=ntimes,tresume=tresume,sasmonth=sasmonth) + #------------------------------------------------------------------------------------# + + + #------ Save the data to the R object. ----------------------------------------------# + cat(" + Saving data to ",basename(ed22.rdata),"...","\n") + save(datum,file=ed22.rdata) + #------------------------------------------------------------------------------------# + }#end if (! complete) + #---------------------------------------------------------------------------------------# + + + #----- Update status file with latest data converted into R. ---------------------------# + latest = paste(datum$year[ntimes],datum$month[ntimes],sep=" ") + dummy = write(x=latest,file=ed22.status,append=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #----- Make some shorter versions of some variables. -----------------------------------# + mfac = datum$month + yfac = datum$year + emean = datum$emean + emsqu = datum$emsqu + qmean = datum$qmean + qmsqu = datum$qmsqu + szpft = datum$szpft + lu = datum$lu + patch = datum$patch + cohort = datum$cohort + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Remove all elements of the DBH/PFT class that do not have a single valid cohort # + # at any given time. # + #---------------------------------------------------------------------------------------# + empty = is.na(szpft$nplant) | szpft$nplant == 0 + for (vname in names(szpft)) szpft[[vname]][empty] = NA + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Convert mortality and recruitment so it is scaled between 0 and 100%. # + #---------------------------------------------------------------------------------------# + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) + #---------------------------------------------------------------------------------------# + + + #----- Find which PFTs, land uses and transitions we need to consider ------------------# + pftave = apply( X = szpft$agb[,ndbh+1,] + , MARGIN = 2 + , FUN = mean + , na.rm = TRUE + )#end apply + luave = apply( X = lu$agb + , MARGIN = 2 + , FUN = mean + , na.rm = TRUE + )#end apply + distave = apply(X=lu$dist,MARGIN=c(2,3),FUN=mean) + selpft = is.finite(pftave ) & pftave > 0. + sellu = is.finite(luave ) & luave > 0. + seldist = is.finite(distave) & distave > 0. + n.selpft = sum(selpft ) + n.sellu = sum(sellu ) + n.seldist = sum(seldist) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Create data frame with yearly averages. # + #---------------------------------------------------------------------------------------# + cat0(" + Create data frame with monthly averages.") + mglob = data.table( year = datum$year + , month = datum$month + , numdays = daymax(datum$month,datum$year) + , atm.prss = emean$atm.prss * 100. + , atm.temp = emean$atm.temp + t00 + , atm.shv = emean$atm.shv * 0.001 + , atm.vels = emean$atm.vels + , precip = emean$rain/daymax(datum$month,datum$year)/day.sec + , rshort.in = emean$rshort + , rlong.in = emean$rlong + , agb = emean$agb + , lai = emean$lai + , wai = emean$wai + , rshort.out = emean$rshort + , rlong.out = emean$rlong + , cas.height = emean$can.depth + , cas.prss = emean$can.prss * 100. + , cas.temp = emean$can.temp + t00 + , cas.shv = emean$can.shv * 0.001 + , gnd.temp = emean$gnd.temp + t00 + , leaf.temp = emean$leaf.temp + t00 + , wood.temp = emean$wood.temp + t00 + , soil.temp = emean$soil.temp.top + t00 + , soil.water = emean$soil.water.top + , soil.rmoist = emean$soil.wetness.top + , sfcw.temp = emean$sfcw.temp + t00 + , sfcw.fliq = emean$sfcw.fliq + , sfcw.mass = emean$sfcw.mass + , sfcw.depth = emean$sfcw.depth + , sfcw.cover = emean$sfcw.cover + , runoff = emean$runoff / day.sec + , leaf.water = emean$leaf.water + , wood.water = 0. * emean$leaf.water + , hflxca = emean$hflxca + , wflxca = emean$wflxca / day.sec + , hflxgc = emean$hflxgc + , wflxgc = emean$wflxgc / day.sec + , hflxlc = emean$hflxlc + , wflxlc = emean$wflxlc / day.sec + , hflxwc = emean$hflxwc + , wflxwc = emean$wflxwc / day.sec + , transp = emean$transp / day.sec + )#end data.frame + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # Write csv files with the output. # + #---------------------------------------------------------------------------------------# + cat0(" + Write output files.") + csv.emean = file.path(outcsv,paste0(place,"_emean.csv" )) + dummy = write.table(x=mglob ,file=csv.emean,quote=FALSE,sep=",",row.names=FALSE) + #---------------------------------------------------------------------------------------# + +}#end for (place in myplaces) +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/mrun.sh b/ED/Template/Template/mrun.sh deleted file mode 100755 index 29a0e5435..000000000 --- a/ED/Template/Template/mrun.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -#-----Change your settings here ----------------------------------------------------------# -here=`pwd` # Folder to start the run -queue='thisqueue' # Queue name -#------------------------------------------------------------------------------------------# - -if [ 'z'${1} = 'z' ] -then - echo 'Which m-file do you want to run (needs to be in current dir include .m)?' - read filenameIN -else - filenameIN=${1} -fi - -if [ 'z'${2} = 'z' ] -then - echo 'What run name do you want to use?' - read jobname -else - jobname=${2} -fi - - -joberrname=${jobname}'_err.out' - -module load math/matlab-R2009a 1>/dev/null 2>/dev/null - -#----- Submitting the job, we use a shell script so we can track the run on the fly -------# -bsub -q ${queue} -o ${joberrname} -J ${jobname} "matlab -nodesktop -nojvm -nosplash < ${filenameIN} > ${jobname}.out" - -echo " - Running ${filenameIN} under job name ${jobname}" diff --git a/ED/Template/Template/plot_eval_ed.r b/ED/Template/Template/plot_eval_ed.r index a70cf1d6c..0ac9e88e7 100644 --- a/ED/Template/Template/plot_eval_ed.r +++ b/ED/Template/Template/plot_eval_ed.r @@ -1080,7 +1080,7 @@ for (place in myplaces){ #----- Find and plot the distribution function for this hour. -----------# sd.obser = sd(this.obser[sel],na.rm=TRUE) - if (sd.obser %>% 1.0e-6){ + if (sd.obser %gt% 1.0e-6){ #----- Find the residuals. -------------------------------------------# this.resid = this.obser - this.model comp$residuals[sel] = this.resid[sel] diff --git a/ED/Template/Template/plot_monthly.r b/ED/Template/Template/plot_monthly.r index 41127c33a..81efb3fce 100644 --- a/ED/Template/Template/plot_monthly.r +++ b/ED/Template/Template/plot_monthly.r @@ -591,21 +591,57 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# - # Replace the mortality and recruitment exponential rates by the "interests" rates. # + # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# @@ -732,10 +768,10 @@ for (place in myplaces){ , na.rm = TRUE )#end apply distave = apply(X=lu$dist,MARGIN=c(2,3),FUN=mean) - selpftl = pftave %>% 0. - selpfts = pftave %>% 0. & (! (pft$key %in% "ALL") ) - sellu = luave %>% 0. - seldist = distave %>% 0. + selpftl = pftave %gt% 0. + selpfts = pftave %gt% 0. & (! (pft$key %in% "ALL") ) + sellu = luave %gt% 0. + seldist = distave %gt% 0. n.selpftl = sum(selpftl) n.selpfts = sum(selpfts) n.sellu = sum(sellu ) @@ -798,7 +834,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]][,ndbh+1,] if (plog){ #----- Eliminate non-positive values in case it is a log plot. -------------# - badlog = (! (thisvar %>% 0) ) & (! stackit) + badlog = (! (thisvar %gt% 0) ) & (! stackit) thisvar[badlog] = NA_real_ }#end if }else{ @@ -817,6 +853,7 @@ for (place in myplaces){ bottom = rep(0.,times=ntimes) }#end if + thisvar = ifelse(test=is.finite(thisvar),yes=thisvar,no=0.) thisvar = cbind(bottom,thisvar[,sequence(npft),drop=FALSE]) thisvar = t(apply(X=thisvar,MARGIN=1,FUN=cumsum)) }#end if (stackit) @@ -992,7 +1029,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]] if (plog){ xylog = "y" - badlog = ( ! (thisvar %>% 0) ) & (! stackit) + badlog = ( ! (thisvar %gt% 0) ) & (! stackit) thisvar[badlog] = NA_real_ }else{ xylog = "" @@ -1061,6 +1098,7 @@ for (place in myplaces){ bottom = rep(0.,times=ntimes) }#end if thisdbh = thisvar[,,p] + thisdbh = ifelse(test=is.finite(thisdbh),yes=thisdbh,no=0.) thisdbh = cbind(bottom,thisdbh[,sequence(ndbh),drop=FALSE]) thisdbh = t(apply(X=thisdbh,MARGIN=1,FUN=cumsum)) }else{ @@ -1912,7 +1950,7 @@ for (place in myplaces){ thisvar = lu[[vnam]] if (plog){ xylog = "y" - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }else{ xylog = "" @@ -2183,7 +2221,8 @@ for (place in myplaces){ legpos = themenow$legpos plotit = themenow$emean ylimit.fix = themenow$emean.lim - + thstack = themenow$stack + if (plotit){ #---------------------------------------------------------------------------------# @@ -2191,7 +2230,9 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# outdir = file.path(outpref,"theme_emean") if (! file.exists(outdir)) dir.create(outdir) - cat0(" + ",group," time series for several variables.") + cat0(" ~ ",group," time series for several variables.") + #---------------------------------------------------------------------------------# + #----- Define the number of layers. ----------------------------------------------# @@ -2199,6 +2240,43 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + ndat = length(emean[[vnames[1]]]) + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=0,nrow=ndat,ncol=nlayers+1) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,l] = ytheme[,l-1] + emean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=NA_real_,nrow=ndat,ncol=nlayers ) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,l] = emean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------# # Find the limit, make some room for the legend, and in case the field is a # @@ -2206,9 +2284,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# xlimit = pretty.xylim(u=as.numeric(datum$tomonth),fracexp=0.0,is.log=FALSE) if (any(! is.finite(ylimit.fix))){ - ylimit = NULL - for (l in 1:nlayers) ylimit = c(ylimit,emean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=plog) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=plog) }else{ ylimit = ylimit.fix }#end if @@ -2264,15 +2340,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , ncol = min(3,pretty.box(nlayers)$ncol) - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }else{ + #----- Line legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2298,12 +2392,33 @@ for (place in myplaces){ if (plotgrid){ abline(v=whenplot8$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ------------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = emean[[vnames[l]]] - points(x=datum$tomonth,y=thisvar,col=lcolours[l],lwd=llwd[l],type=ltype - ,pch=16,cex=0.8) - }#end for + #----- Plot data. -------------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ------------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(datum$tomonth,rev(datum$tomonth)) + , y = c(ytheme[,l] ,rev(ytheme [,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }else{ + #----- Plot lines. ---------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = datum$tomonth + , y = ytheme [,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2340,6 +2455,7 @@ for (place in myplaces){ legpos = themenow$legpos plotit = themenow$mmean ylimit.fix = themenow$mmean.lim + thstack = themenow$stack if (plotit){ @@ -2348,7 +2464,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# outdir = file.path(outpref,"theme_mmean") if (! file.exists(outdir)) dir.create(outdir) - cat0(" + ",group," time series for several variables.") + cat0(" ~ ",group," time series for several variables.") #----- Define the number of layers. ----------------------------------------------# @@ -2356,6 +2472,43 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + ndat = length(mmean[[vnames[1]]]) + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=0,nrow=ndat,ncol=nlayers+1) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,l] = ytheme[,l-1] + mmean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=NA_real_,nrow=ndat,ncol=nlayers ) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,l] = mmean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------# # Find the limit, make some room for the legend, and in case the field is a # @@ -2363,9 +2516,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# xlimit = pretty.xylim(u=montmont,fracexp=0.0,is.log=plog) if (any (! is.finite(ylimit.fix))){ - ylimit = NULL - for (l in 1:nlayers) ylimit = c(ylimit,mmean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=plog) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=plog) }else{ ylimit = ylimit.fix }#end if @@ -2421,17 +2572,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , pch = 16 - , ncol = min(3,pretty.box(nlayers)$ncol) - , cex = 0.9*cex.ptsz - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }else{ + #----- Line legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2457,12 +2624,33 @@ for (place in myplaces){ if (plotgrid){ abline(v=mplot$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ------------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = mmean[[vnames[l]]] - points(x=montmont,y=thisvar,col=lcolours[l],lwd=llwd[l],type=ltype - ,pch=16,cex=0.8) - }#end for + #----- Plot data. -------------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ------------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(montmont ,rev(montmont)) + , y = c(ytheme[,l],rev(ytheme [,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }else{ + #----- Plot lines. ---------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = montmont + , y = ytheme [,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2498,6 +2686,7 @@ for (place in myplaces){ unit = themenow$unit legpos = themenow$legpos plotit = themenow$qmean + thstack = themenow$stack if (plog){ xylog = "y" }else{ @@ -2514,18 +2703,66 @@ for (place in myplaces){ if (! file.exists(outdir)) dir.create(outdir) outtheme = file.path(outdir,prefix) if (! file.exists(outtheme)) dir.create(outtheme) - cat0(" + ",group," diurnal cycle for several variables.") + cat0(" ~ ",group," diurnal cycle for several variables.") #----- Define the number of layers. ----------------------------------------------# nlayers = length(vnames) - xlimit = range(thisday) - ylimit = NULL - for (l in sequence(nlayers)) ylimit = c(ylimit,umean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=FALSE) #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = array(data=0,dim=c(dim(umean[[vnames[1]]]),nlayers+1)) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,,l] = ytheme[,,l-1] + umean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = array(data=0,dim=c(dim(umean[[vnames[1]]]),nlayers)) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,,l] = umean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + + + #----- Append the first hour of the day at the end. ------------------------------# + ytheme = abind(ytheme,ytheme[,1,,drop=FALSE],along=2) + #---------------------------------------------------------------------------------# + + + + #------ Find limits. -------------------------------------------------------------# + xlimit = range(thisday) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=FALSE) + #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# # Loop over all months. # #---------------------------------------------------------------------------------# @@ -2574,15 +2811,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , ncol = min(3,pretty.box(nlayers)$ncol) - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. -----------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #------------------------------------------------------------------------# + }else{ + #----- Line legend. -----------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #------------------------------------------------------------------------# + }#end if (thstack) #---------------------------------------------------------------------------# @@ -2608,16 +2863,37 @@ for (place in myplaces){ if (plotgrid){ abline(v=uplot$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ---------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = umean[[vnames[l]]] - thisvar = cbind(thisvar[,ndcycle],thisvar) - points(x=thisday,y=thisvar[pmon,],col=lcolours[l] - ,lwd=llwd[l],type=ltype,pch=16) - }#end for + #----- Plot data. ----------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ---------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(thisday ,rev(thisday )) + , y = c(ytheme[pmon,,l],rev(ytheme[pmon,,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------# + }else{ + #----- Plot lines. ------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = thisday + , y = ytheme [pmon,,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------# + }#end if (thstack) #---------------------------------------------------------------------------# + #----- Close the device. ---------------------------------------------------# dummy = close.plot(outform=outform[o]) #---------------------------------------------------------------------------# diff --git a/ED/Template/Template/plot_yearly.r b/ED/Template/Template/plot_yearly.r index 5b588afe9..ae1122ee8 100644 --- a/ED/Template/Template/plot_yearly.r +++ b/ED/Template/Template/plot_yearly.r @@ -428,18 +428,53 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# @@ -544,7 +579,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]][,ndbh+1,] if (plog){ #----- Eliminate non-positive values in case it is a log plot. -------------# - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }#end if }else{ @@ -683,7 +718,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]] if (plog){ xylog = "y" - badlog = thisvar %<=% 0 + badlog = thisvar %le% 0 thisvar[badlog] = NA }else{ xylog = "" @@ -1055,7 +1090,7 @@ for (place in myplaces){ thisvar = lu[[vnam]] if (plog){ xylog = "y" - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }else{ xylog = "" @@ -1949,7 +1984,7 @@ for (place in myplaces){ #------------------------------------------------------------------------------# # Discard cohorts that are near-recruit size. # #------------------------------------------------------------------------------# - keepww = popww %>% 0. + keepww = popww %gt% 0. ageww = ageww[keepww] dbhww = dbhww[keepww] pftww = pftww[keepww] diff --git a/ED/Template/Template/purge.sh b/ED/Template/Template/purge.sh deleted file mode 100755 index e8e920edd..000000000 --- a/ED/Template/Template/purge.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -rm -fvr analy -rm -fvr histo -rm -fvr output -rm -fvr rdata_* -mkdir analy -mkdir histo -mkdir output -rm -fv core.* fort.* *_out.out *_lsf.out *_out.err -rm -fv budget_* thermo_state_* photo_state_* diff --git a/ED/Template/Template/srun.sh b/ED/Template/Template/srun.sh deleted file mode 100755 index b65e514bb..000000000 --- a/ED/Template/Template/srun.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -#--------------------------------- Change settings here -----------------------------------# -here="pathhere/thispoly" # Folder to start the run -queue="thisqueue" # Queue name -joblog="${here}/serial_lsf.out" # Name of the job output -jobname="thisdesc-thispoly" # Job name -callserial="${here}/callserial.sh" # Name of executable -initrc="myinitrc" # Script to load before doing anything -thisnum=myorder # No longer used -sbatch=$(which sbatch) # SLURM command to submit job. -memory=thismemory # Requested memory (per CPU) -runtime=thistime # Requested time -#------------------------------------------------------------------------------------------# - - -#----- Source script. ---------------------------------------------------------------------# -. ${initrc} -#------------------------------------------------------------------------------------------# - - -#----- Erase old logfiles and joblogs -----------------------------------------------------# -if [ -s ${joblog} ] -then - rm -fv ${joblog} -fi -#------------------------------------------------------------------------------------------# - - - -#----- Submit the job, we use a shell script so we can track the run on the fly -----------# -${sbatch} -p ${queue} --mem-per-cpu=${memory} -t ${runtime} -o ${joblog} -J ${jobname} \ - -n 1 --wrap="${callserial} zzzzzzzz" -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/whichrun.r b/ED/Template/Template/whichrun.r index b89fe317a..1677dc3d8 100644 --- a/ED/Template/Template/whichrun.r +++ b/ED/Template/Template/whichrun.r @@ -53,6 +53,7 @@ endrun = file.path(main,polyg,"serial_lsf.out" ) hasrun = file.path(main,polyg,"serial_out.out" ) haserr = file.path(main,polyg,"serial_out.err" ) hascrashed = file.path(main,polyg,"crashed_out.out") +hashydfail = file.path(main,polyg,"hydfail_out.out") hassigsegv = file.path(main,polyg,"sigsegv_out.out") hasbad.met = file.path(main,polyg,"bad_met_out.out") hasmetmiss = file.path(main,polyg,"metmiss_out.out") @@ -85,13 +86,15 @@ if (file.exists(hasrun) && ! sigsegv){ metmiss = ( length(grep("Cannot open met driver input file",simout)) > 0 | length(grep("Specify ED_MET_DRIVER_DB properly",simout)) > 0 ) crashed = length(grep("IFLAG1 problem." ,simout)) > 0 + hydfail = length(grep("Plant Hydrodynamics is off-track." ,simout)) > 0 bad.met = length(grep("Meteorological forcing has issues" ,simout)) > 0 stopped = length(grep("FATAL ERROR" ,simout)) > 0 finished = length(grep("ED-2\\.2 execution ends" ,simout)) > 0 - running = ! (metmiss || crashed || stopped || finished) + running = ! (metmiss || crashed || hydfail || stopped || finished) }else if (file.exists(hasrun) && sigsegv){ metmiss = FALSE crashed = FALSE + hydfail = FALSE bad.met = FALSE stopped = FALSE finished = FALSE @@ -100,6 +103,7 @@ if (file.exists(hasrun) && ! sigsegv){ metmiss = file.exists(hasmetmiss) bad.met = file.exists(hasbad.met) crashed = file.exists(hascrashed) + hydfail = file.exists(hashydfail) stopped = file.exists(hasstopped) sigsegv = file.exists(hassigsegv) finished = FALSE @@ -153,7 +157,7 @@ if (nhisto > 0){ dummy = file.remove(tryhisto) if (finished){ finished = FALSE - running = ! (metmiss || crashed || stopped || finished) + running = ! (metmiss || crashed || hydfail || stopped || finished) }#end if }else{ hasoutput = TRUE @@ -351,6 +355,8 @@ if (running && hasoutput){ status = paste(polyg,yyyy,mm,dd,hhhh,"SIGSEGV",agb,bsa,lai,scb,npa,sep=" ") }else if(crashed){ status = paste(polyg,yyyy,mm,dd,hhhh,"CRASHED",agb,bsa,lai,scb,npa,sep=" ") +}else if(hydfail){ + status = paste(polyg,yyyy,mm,dd,hhhh,"HYDFAIL",agb,bsa,lai,scb,npa,sep=" ") }else if(bad.met){ status = paste(polyg,yyyy,mm,dd,hhhh,"BAD_MET",agb,bsa,lai,scb,npa,sep=" ") }else if (metmiss){ diff --git a/ED/Template/Template/yearly_ascii.r b/ED/Template/Template/yearly_ascii.r index 63047156e..7b8df3af6 100644 --- a/ED/Template/Template/yearly_ascii.r +++ b/ED/Template/Template/yearly_ascii.r @@ -414,21 +414,58 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# diff --git a/ED/Template/bring_scripts.sh b/ED/Template/bring_scripts.sh index f4d20a56d..5bc552f2b 100755 --- a/ED/Template/bring_scripts.sh +++ b/ED/Template/bring_scripts.sh @@ -11,18 +11,28 @@ then #------ No platform provided. Try to guess, and if failed, then prompts the user. -----# host=$(hostname -s) case ${host} in - rclogin*|holy*|moorcroft*|rcnx*) platform="SLURM" ;; - au*|ha*) platform="PBS" ;; - sdumont*) platform="SLURM" ;; - sun-master|cmm*) platform="sun-lncc" ;; + rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + #----- Use SLURM scripts. --------------------------------------------------------# + platform="SLURM" + #---------------------------------------------------------------------------------# + ;; + au*|ha*|sun-master|cmm*) + #----- Use PBS scripts. ----------------------------------------------------------# + platform="PBS" + #---------------------------------------------------------------------------------# + ;; *) + #----- Host name is not one of the known ones. -----------------------------------# echo -n "Failed guessing platform from node name. Please type the name: " read platform + #---------------------------------------------------------------------------------# ;; esac - + #---------------------------------------------------------------------------------------# else + #------ Platform is provided as argument. ----------------------------------------------# platform=${1} + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# @@ -62,4 +72,5 @@ fi #----- Copy all scripts from the script pool. ---------------------------------------------# /bin/cp -v ./scripts/${platform}/*.sh . +/bin/cp -v ./scripts/COMMON/*.sh . #------------------------------------------------------------------------------------------# diff --git a/ED/Template/compare_equilibrium.r b/ED/Template/compare_equilibrium.r index 23715e718..9444b608f 100644 --- a/ED/Template/compare_equilibrium.r +++ b/ED/Template/compare_equilibrium.r @@ -306,7 +306,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "agb" , desc = "Above-ground biomass" , unit = untab$kgcom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -320,7 +320,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "bsa" , desc = "Basal area" , unit = untab$m2om2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -334,7 +334,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "lai" , desc = "Leaf area index" , unit = untab$m2lom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -348,7 +348,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tai" , desc = "Tree area index" , unit = untab$m2lom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -610,8 +610,8 @@ for (p in sequence(nsites)){ #---------------------------------------------------------------------------------# # Eliminate cohorts that are too small for AGB and basal area estimates. # #---------------------------------------------------------------------------------# - agbco = ifelse(dbhco %>=% this$dbh.min, agbco, 0.) - bsaco = ifelse(dbhco %>=% this$dbh.min, bsaco, 0.) + agbco = ifelse(dbhco %ge% this$dbh.min, agbco, 0.) + bsaco = ifelse(dbhco %ge% this$dbh.min, bsaco, 0.) #---------------------------------------------------------------------------------# diff --git a/ED/Template/compare_hourly.r b/ED/Template/compare_hourly.r index 5b10b79c2..65de2af89 100644 --- a/ED/Template/compare_hourly.r +++ b/ED/Template/compare_hourly.r @@ -333,7 +333,7 @@ compvar[[ n]] = list( vnam = "ustar" , symbol = "u^symbol(\"\\052\")" , desc = "Friction velocity" , unit = untab$mos - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#3B24B3" @@ -347,7 +347,7 @@ compvar[[ n]] = list( vnam = "cflxca" , symbol = "dot(C)[a*e]" , desc = "Carbon dioxide flux" , unit = untab$umolcom2os - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#AB8C3D" @@ -361,7 +361,7 @@ compvar[[ n]] = list( vnam = "cflxst" , symbol = "dot(C)[s*t*o*r]" , desc = "Carbon dioxide storage" , unit = untab$umolcom2os - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "orangered" , hue.high = "blue" , col = "#7D6E93" @@ -375,7 +375,7 @@ compvar[[ n]] = list( vnam = "nee" , symbol = "N*E*E" , desc = "Net ecosystem exchange" , unit = untab$umolcom2os - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#A3CC52" @@ -389,7 +389,7 @@ compvar[[ n]] = list( vnam = "nep" , symbol = "N*E*P" , desc = "Net ecosystem productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , col = "#A3CC52" @@ -403,7 +403,7 @@ compvar[[ n]] = list( vnam = "reco" , symbol = "dot(R)[E*c*o]" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#AB8C3D" @@ -417,7 +417,7 @@ compvar[[ n]] = list( vnam = "gpp" , symbol = "G*P*P" , desc = "Gross primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , col = "#306614" @@ -431,7 +431,7 @@ compvar[[ n]] = list( vnam = "parup" , symbol = "dot(Q)[P*A*R]^symbol(\"\\335\")" , desc = "Outgoing PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#143305" @@ -445,7 +445,7 @@ compvar[[ n]] = list( vnam = "rshortup" , symbol = "dot(Q)[S*W]^symbol(\"\\335\")" , desc = "Outgoing shortwave radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#2996CC" @@ -459,7 +459,7 @@ compvar[[ n]] = list( vnam = "rlongup" , symbol = "dot(Q)[L*W]^symbol(\"\\335\")" , desc = "Outgoing longwave radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#E65C17" @@ -473,7 +473,7 @@ compvar[[ n]] = list( vnam = "hflxca" , symbol = "dot(Q)[a*e]" , desc = "Sensible heat flux" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#990F0F" @@ -487,7 +487,7 @@ compvar[[ n]] = list( vnam = "wflxca" , symbol = "dot(W)[a*e]" , desc = "Water vapour flux" , unit = untab$kgwom2oday - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0A4766" @@ -501,7 +501,7 @@ compvar[[ n]] = list( vnam = "can.temp" , symbol = "T[a]" , desc = "CAS Temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#4D0404" @@ -515,7 +515,7 @@ compvar[[ n]] = list( vnam = "can.shv" , symbol = "w[a]" , desc = "CAS specific humidity" , unit = untab$gwokg - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#160959" @@ -529,7 +529,7 @@ compvar[[ n]] = list( vnam = "can.co2" , symbol = "c[a]" , desc = "CAS CO2 mix. ratio" , unit = untab$umolcomol - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#4B6614" @@ -543,7 +543,7 @@ compvar[[ n]] = list( vnam = "soil.temp" , symbol = "T[s*o*i*l]" , desc = "Soil temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#7D6E93" @@ -557,7 +557,7 @@ compvar[[ n]] = list( vnam = "soil.water" , symbol = "vartheta[s*o*i*l]" , desc = "Soil moisture" , unit = untab$m3wom3 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#00AAAF" @@ -571,7 +571,7 @@ compvar[[ n]] = list( vnam = "soil.wetness" , symbol = "hat(w)[s*o*i*l]" , desc = "Soil wetness" , unit = untab$pc - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#00F3FB" @@ -595,7 +595,7 @@ control[[n]] = list( vnam = "rshort" , symbol = "S*W^symbol(\"\\337\")" , desc = "Incoming shortwave radiation" , unit = untab$wom2 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#FF5700" @@ -608,7 +608,7 @@ control[[n]] = list( vnam = "par" , symbol = "P*A*R^symbol(\"\\337\")" , desc = "Incoming PAR" , unit = untab$umolom2os - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -621,7 +621,7 @@ control[[n]] = list( vnam = "rlong" , symbol = "L*W^symbol(\"\\337\")" , desc = "Incoming longwave radiation" , unit = untab$wom2 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#A00014" @@ -634,7 +634,7 @@ control[[n]] = list( vnam = "atm.prss" , symbol = "p(e*f*t)" , desc = "Air pressure" , unit = untab$hpa - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#520485" @@ -647,7 +647,7 @@ control[[n]] = list( vnam = "atm.temp" , symbol = "T(e*f*t)" , desc = "Air temperature" , unit = untab$degC - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#FF5700" @@ -660,7 +660,7 @@ control[[n]] = list( vnam = "atm.shv" , symbol = "w(e*f*t)" , desc = "Air specific humidity" , unit = untab$gwokg - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -673,7 +673,7 @@ control[[n]] = list( vnam = "atm.vels" , symbol = "u(e*f*t)" , desc = "Wind speed" , unit = untab$mos - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#520485" @@ -686,7 +686,7 @@ control[[n]] = list( vnam = "rain" , symbol = "dot(W)(e*f*t)" , desc = "Precipitation rate" , unit = untab$kgwom2oday - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -699,7 +699,7 @@ control[[n]] = list( vnam = "atm.vpdef" , symbol = "e(e*f*t)" , desc = "Vapour pressure deficit" , unit = untab$hpa - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#FF5700" @@ -1534,7 +1534,7 @@ for (p in loop.sites){ #----- Create a quick filter for different u*. --------------------------------------# ustar.eco = ifelse(obser$measured.ustar & measured.co2,obser$ustar,NA) - ust.measured.eco = outer(ustar.eco,obser$ust.filter,FUN='%>=%') + ust.measured.eco = outer(ustar.eco,obser$ust.filter,FUN='%ge%') #------------------------------------------------------------------------------------# }#end if #---------------------------------------------------------------------------------------# @@ -8997,7 +8997,7 @@ if (plot.skill.taylor){ #------------------------------------------------------------------------------# comp = res[[iata]]$sim[[simul.key[1]]][[this.vnam]] sdev.obs.now = sqrt(comp$obs.moment[cc,d,nseason,2]) - sel = sel & sdev.obs.now %>% 0 + sel = sel & sdev.obs.now %gt% 0 n.sel = sum(sel) #------------------------------------------------------------------------------# @@ -9537,7 +9537,7 @@ if (plot.skill.taylor){ #----- Select fortnightly averages. ----------------------------------------# sel = is.finite(obs[[this.fnmean]][,cc]) sdev.obs.now = sd(obs[[this.fnmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.fnmean]][sel,cc] this.mod = mod[[this.fnmean]][sel,cc] percent.skill[p,d] = sum(sel) @@ -9545,7 +9545,7 @@ if (plot.skill.taylor){ #----- Select daily averages. ----------------------------------------------# sel = is.finite(obs[[this.dmean]][,cc]) sdev.obs.now = sd(obs[[this.dmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.dmean]][sel,cc] this.mod = mod[[this.dmean]][sel,cc] percent.skill[p,d] = sum(sel) @@ -9558,7 +9558,7 @@ if (plot.skill.taylor){ sel = d.sel & s.sel & o.sel sel = ifelse(is.na(sel),FALSE,sel) sdev.obs.now = sd(obs[[this.vnam]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.vnam]][sel,cc] this.mod = mod[[this.vnam]][sel,cc] if (sum(d.sel & s.sel) > 0){ @@ -9777,7 +9777,7 @@ if (plot.skill.taylor){ for (p in sequence(nsites)){ iata = sites$iata[p] this.diel = diel.key[d] - if (percent.skill[p,d] %>% 0){ + if (percent.skill[p,d] %gt% 0){ pair.now = list.skill[[iata]][[this.diel]] }else{ pair.now = list(obs=c(NA,NA,NA),mod=c(NA,NA,NA)) @@ -10278,7 +10278,7 @@ if (plot.skill.taylor){ sel = ( is.finite(obs[[this.fnmean]][,cc]) & this.vnam %in% v.inc ) sdev.obs.now = sd(obs[[this.fnmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.fnmean]][sel,cc] this.mod = mod[[this.fnmean]][sel,cc] percent.skill[v,p] = sum(sel) @@ -10287,7 +10287,7 @@ if (plot.skill.taylor){ sel = ( is.finite(obs[[this.dmean]][,cc]) & this.vnam %in% v.inc ) sdev.obs.now = sd(obs[[this.dmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.dmean]][sel,cc] this.mod = mod[[this.dmean]][sel,cc] percent.skill[v,p] = sum(sel) @@ -10300,7 +10300,7 @@ if (plot.skill.taylor){ sel = d.sel & s.sel & o.sel sel = ifelse(is.na(sel),FALSE,sel) sdev.obs.now = sd(obs[[this.vnam]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.vnam]][sel,cc] this.mod = mod[[this.vnam]][sel,cc] if (sum(d.sel & s.sel) > 0){ @@ -11048,7 +11048,7 @@ if (plot.soil.skill.taylor){ comp = res[[iata]]$sim[[simul.key[1]]][[this.vnam]] sdev.obs.now = sqrt(comp$obs.moment[cc,d,nseason,2]) sdev.mod.now = sqrt(comp$mod.moment[cc,d,nseason,2]) - sel = sel & sdev.obs.now %>% 0 + sel = sel & sdev.obs.now %gt% 0 n.sel = sum(sel) #------------------------------------------------------------------------# @@ -12117,7 +12117,7 @@ if (make.summ.table){ #------ Aggregate data to the total. ------------------------------------------# - if (df.now %>% 0 & o.sdev.now %>% 0){ + if (df.now %gt% 0 & o.sdev.now %gt% 0){ s.table$n [v] = s.table$n [v] + n.now s.table$df [v] = s.table$df [v] + df.now s.table$bias [v] = s.table$bias [v] + n.now * bias.now diff --git a/ED/Template/compare_longterm.r b/ED/Template/compare_longterm.r index ab20899ac..6f325f883 100644 --- a/ED/Template/compare_longterm.r +++ b/ED/Template/compare_longterm.r @@ -14,7 +14,7 @@ graphics.off() # Here is the user defined variable section. # #------------------------------------------------------------------------------------------# here = getwd() # Current directory -srcdir = "/n/home00/mlongo/util/Rsc" # Script directory +srcdir = "/n/home00/mlongo/Util/Rsc" # Script directory ibackground = 0 # Make figures compatible to background # 0 -- white # 1 -- black @@ -236,7 +236,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "agb" , desc = "Above-ground biomass" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -249,7 +249,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ba" , desc = "Basal area" , unit = untab$m2om2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -262,7 +262,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "lai" , desc = "Leaf area index" , unit = untab$m2lom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -275,7 +275,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "gpp" , desc = "Gross primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -288,7 +288,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "npp" , desc = "Net primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -301,7 +301,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -314,7 +314,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "cba" , desc = "Carbon balance" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -327,7 +327,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -340,7 +340,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "nep" , desc = "Net Ecosystem Productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -353,7 +353,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -366,7 +366,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wflxca" , desc = "Water vapour flux" , unit = untab$kgwom2oday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -379,7 +379,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "transp" , desc = "Transpiration" , unit = untab$kgwom2oday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -392,7 +392,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "bowen" , desc = "Bowen ratio" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -405,7 +405,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tratio" , desc = "Transpiration ratio" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -418,7 +418,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ustar" , desc = "Friction velocity" , unit = untab$mos - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -431,7 +431,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshortup" , desc = "Upward SW radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -444,7 +444,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "albedo" , desc = "Albedo" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -457,7 +457,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rlongup" , desc = "Upward LW radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -470,7 +470,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "parup" , desc = "Upward PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -483,7 +483,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.gnd" , desc = "Ground absorption - PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -496,7 +496,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshort.gnd" , desc = "Ground absorption - SW" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -509,7 +509,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gpp" , desc = "Leaf GPP" , unit = untab$kgcom2loyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -522,7 +522,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = untab$kgwom2loday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -535,7 +535,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.temp" , desc = "Leaf temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -548,7 +548,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.vpd" , desc = "Leaf VPD" , unit = untab$hpa - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -561,7 +561,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf" , desc = "Leaf Absorption - PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -574,7 +574,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.beam" , desc = "Leaf Absorption - Direct PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -587,7 +587,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.diff" , desc = "Leaf Absorption - Diffuse PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -600,7 +600,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par" , desc = "Norm. Leaf Absorption - PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -613,7 +613,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.beam" , desc = "Norm. Leaf Absorption - Direct PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -626,7 +626,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.diff" , desc = "Norm. Leaf Absorption - Diffuse PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -639,7 +639,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.light" , desc = "Light-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -652,7 +652,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.rubp" , desc = "RuBP-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -665,7 +665,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.co2" , desc = "CO2-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -678,7 +678,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "fast.soil.c" , desc = "Fast soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -691,7 +691,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "struct.soil.c" , desc = "Structural soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -704,7 +704,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "slow.soil.c" , desc = "Slow soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -717,7 +717,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tot.soil.c" , desc = "Soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -730,7 +730,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "can.depth" , desc = "Mean canopy height" , unit = untab$m - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -743,7 +743,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "can.area" , desc = "Mean canopy area" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -756,7 +756,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wood.dens" , desc = "Mean wood density" , unit = untab$gocm3 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -769,7 +769,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "firemort" , desc = "Fire mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -782,7 +782,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ncbmort" , desc = "Density-dependent mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -795,7 +795,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "dimort" , desc = "Density independent mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -808,7 +808,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "mort" , desc = "Mortality rate" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -1454,12 +1454,12 @@ if (reload.range && file.exists(rdata.range)){ #------ Bowen ratio: use the patch-level variable. ----------------------# hflxca = datum$patch$hflxca [[stamp]] qwflxca = datum$patch$qwflxca[[stamp]] - vnow = ifelse(qwflxca %!=% 0, hflxca/qwflxca, NA) + vnow = ifelse(qwflxca %ne% 0, hflxca/qwflxca, NA) }else if(this.vnam %in% "tratio"){ #------ Bowen ratio: use the patch-level variable. ----------------------# transp = datum$patch$transp[[stamp]] wflxca = datum$patch$wflxca[[stamp]] - vnow = ifelse(wflxca %!=% 0, transp/wflxca, NA) + vnow = ifelse(wflxca %ne% 0, transp/wflxca, NA) }else if(this.patchvar){ #------ Use patch-level info if available... ----------------------------# vnow = datum$patch [[this.vnam]][[stamp]] @@ -1663,20 +1663,20 @@ for (p in loop.sites){ szpft = NULL patch = NULL }else if (this.vnam %in% "bowen"){ - emean = with(datum$emean,ifelse(qwflxca %!=% 0,hflxca/qwflxca,NA)) + emean = with(datum$emean,ifelse(qwflxca %ne% 0,hflxca/qwflxca,NA)) szpft = NULL patch = with( data = datum$patch - , expr = mapply( FUN = function(h,qw) ifelse(qw%!=%0,h/qw,NA) + , expr = mapply( FUN = function(h,qw) ifelse(qw%ne%0,h/qw,NA) , h = hflxca , qw = qwflxca , SIMPLIFY = FALSE )#end mapply )#end with }else if (this.vnam %in% "tratio"){ - emean = with(datum$emean,ifelse(wflxca %!=% 0,transp/wflxca,NA)) + emean = with(datum$emean,ifelse(wflxca %ne% 0,transp/wflxca,NA)) szpft = NULL patch = with( data = datum$patch - , expr = mapply( FUN = function(tp,w) ifelse(w%!=%0,tp/w,NA) + , expr = mapply( FUN = function(tp,w) ifelse(w%ne%0,tp/w,NA) , tp = transp , w = wflxca , SIMPLIFY = FALSE @@ -4115,7 +4115,7 @@ if (plot.ym.patch){ # Update range. # #---------------------------------------------------------------------------# if (zlog){ - ym.patch = ifelse(ym.patch %>% 0.0,ym.patch,NA) + ym.patch = ifelse(ym.patch %gt% 0.0,ym.patch,NA) yrange[,p,s] = range(c(yrange[,p,s],ym.patch),finite=TRUE) }else if (this.vnam %in% "bowen"){ ym.patch = pmax(bmn,pmin(bmx,ym.patch)) @@ -4560,7 +4560,7 @@ if (plot.zm.patch){ zm.patch = model[[this.vnam]]$zm.age }#end if if (zlog){ - zm.patch = ifelse(zm.patch %>% 0.0,zm.patch,NA) + zm.patch = ifelse(zm.patch %gt% 0.0,zm.patch,NA) }else if (this.vnam %in% "bowen"){ zm.patch = pmax(bmn,pmin(bmx,zm.patch)) + 0. * zm.patch }else if (this.vnam %in% "tratio"){ @@ -5056,7 +5056,7 @@ if (plot.xyz.patch){ # Update range. # #---------------------------------------------------------------------------# if (zlog){ - mm.patch = ifelse(mm.patch %>% 0.0,mm.patch,NA) + mm.patch = ifelse(mm.patch %gt% 0.0,mm.patch,NA) }else if (this.vnam %in% "bowen"){ mm.patch = pmax(bmn,pmin(bmx,mm.patch)) + 0. * mm.patch }else if (this.vnam %in% "tratio"){ diff --git a/ED/Template/compare_patch.r b/ED/Template/compare_patch.r index 9c55a3d1b..fdcf3e9b9 100644 --- a/ED/Template/compare_patch.r +++ b/ED/Template/compare_patch.r @@ -145,7 +145,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zupr.gpp" , desc = "GPP - Upper canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -156,7 +156,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zmid.gpp" , desc = "GPP - Mid-canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -167,7 +167,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zlwr.gpp" , desc = "GPP - Lower canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -178,7 +178,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "gpp" , desc = "Gross primary productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "gpp" , clcum = "nplant" @@ -189,7 +189,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "npp" , desc = "Net primary productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "npp" , clcum = "nplant" @@ -200,7 +200,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = "kgcom2oyr" - , cscheme = "iatlas" + , cscheme = "ibrbg" , qmean = TRUE , clprof = "plant.resp" , clcum = "nplant" @@ -211,7 +211,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "cba" , desc = "Carbon balance" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = "cba" , clcum = NA_character_ @@ -222,7 +222,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = "kgcom2oyr" - , cscheme = "iatlas" + , cscheme = "ibrbg" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -233,7 +233,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "nep" , desc = "Net Ecosystem Productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -244,7 +244,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -255,7 +255,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wflxca" , desc = "Water vapour flux" , unit = "kgwom2oday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -266,7 +266,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "transp" , desc = "Transpiration" , unit = "kgwom2oday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = "transp" , clcum = "nplant" @@ -277,7 +277,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshortup" , desc = "Upward SW radiation" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -288,7 +288,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rlongup" , desc = "Upward LW radiation" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -299,7 +299,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "parup" , desc = "Upward PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -310,7 +310,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.gnd" , desc = "Ground absorption - PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -321,7 +321,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshort.gnd" , desc = "Ground absorption - SW" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -332,7 +332,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "sm.stress" , desc = "Soil moisture stress" , unit = "empty" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -343,7 +343,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gpp" , desc = "Leaf GPP" , unit = "kgcom2loyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "leaf.gpp" , clcum = NA_character_ @@ -354,7 +354,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.temp" , desc = "Mean Leaf Temperature" , unit = "degC" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.temp" , clcum = NA_character_ @@ -365,7 +365,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.vpd" , desc = "Mean Leaf VPD" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.vpd" , clcum = NA_character_ @@ -376,7 +376,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = "kgwom2loday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = "leaf.gsw" , clcum = NA_character_ @@ -387,7 +387,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf" , desc = "Leaf Absorption - PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par" , clcum = "lai" @@ -398,7 +398,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.beam" , desc = "Leaf Absorption - Direct PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.beam" , clcum = "lai" @@ -409,7 +409,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.diff" , desc = "Leaf Absorption - Diffuse PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.diff" , clcum = "lai" @@ -420,7 +420,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par" , desc = "Norm. Leaf Absorption - PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par" , clcum = NA_character_ @@ -431,7 +431,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.beam" , desc = "Norm. Leaf Absorption - Direct PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.beam" , clcum = NA_character_ @@ -442,7 +442,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.diff" , desc = "Norm. Leaf Absorption - Diffuse PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.diff" , clcum = NA_character_ @@ -453,7 +453,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.light" , desc = "Light-limited Assimilation" , unit = "umolom2los" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "assim.light" , clcum = NA_character_ @@ -464,7 +464,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.rubp" , desc = "RuBP-limited Assimilation" , unit = "umolom2los" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "assim.rubp" , clcum = NA_character_ @@ -475,7 +475,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lpar" , desc = "Daytime PAR absorportion by leaves" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -486,7 +486,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lvpd" , desc = "Daytime Leaf VPD" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -497,7 +497,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.ltemp" , desc = "Daytime Leaf Temperature" , unit = "degC" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -508,7 +508,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.sms" , desc = "Daytime soil moisture stress" , unit = "empty" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -519,7 +519,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lgsw" , desc = "Daytime stomatal conductance" , unit = "kgwom2loday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -713,8 +713,8 @@ msize = plotsize(proje=FALSE,paper=mpaper,extendfc="lon",extfactor=f.ext/2) # Define some utility functions to determine derived patch variables. # #------------------------------------------------------------------------------------------# sum.soil.c.fun = function(fast,slow,struct) fast + slow + struct -bowen.fun = function(h,qw) ifelse(test = qw %!=% 0., yes = h/qw, no = NA) -tratio.fun = function(tp,w) ifelse(test = w %!=% 0., yes = tp/w, no = NA) +bowen.fun = function(h,qw) ifelse(test = qw %ne% 0., yes = h/qw, no = NA) +tratio.fun = function(tp,w) ifelse(test = w %ne% 0., yes = tp/w, no = NA) discard.fun = function(x) x * NA #------------------------------------------------------------------------------------------# @@ -741,7 +741,7 @@ layer.gpp.one.fun = function(dat,top,bot){ #------ We can't process empty data frames. --------------------------------------------# if (nrow(dat) > 0){ #----- Discard empty layers. --------------------------------------------------------# - dat = dat[dat$lai %>% 0,,drop=FALSE] + dat = dat[dat$lai %gt% 0,,drop=FALSE] #------------------------------------------------------------------------------------# }#end if (nrow(dat) > 0) #---------------------------------------------------------------------------------------# @@ -800,7 +800,7 @@ layer.gpp.one.fun = function(dat,top,bot){ #------ We can't process empty data frames. --------------------------------------------# if (nrow(dat) > 0){ #----- Discard empty layers. --------------------------------------------------------# - dat = dat[dat$lai %>% 0,,drop=FALSE] + dat = dat[dat$lai %gt% 0,,drop=FALSE] #------------------------------------------------------------------------------------# }#end if (nrow(dat) > 0) #---------------------------------------------------------------------------------------# diff --git a/ED/Template/compare_profiles.r b/ED/Template/compare_profiles.r index 79015524d..7219f4329 100644 --- a/ED/Template/compare_profiles.r +++ b/ED/Template/compare_profiles.r @@ -1810,7 +1810,7 @@ if (plot.site){ # for relative components, to avoid weird results. # #------------------------------------------------------------------------------# sel.day = tapply(X=model$diel[mn],INDEX=model$hour[mn],FUN=commonest) - sel.day = sel.day %==% 2 + sel.day = sel.day %eq% 2 #------------------------------------------------------------------------------# diff --git a/ED/Template/make_joborder.r b/ED/Template/make_joborder.r index 584a54388..3370fbbb2 100644 --- a/ED/Template/make_joborder.r +++ b/ED/Template/make_joborder.r @@ -29,6 +29,9 @@ lonlat = NULL # NULL - define runs local # (varrun/varlabel) #lonlat = file.path(here,"lonlat_input.txt") # Not NULL - read lon/lat from file, # and finish up settings below +add.coord = TRUE # Add coordinates to names +varalways = "ifire" # Variables to always appear in the + # jobname #------------------------------------------------------------------------------------------# @@ -132,128 +135,129 @@ if (! defjob && is.null(lonlat)){ #------------------------------------------------------------------------------------------# # Default properties. # #------------------------------------------------------------------------------------------# -default = list( run = "unnamed" - , iata = "xxx" - , lon = 0.00 - , lat = 0.00 - , yeara = "1967" - , montha = "01" - , daya = "01" - , timea = "0000" - , yearz = "2013" - , monthz = "01" - , dayz = "01" - , timez = "0000" - , init.mode = 6 - , iscenario = "default" - , isizepft = 0 - , iage = 30 - , imaxcohort = 50 - , isoilflg = 1 - , istext = 1 - , sand = -1.0 - , clay = -1.0 - , slsoc = 0.0266 - , slph = 4.7 - , slcec = 0.124 - , sldbd = 1192. - , depth = "F" - , isoil.hydro = 2 - , isoilbc = 1 - , sldrain = 90. - , scolour = 16 - , slzres = 0 - , queue = "linux.q" - , met.driver = "tower" - , dtlsm = 600. - , month.yrstep = 1 - , iphysiol = 3 - , vmfact.c3 = 1.00 - , vmfact.c4 = 1.00 - , mphoto.trc3 = 8.0 - , mphoto.tec3 = 7.2 - , mphoto.c4 = 4.0 - , bphoto.blc3 = 10000. - , bphoto.nlc3 = 1000. - , bphoto.c4 = 10000. - , kw.grass = 25. - , kw.tree = 20. - , gamma.c3 = 0.015 - , gamma.c4 = 0.025 - , d0.grass = 0.016 - , d0.tree = 0.016 - , alpha.c3 = 0.080 - , alpha.c4 = 0.040 - , klowco2 = round(0.7/39 * 1.e6) - , decomp.scheme = 5 - , rrffact = 1.000 - , growthresp = 0.300 - , lwidth.grass = 0.05 - , lwidth.bltree = 0.05 - , lwidth.nltree = 0.05 - , q10.c3 = 2.21 - , q10.c4 = 2.21 - , h2o.limit = 5 - , imort.scheme = 1 - , ddmort.const = 0.8 - , cbr.scheme = 0 - , isfclyrm = 4 - , icanturb = 0 - , ubmin = 1.00 - , ugbmin = 0.40 - , ustmin = 0.10 - , gamm = 13.0 - , gamh = 13.0 - , tprandtl = 1.00 - , ribmax = 0.50 - , atmco2 = 400. - , thcrit = -1.20 - , sm.fire = -1.40 - , ifire = 0 - , fire.parm = 0.5 - , ipercol = 0 - , runoff.time = 3600. - , imetrad = 5 - , ibranch = 1 - , icanrad = 2 - , ihrzrad = 0 - , crown.mod = 0 - , ltrans.vis = 0.05 - , lreflect.vis = 0.10 - , ltrans.nir = 0.200 - , lreflect.nir = 0.400 - , orient.tree = +0.100 - , orient.grass = -0.300 - , clump.tree = 0.80 - , clump.grass = 0.80 - , igoutput = 0 - , ivegtdyn = 1 - , ihydro = 0 - , istemresp = 1 - , istomata = 0 - , iplastic = 2 - , icarbonmort = 2 - , ihydromort = 0 - , igndvap = 0 - , iphen = -1 - , iallom = 3 - , ieconomics = 1 - , igrass = 1 - , ibigleaf = 0 - , integ.scheme = 1 - , nsub.euler = 50 - , irepro = 3 - , treefall = 0.0100 - , ianth.disturb = 0 - , ianth.dataset = "glu-331" - , sl.scale = 0 - , sl.yr.first = 1992 - , sl.nyrs = 50. - , biomass.harv = 0. - , skid.area = 1.0 - , skid.small = 0.60 - , skid.large = 1.00 - , felling.small = 0.35 +default = list( run = "unnamed" + , iata = "xxx" + , lon = 0.00 + , lat = 0.00 + , yeara = "1967" + , montha = "01" + , daya = "01" + , timea = "0000" + , yearz = "2013" + , monthz = "01" + , dayz = "01" + , timez = "0000" + , init.mode = 6 + , iscenario = "default" + , isizepft = 0 + , iage = 30 + , imaxcohort = 50 + , isoilflg = 1 + , istext = 1 + , sand = -1.0 + , clay = -1.0 + , slsoc = 0.0266 + , slph = 4.7 + , slcec = 0.124 + , sldbd = 1192. + , depth = "F" + , isoil.hydro = 2 + , isoilbc = 1 + , sldrain = 90. + , scolour = 16 + , slzres = 0 + , queue = "linux.q" + , met.driver = "tower" + , dtlsm = 600. + , month.yrstep = 1 + , iphysiol = 3 + , vmfact.c3 = 1.00 + , vmfact.c4 = 1.00 + , mphoto.trc3 = 8.0 + , mphoto.tec3 = 7.2 + , mphoto.c4 = 4.0 + , bphoto.blc3 = 10000. + , bphoto.nlc3 = 1000. + , bphoto.c4 = 10000. + , kw.grass = 25. + , kw.tree = 20. + , gamma.c3 = 0.015 + , gamma.c4 = 0.025 + , d0.grass = 0.016 + , d0.tree = 0.016 + , alpha.c3 = 0.080 + , alpha.c4 = 0.040 + , klowco2 = round(0.7/39 * 1.e6) + , decomp.scheme = 5 + , rrffact = 1.000 + , growthresp = 0.300 + , lwidth.grass = 0.05 + , lwidth.bltree = 0.05 + , lwidth.nltree = 0.05 + , q10.c3 = 2.21 + , q10.c4 = 2.21 + , h2o.limit = 5 + , imort.scheme = 1 + , ddmort.const = 0.8 + , cbr.scheme = 0 + , isfclyrm = 3 + , icanturb = 0 + , ubmin = 1.00 + , ugbmin = 0.40 + , ustmin = 0.10 + , gamm = 13.0 + , gamh = 13.0 + , tprandtl = 1.00 + , ribmax = 0.50 + , atmco2 = 400. + , thcrit = -1.20 + , sm.fire = -1.40 + , ifire = 0 + , fire.parm = 0.5 + , ipercol = 0 + , runoff.time = 3600. + , imetrad = 5 + , ibranch = 1 + , icanrad = 2 + , ihrzrad = 0 + , crown.mod = 0 + , ltrans.vis = 0.05 + , lreflect.vis = 0.10 + , ltrans.nir = 0.200 + , lreflect.nir = 0.400 + , orient.tree = +0.100 + , orient.grass = -0.300 + , clump.tree = 0.80 + , clump.grass = 0.80 + , igoutput = 0 + , ivegtdyn = 1 + , ihydro = 0 + , istemresp = 1 + , istomata = 0 + , iplastic = 2 + , icarbonmort = 2 + , ihydromort = 0 + , igndvap = 0 + , iphen = -1 + , iallom = 3 + , ieconomics = 1 + , igrass = 1 + , ibigleaf = 0 + , integ.scheme = 1 + , nsub.euler = 50 + , irepro = 3 + , treefall = 0.0100 + , ianth.disturb = 0 + , ianth.dataset = "glu-331" + , sl.scale = 0 + , sl.yr.first = 1992 + , sl.nyrs = 50. + , biomass.harv = 0. + , skid.area = 1.0 + , skid.dbh.thresh = 30. + , skid.small = 0.60 + , skid.large = 1.00 + , felling.small = 0.35 ) #end list #------------------------------------------------------------------------------------------# @@ -302,17 +306,17 @@ for (n in sequence(nvars)){ joborder$felling.small = sapply(myruns$sl.type,FUN=switch,ril=0.35,cvl=0.10,NA) }else if (name.now %in% "ihydrodyn"){ idx = myruns$ihydrodyn + 1 - joborder$ihydro = c(0,0,1)[idx] - joborder$istemresp = c(0,1,1)[idx] - joborder$istomata = c(0,0,1)[idx] - joborder$growthresp = c(0.30,0.45,0.45)[idx] - joborder$iphen = c(3,3,4)[idx] - joborder$iplastic = c(2,3,3)[idx] - joborder$icarbonmort = c(1,2,2)[idx] - joborder$ihydromort = c(0,0,1)[idx] - joborder$iallom = c(3,4,4)[idx] - joborder$h2o.limit = c(5,5,4)[idx] - joborder$igrass = c(1,1,0)[idx] + joborder$ihydro = c( 0, 1, 1, 1, 1, 1)[idx] + joborder$istemresp = c( 0, 0, 1, 1, 0, 0)[idx] + joborder$istomata = c( 0, 1, 1, 1, 1, 1)[idx] + joborder$growthresp = c(0.30,0.45,0.45,0.40,0.40,0.40)[idx] + joborder$iphen = c( 2, 2, 4, 4, 3, 5)[idx] + joborder$iplastic = c( 2, 2, 3, 3, 2, 2)[idx] + joborder$icarbonmort = c( 1, 1, 2, 2, 1, 1)[idx] + joborder$ihydromort = c( 0, 0, 1, 1, 0, 0)[idx] + joborder$iallom = c( 3, 3, 4, 3, 3, 5)[idx] + joborder$h2o.limit = c( 5, 3, 4, 3, 3, 3)[idx] + joborder$igrass = c( 1, 0, 0, 0, 0, 0)[idx] }else if (name.now %in% names(joborder)){ joborder[[name.now]] = myruns[[name.now]] }else{ @@ -344,6 +348,11 @@ if ( "biomass.harv" %in% names(varrun)){ )#end redundant forbidden = forbidden | redundant }#end if ("biomass.harv" %in% names(varrun)) +if ( all(c("ifire","sm.fire") %in% names(varrun))){ + smf.min = min(varrun$sm.fire) + redundant = joborder$ifire == 0 & joborder$sm.fire != smf.min + forbidden = forbidden | redundant +}#end if ( "ifire" %in% names(varrun)) joborder = joborder[! forbidden,] myruns = myruns[! forbidden,] nruns = nrow(myruns) @@ -421,6 +430,18 @@ if (is.null(lonlat)){ #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case coordinates are sought, add them right after iata. # + #---------------------------------------------------------------------------------------# + if (add.coord){ + idx = match(varrun$iata,poilist$iata) + lonlab = sprintf("lon%+06.2f",poilist$lon[idx]) + latlab = sprintf("lat%+06.2f",poilist$lat[idx]) + varlabel$iata = paste(varlabel$iata,lonlab,latlab,sep="_") + }#end if + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Build the name of the simulations. The polygon name always stays, even if the run # @@ -430,7 +451,7 @@ if (is.null(lonlat)){ runname = defname[! forbidden] metname = "" }else{ - stay = which(names(varlabel) %in% c("iata")) + stay = which(names(varlabel) %in% c("iata",varalways)) bye = which(sapply(X=varlabel,FUN=length) == 1) bye = bye[! bye %in% stay] if (length(bye) > 0) for (b in sort(bye,decreasing=TRUE)) varlabel[[b]] = NULL @@ -452,11 +473,10 @@ if (is.null(lonlat)){ #---------------------------------------------------------------------------------------# # Job name by appending longitude and latitude. # #---------------------------------------------------------------------------------------# - joborder$run = paste( joborder$iata - , "_lon",sprintf("%+06.2f",joborder$lon) - , "_lat",sprintf("%+06.2f",joborder$lat) - , sep = "" - )#end paste + joborder$run = paste0( joborder$iata + , "_lon",sprintf("%+06.2f",joborder$lon) + , "_lat",sprintf("%+06.2f",joborder$lat) + )#end paste0 #---------------------------------------------------------------------------------------# }#end if #------------------------------------------------------------------------------------------# diff --git a/ED/Template/plot_vulnerable.r b/ED/Template/plot_vulnerable.r index 25eb83397..b57e54ad2 100644 --- a/ED/Template/plot_vulnerable.r +++ b/ED/Template/plot_vulnerable.r @@ -101,7 +101,7 @@ ed22var[[ 1]] = list( vname = "et" , plog = FALSE , min = 600 , max = 1600 - , cscheme = "ipanoply" + , cscheme = "rdbu" )#end list ed22var[[ 2]] = list( vname = "transp" , desc = "Transpiration" @@ -109,7 +109,7 @@ ed22var[[ 2]] = list( vname = "transp" , plog = FALSE , min = 400 , max = 1000 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 3]] = list( vname = "gpp" , desc = "Gross Primary Productivity" @@ -117,7 +117,7 @@ ed22var[[ 3]] = list( vname = "gpp" , plog = FALSE , min = 1.5 , max = 3.5 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 4]] = list( vname = "npp" , desc = "Net Primary Productivity" @@ -125,7 +125,7 @@ ed22var[[ 4]] = list( vname = "npp" , plog = FALSE , min = 1.2 , max = 3.0 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 5]] = list( vname = "rshort" , desc = "Incoming SW Radiation" @@ -133,7 +133,7 @@ ed22var[[ 5]] = list( vname = "rshort" , plog = FALSE , min = 170 , max = 230 - , cscheme = "icloudy" + , cscheme = "ibugy" )#end list ed22var[[ 6]] = list( vname = "atm.temp" , desc = "Air temperature" @@ -141,7 +141,7 @@ ed22var[[ 6]] = list( vname = "atm.temp" , plog = FALSE , min = 15 , max = 27 - , cscheme = "panoply" + , cscheme = "irdbu" )#end list ed22var[[ 7]] = list( vname = "atm.vpd" , desc = "Air VPD" @@ -149,7 +149,7 @@ ed22var[[ 7]] = list( vname = "atm.vpd" , plog = FALSE , min = 5 , max = 21 - , cscheme = "panoply" + , cscheme = "irdbu" )#end list ed22var[[ 8]] = list( vname = "agb" , desc = "Above-ground biomass" @@ -157,7 +157,7 @@ ed22var[[ 8]] = list( vname = "agb" , plog = FALSE , min = 0 , max = 22 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 9]] = list( vname = "bsa" , desc = "Basal Area" @@ -165,7 +165,7 @@ ed22var[[ 9]] = list( vname = "bsa" , plog = FALSE , min = 0 , max = 32 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[10]] = list( vname = "lai" , desc = "Leaf area index" @@ -173,7 +173,7 @@ ed22var[[10]] = list( vname = "lai" , plog = FALSE , min = 1.5 , max = 4.5 - , cscheme = "clife" + , cscheme = "prgn" )#end list #------------------------------------------------------------------------------------------# @@ -183,7 +183,7 @@ ed22var[[10]] = list( vname = "lai" statvar = list() statvar[[ 1]] = list( vname = "location" , desc = "Location Parameter" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "mmoyr" , min = 900 , max = 3500 @@ -191,7 +191,7 @@ statvar[[ 1]] = list( vname = "location" )#end list statvar[[ 2]] = list( vname = "scale" , desc = "Scale Parameter" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "mmoyr" , min = 100 , max = 1000 @@ -199,7 +199,7 @@ statvar[[ 2]] = list( vname = "scale" )#end list statvar[[ 3]] = list( vname = "shape" , desc = "Shape Parameter" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "empty" , min = -5 , max = +5 @@ -207,7 +207,7 @@ statvar[[ 3]] = list( vname = "shape" )#end list statvar[[ 4]] = list( vname = "dlocation.rel" , desc = "Vulnerability (Location)" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "empty" , min = -3 , max = 0 @@ -215,7 +215,7 @@ statvar[[ 4]] = list( vname = "dlocation.rel" )#end list statvar[[ 5]] = list( vname = "dscale.rel" , desc = "Vulnerability (Scale)" - , cscheme = "ihue.hot" + , cscheme = "imagma" , unit = "empty" , min = 0.0 , max = 3.0 @@ -223,7 +223,7 @@ statvar[[ 5]] = list( vname = "dscale.rel" )#end list statvar[[ 6]] = list( vname = "dshape.abs" , desc = "Vulnerability (Shape)" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "empty" , min = -3.0 , max = 0.0 @@ -231,7 +231,7 @@ statvar[[ 6]] = list( vname = "dshape.abs" )#end list statvar[[ 7]] = list( vname = "mean" , desc = "Mean" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "mmoyr" , min = 900 , max = 3500 @@ -239,7 +239,7 @@ statvar[[ 7]] = list( vname = "mean" )#end list statvar[[ 8]] = list( vname = "sdev" , desc = "Standard Deviation" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "mmoyr" , min = 100 , max = 800 @@ -247,7 +247,7 @@ statvar[[ 8]] = list( vname = "sdev" )#end list statvar[[ 9]] = list( vname = "skew" , desc = "Skewness" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "empty" , min = -1.5 , max = 1.5 @@ -255,7 +255,7 @@ statvar[[ 9]] = list( vname = "skew" )#end list statvar[[10]] = list( vname = "sn.cvar" , desc = "Coeff. of Variation (SN)" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "empty" , min = 0.1 , max = 0.3 @@ -263,7 +263,7 @@ statvar[[10]] = list( vname = "sn.cvar" )#end list statvar[[11]] = list( vname = "norm.cvar" , desc = "Coeff. of Variation" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "empty" , min = 0.10 , max = 0.25 @@ -434,9 +434,7 @@ nptref = length(ptref) #------ List of schemes to use col1. ------------------------------------------------------# -col1.schemes = c("panoply","ipanoply","muitas","imuitas","hue.purple","ihue.purple" - ,"cloudy","icloudy","hue.blue","ihue.blue","hue.green","ihue.green" - ,"clife","iclife","hue.cold","ihue.cold") +col1.schemes = c("irdbu","rdbu","bugy","ibugy","prgn","iprgn","magma","imagma") #------------------------------------------------------------------------------------------# @@ -1628,7 +1626,7 @@ for (v in sequence(nstatvar)){ cat (" + Plot the RMSE for each site and data set...","\n") #---- Select colour for sites. ---------------------------------------------------------# - if ("panoply" %in% col1.schemes){ + if ("irdbu" %in% col1.schemes){ col.key = "col1" }else{ col.key = "col2" @@ -1732,7 +1730,7 @@ cat (" + Plot the RMSE for each site and data set...","\n") , fixed.ylim = TRUE , xlim = longitude.limit , ylim = latitude.limit - , colour.palette = panoply + , colour.palette = irdbu , levels = this.levels , nlevels = this.nlevels , pch = pch.wmo @@ -2145,7 +2143,7 @@ for (v in sequence(nthree.dim)){ n.pretty.fourth = length(pretty.fourth) fourth.breaks = c(-Inf,pretty.fourth[-c(1,n.pretty.fourth)],Inf) fourth.colour = cut(ymean[[vname.fourth]],fourth.breaks) - fourth.cscheme = clife(n=length(levels(fourth.colour))-1) + fourth.cscheme = prgn(n=length(levels(fourth.colour))-1) fourth.colour = fourth.cscheme[match(fourth.colour,levels(fourth.colour))] #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/bring_figures.sh b/ED/Template/scripts/COMMON/bring_figures.sh new file mode 100755 index 000000000..5d265ea8d --- /dev/null +++ b/ED/Template/scripts/COMMON/bring_figures.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# +here=$(pwd) +#----- Description of this simulation, used to create unique job names. -------------------# +desc=$(basename ${here}) +#----- File containing the list of jobs and their settings: -------------------------------# +joborder="${here}/joborder.txt" # ! File with the job instructions +#----- Sub-directory to copy. -------------------------------------------------------------# +subdir="monthly" +#----- Sub-sub-directory to copy (for all, set all). --------------------------------------# +subsub="compemean compmmean tspft tsdbh theme_mmean" +#----- Prefix of files to bring that are in the main directory. ---------------------------# +subpref="disturb" +#------------------------------------------------------------------------------------------# + + +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# Unless you are going to modify the way jobs are submitted, you don't need to change # +# anything beyond this point. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + + + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +if [ ${npolys} -lt 100 ] +then + ndig=2 +elif [ ${npolys} -lt 1000 ] +then + ndig=3 +elif [ ${npolys} -lt 10000 ] +then + ndig=4 +else + ndig=5 +fi +format="%${ndig}.${ndig}i" +#------------------------------------------------------------------------------------------# + + + +#----- Create path with output files. -----------------------------------------------------# +outpath="${here}/${desc}_figures" +mkdir -pv ${outpath} +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +n_submit=0 +while [[ ${ff} -lt ${npolys} ]] +do + let ff=${ff}+1 + let line=${ff}+3 + ffout=$(printf "${format}" ${ff}) + + + + + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + echo " + Copy figures from simulation: ${polyname}." + #---------------------------------------------------------------------------------------# + + + #------ Create output path for this simulation. ----------------------------------------# + inpoly="${here}/${polyname}/${subdir}" + outpoly="${outpath}/${polyname}" + mkdir -p ${outpoly} + #---------------------------------------------------------------------------------------# + + + #------ Copy files. --------------------------------------------------------------------# + for subnow in ${subsub} + do + #----- Check whether to copy everything or a specific directory. --------------------# + case ${subnow} in + all) + rsync -Purtv ${inpoly}/* ${outpoly} + ;; + tsdbh) + mkdir -p ${outpoly}/tsdbh + rsync -Purtv ${inpoly}/tsdbh/*/*-pft-00-* ${outpoly}/tsdbh + ;; + *) + rsync -Purtv ${inpoly}/${subnow} ${outpoly} + ;; + esac + #------------------------------------------------------------------------------------# + done + #---------------------------------------------------------------------------------------# + + + #------ Copy files in the main sub-directory, in case any is to be copied. -------------# + if [[ "${subpref}" != "" ]] + then + #------------------------------------------------------------------------------------# + # Loop through prefixes. # + #------------------------------------------------------------------------------------# + for prefnow in ${subpref} + do + #----- Check whether to copy everything or a specific directory. -----------------# + rsync -Putv ${inpoly}/${prefnow}*.??? ${outpoly} + #---------------------------------------------------------------------------------# + done + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# + +done +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/email_reset.sh b/ED/Template/scripts/COMMON/email_reset.sh similarity index 100% rename from ED/Template/scripts/PBS/email_reset.sh rename to ED/Template/scripts/COMMON/email_reset.sh diff --git a/ED/Template/scripts/SLURM/last_histo.sh b/ED/Template/scripts/COMMON/last_histo.sh similarity index 75% rename from ED/Template/scripts/SLURM/last_histo.sh rename to ED/Template/scripts/COMMON/last_histo.sh index d1b819f60..55fac6e42 100755 --- a/ED/Template/scripts/SLURM/last_histo.sh +++ b/ED/Template/scripts/COMMON/last_histo.sh @@ -148,128 +148,129 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #--------------------------------------------------------------------------------------- diff --git a/ED/Template/scripts/COMMON/reset.sh b/ED/Template/scripts/COMMON/reset.sh new file mode 100755 index 000000000..e6b175eb0 --- /dev/null +++ b/ED/Template/scripts/COMMON/reset.sh @@ -0,0 +1,436 @@ +#!/bin/sh +here=$(pwd) +moi=$(whoami) +diskthere="/n/moorcroftfs2" +joborder="${here}/joborder.txt" + +desc=$(basename ${here}) + +#----- Executable name. -------------------------------------------------------------------# +execname="ed_2.2-opt" +execsrc="${HOME}/EDBRAMS/ED/build" +#------------------------------------------------------------------------------------------# + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + platform="SLURM" + ;; +au*|ha*|sun-master|cmm*) + platform="PBS" + ;; +*) + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + ;; +esac +#------------------------------------------------------------------------------------------# + + +#----- Find the output path (both local and remote paths will be cleaned). ----------------# +basehere=$(basename ${here}) +dirhere=$(dirname ${here}) +while [ ${basehere} != ${moi} ] +do + basehere=$(basename ${dirhere}) + dirhere=$(dirname ${dirhere}) +done +diskhere=${dirhere} +echo "-------------------------------------------------------------------------------" +echo " - Simulation control on disk: ${diskhere}" +echo " - Output on disk: ${diskthere}" +echo "-------------------------------------------------------------------------------" +there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) +#------------------------------------------------------------------------------------------# + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +#------------------------------------------------------------------------------------------# + + +#----- Check that the user is aware that it will remove everything... ---------------------# +if [ "x${1}" == "x-d" ] +then + echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" +else + echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" +fi +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo " " +echo " Look, this will really stop ALL your jobs and delete all files!!!" +echo " Are you sure? [y/N]" +echo " " +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "Okay then, but if you regret later don't say that I did not warn you..." +echo "I'm giving you a few seconds to kill this script in case you change your mind..." +delfun=11 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Job stopping will begin in ${delfun} seconds..." + sleep 1 +done +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #------ Define job name. ---------------------------------------------------------------# + jobname="${desc}-${polyname}" + #---------------------------------------------------------------------------------------# + + + #------- Delete jobs. ------------------------------------------------------------------# + case "${platform}" in + SLURM) + scancel -n ${jobname} + ;; + PBS) + jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + qdel ${jobid} + fi + ;; + esac + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + +delfun=16 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Files will be deleted in ${delfun} seconds..." + sleep 1 +done + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + if [ "x${1}" == "x-d" ] + then + find "${here}/${polyname}" -print -delete + find "${there}/${polyname}" -print -delete + else + /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" + /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" + cd "${here}/${polyname}" + ./purge.sh + cd "${there}/${polyname}" + ./purge.sh + fi +done +#------------------------------------------------------------------------------------------# + + + + +#------------------------------------------------------------------------------------------# +# Replace the executable. # +#------------------------------------------------------------------------------------------# +cd ${here} +if [ -s ${here}/executable/${execname} ] +then + rm -frv ${here}/executable/${execname} + cp -fv ${execsrc}/${execname} ${here}/executable +fi +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/sim_sitter.sh b/ED/Template/scripts/COMMON/sim_sitter.sh new file mode 100755 index 000000000..d90799d3d --- /dev/null +++ b/ED/Template/scripts/COMMON/sim_sitter.sh @@ -0,0 +1,360 @@ +#!/bin/bash + + + +#------------------------------------------------------------------------------------------# +# Which scripts to run. # +# # +# - read_monthly.r - This reads the monthly mean files (results can then be used for # +# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # +# thing.) # +# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it is # +# intended to simplify the output for learning purposes. # +# - plot_monthly.r - This creates several plots based on the monthly mean output. # +# - plot_yearly.r - This creates plots with year time series. # +# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # +# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # +# # +# The following scripts should work too, but I haven't tested them. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # +# the step to be rejected. # +#------------------------------------------------------------------------------------------# + + +#----- Main settings. Do look at run_sitter.sh and epost.sh for additional settings. -----# +here=$(pwd) # Current path. +there="/path/to/permanent/storage" # Permanent storage path (leave empty for no transfer) +email="myself\@myserver.com" # Your e-mail. Put a backslash before the @ +sbatch=$(which sbatch) # SLURM command to submit job. +sitter_queue="myqueue" # Queue to run run_sitter.sh +sitter_runtime="mytime" # Run time request for run_sitter.sh +sitter_memory=0 # Requested memory (Mb) for run_sitter.sh +lhisto_queue="myqueue" # Queue to run last_histo.sh +lhisto_runtime="mytime" # Run time request for last_histo.sh +lhisto_memory=0 # Requested memory (Mb) for last_histo.sh +transfer_full=false # Flag to decide between full and partial transfer +epost_queue="myqueue" # Queue to run epost.sh +epost_runtime="mytime" # Run time request for epost.sh +epost_memory=0 # Requested memory (Mb) for epost.sh +epost_reserve="" # Reservation flag (leave blank unless you have + # reservation privileges). +rscript="nothing.r" # Which script to run with epost.sh. See options above. + # Multiple scripts are allowed, put spaces between + # them. (e.g. rscript="plot_monthly.r plot_fast.r") +overcommit=false # Ignore maximum number of tasks when submitting + # epost tasks? +frqemail=43200 # How often to send emails on simulation status? +delay1st_min=20 # Time (in minutes) to wait before the first check + # (needed in case the run_sitter script is submitted + # before the simulation starts. In case the + # simulation is already running, it is fine to set + # this to zero). +wait_minutes=60 # Waiting time before checking run again (in minutes) +frqpost=3 # How often to run post-processing and file management + # This number is in iterations. Zero means never. +frqtouch=0 # How often to touch executable, scripts, and Template? + # This number is in iterations. Zero means never. +checkhourly="n" # Check hourly files. +checkstatus="y" # Check status before compressing +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# THINK TWICE BEFORE CHANGING ANYTHING BEYOND THIS POINT. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + +#----- Make sure e-mail and queue are pre-defined. ----------------------------------------# +if [[ "${email}" == "myself\@myserver.com" ]] || + [[ "${there}" == "/path/to/permanent/storage" ]] || + [[ "${rscript}" == "nothing.r" ]] || + [[ "${sitter_queue}" == "myqueue" ]] || + [[ "${sitter_runtime}" == "mytime" ]] || + [[ ${sitter_memory} -eq 0 ]] || + [[ "${lhisto_queue}" == "myqueue" ]] || + [[ "${lhisto_runtime}" == "mytime" ]] || + [[ ${lhisto_memory} -eq 0 ]] || + [[ "${epost_queue}" == "myqueue" ]] || + [[ "${epost_runtime}" == "mytime" ]] || + [[ ${epost_memory} -eq 0 ]] +then + echo "---------------------------------------------------------------------------------" + echo " The following variables must be set. In case any of them have dummy values, " + echo " check your script sim_sitter.sh." + echo " " + echo " email = ${email}" + echo " there = ${there}" + echo " rscript = ${rscript}" + echo " sitter_queue = ${sitter_queue}" + echo " epost_queue = ${epost_queue}" + echo " lhisto_queue = ${lhisto_queue}" + echo " sitter_queue = ${sitter_queue}" + echo " sitter_runtime = ${sitter_runtime}" + echo " sitter_memory = ${sitter_memory}" + echo " lhisto_queue = ${lhisto_queue}" + echo " lhisto_runtime = ${lhisto_runtime}" + echo " lhisto_memory = ${lhisto_memory}" + echo " epost_queue = ${epost_queue}" + echo " epost_runtime = ${epost_runtime}" + echo " epost_memory = ${epost_memory}" + echo " " + echo "---------------------------------------------------------------------------------" + exit 99 +fi +#------------------------------------------------------------------------------------------# + + + +#----- Find out which platform we are using. ----------------------------------------------# +if [ "${1}" == "" ] +then + #------ No platform provided. Try to guess, and if failed, then prompts the user. -----# + host=$(hostname -s) + case ${host} in + rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + #----- Use SLURM scripts. --------------------------------------------------------# + platform="SLURM" + #---------------------------------------------------------------------------------# + ;; + au*|ha*|sun-master|cmm*) + #----- Use PBS scripts. ----------------------------------------------------------# + platform="PBS" + #---------------------------------------------------------------------------------# + ;; + *) + #----- Host name is not one of the known ones. -----------------------------------# + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + #---------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# +else + #------ Platform is provided as argument. ----------------------------------------------# + platform=${1} + #---------------------------------------------------------------------------------------# +fi +#------------------------------------------------------------------------------------------# + + + + +#------ List of scripts. ------------------------------------------------------------------# +run_sitter="${here}/run_sitter.sh" +epost="${here}/epost.sh" +transfer="${here}/transfer.sh" +orig_histo="${here}/scripts/COMMON/last_histo.sh" +last_histo="${here}/last_histo.sh" +#------------------------------------------------------------------------------------------# + + + +#----- Set job prefix. --------------------------------------------------------------------# +desc=$(basename ${here}) +#------------------------------------------------------------------------------------------# + + + + +#------------------------------------------------------------------------------------------# +# In case this is a SLURM cluster, append header to last_histo.sh. # +#------------------------------------------------------------------------------------------# +case "${platform}" in +SLURM) + #----- Reset last_histo. ---------------------------------------------------------------# + echo " + Reset $(basename ${last_histo})" + /bin/rm -f ${last_histo} + touch ${last_histo} + chmod u+x ${last_histo} + #---------------------------------------------------------------------------------------# + + + #----- Set some job instructions. ------------------------------------------------------# + lhisto_task="${desc}-last_histo.sh" + lhisto_sto="${here}/out_last_histo.out" + lhisto_ste="${here}/out_last_histo.err" + #---------------------------------------------------------------------------------------# + + + + #----- Add header. ---------------------------------------------------------------------# + echo "#!/bin/bash" >> ${last_histo} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${last_histo} + echo "#SBATCH --cpus-per-task=1 # CPUs per task" >> ${last_histo} + echo "#SBATCH --partition=${lhisto_queue} # Job partition" >> ${last_histo} + echo "#SBATCH --job-name=${lhisto_task} # Task name" >> ${last_histo} + echo "#SBATCH --mem-per-cpu=${lhisto_memory} # Memory per CPU" >> ${last_histo} + echo "#SBATCH --time=${lhisto_runtime} # Time for job" >> ${last_histo} + echo "#SBATCH --output=${lhisto_sto} # Standard output path" >> ${last_histo} + echo "#SBATCH --error=${lhisto_ste} # Standard error path" >> ${last_histo} + echo "#SBATCH --chdir=${here} # Main directory" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Initial settings." >> ${last_histo} + echo "here=\"${here}\" # Main path" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Print information about this job." >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"----- Summary of current job -------------------------\"" >> ${last_histo} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${last_histo} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${last_histo} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${last_histo} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${last_histo} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${last_histo} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${last_histo} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${last_histo} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${last_histo} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${last_histo} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${last_histo} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${last_histo} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${last_histo} + echo "echo \"------------------------------------------------------\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Define home in case home is not set" >> ${last_histo} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${last_histo} + echo "then" >> ${last_histo} + echo " export HOME=\$(echo ~)" >> ${last_histo} + echo "fi" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Load modules and settings." >> ${last_histo} + echo ". \${HOME}/.bashrc" >> ${last_histo} + #---------------------------------------------------------------------------------------# + + + + #----- Append the template last_histo.sh, skipping the first two lines. ----------------# + tail -n +3 ${orig_histo} >> ${last_histo} + #---------------------------------------------------------------------------------------# + + ;; +esac +#------------------------------------------------------------------------------------------# + + + + + + +#------------------------------------------------------------------------------------------# +# Make substitutions. # +# IMPORTANT: make sure "there" substitutions precede "here", otherwise the script will # +# not work as intended. # +#------------------------------------------------------------------------------------------# +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${run_sitter} +sed -i~ s@"recipient=\"\""@"recipient=\"${email}\""@g ${run_sitter} +sed -i~ s@"frqemail=\"\""@"frqemail=${frqemail}"@g ${run_sitter} +sed -i~ s@"delay1st_min=\"\""@"delay1st_min=${delay1st_min}"@g ${run_sitter} +sed -i~ s@"wait_minutes=\"\""@"wait_minutes=${wait_minutes}"@g ${run_sitter} +sed -i~ s@"frqpost=\"\""@"frqpost=${frqpost}"@g ${run_sitter} +sed -i~ s@"frqtouch=\"\""@"frqtouch=${frqtouch}"@g ${run_sitter} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${epost} +sed -i~ s@"global_queue=\"\""@"global_queue=\"${epost_queue}\""@g ${epost} +sed -i~ s@"rscript=\"\""@"rscript=\"${rscript}\""@g ${epost} +sed -i~ s@"submit=false"@"submit=true"@g ${epost} +sed -i~ s@"reservation=\"\""@"reservation=\"${epost_reserve}\""@g ${epost} +sed -i~ s@"sim_memory=0"@"sim_memory=${epost_memory}"@g ${epost} +sed -i~ s@"runtime=\"00:00:00\""@"runtime=\"${epost_runtime}\""@g ${epost} +sed -i~ s@"overcommit=\"\""@"overcommit=${overcommit}"@g ${epost} +sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${transfer} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${transfer} +sed -i~ s@"full_transfer=boolean"@"full_transfer=${transfer_full}"@g ${transfer} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${last_histo} +sed -i~ s@"checkhourly=\"\""@"checkhourly=\"${checkhourly}\""@g ${last_histo} +sed -i~ s@"checkstatus=\"\""@"checkstatus=\"${checkstatus}\""@g ${last_histo} +#------------------------------------------------------------------------------------------# + + +#----- Substitute paths in sit_utils R scripts. -------------------------------------------# +sed -i~ s@"mypath"@"${here}"@g ${here}/sit_utils/plot.region.r +sed -i~ s@"mypath"@"${here}"@g ${here}/sit_utils/plot.status.r +#------------------------------------------------------------------------------------------# + + +#----- Job preferences. -------------------------------------------------------------------# +sitter_joblog="${here}/out_sitter.out" +sitter_jobpref=$(basename ${here}) +sitter_jobname="${desc}-sitter" +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Check whether to submit the job. # +#------------------------------------------------------------------------------------------# +if [[ -s "${here}/run_sitter.lock" ]] || [[ -s "${here}/transfer.lock" ]] +then + echo " Lock file found for run_sitter.sh and/or transfer.lock." + echo " The scripts may be already running." + echo " Submit the script anyway [y|N]?" + read goahead +else + goahead="y" +fi +goahead="$(echo ${goahead} | tr '[:upper:]' '[:lower:]')" +#------------------------------------------------------------------------------------------# + + +#----- Submit run_sitter.sh in batch mode. ------------------------------------------------# +comm="${sbatch} -p ${sitter_queue} --mem-per-cpu=${sitter_memory} -t ${sitter_runtime}" +comm="${comm} -o ${sitter_joblog} -J ${sitter_jobname} -n 1 " +comm="${comm} --wrap=\"${here}/run_sitter.sh\"" +case ${goahead} in +y|yes) + /bin/rm -f ${here}/run_sitter.lock + /bin/rm -f ${here}/transfer.lock + /bin/rm -f ${here}/sit_utils/mycheck.txt + /bin/rm -f ${here}/sit_utils/lastcheck.txt + echo ${comm} + ${comm} + ;; +*) + bann="Script run_sitter was not submitted. In case you want to submit manually" + bann="${bann} this is the command:" + echo ${bann} + echo " " + echo ${comm} + ;; +esac +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/stopalljobs.sh b/ED/Template/scripts/COMMON/stopalljobs.sh new file mode 100755 index 000000000..f95640dcc --- /dev/null +++ b/ED/Template/scripts/COMMON/stopalljobs.sh @@ -0,0 +1,228 @@ +#!/bin/bash +here=$(pwd) +joborder="${here}/joborder.txt" +desc=$(basename ${here}) + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + platform="SLURM" + ;; +au*|ha*|sun-master|cmm*) + platform="PBS" + ;; +*) + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + ;; +esac +#------------------------------------------------------------------------------------------# + + + + +#----- Determine the number of polygons to stop. ------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 + +echo "Are you sure that you want to stop all jobs? [y/N]" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi +#------------------------------------------------------------------------------------------# + + +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo " " +echo " Look, this will really stop ALL your jobs... Are you sure? [y/N]" +echo " " +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "Alright then, but in case you regret later don't say that I didn't warn you..." +echo "I am giving you a few seconds to kill this script in case you change your mind..." +delfun=11 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Job stopping will begin in ${delfun} seconds..." + sleep 1 +done + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #------ Define job name. ---------------------------------------------------------------# + jobname="${desc}-${polyname}" + #---------------------------------------------------------------------------------------# + + + #------- Delete jobs. ------------------------------------------------------------------# + case "${platform}" in + SLURM) + scancel -n ${jobname} + ;; + PBS) + jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + qdel ${jobid} + fi + ;; + esac + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + + diff --git a/ED/Template/scripts/COMMON/transfer.sh b/ED/Template/scripts/COMMON/transfer.sh new file mode 100755 index 000000000..75544238f --- /dev/null +++ b/ED/Template/scripts/COMMON/transfer.sh @@ -0,0 +1,332 @@ +#!/bin/bash + +#==========================================================================================# +#==========================================================================================# +# Main settings: # +#------------------------------------------------------------------------------------------# +#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# +here="" +#----- Location to create the copy of these files. ----------------------------------------# +there="" +#----- File containing the list of jobs and their settings: -------------------------------# +joborder="${here}/joborder.txt" +#----- Command to be used for rsync. ------------------------------------------------------# +frsync="rsync -Putq --links --copy-unsafe-links" +rrsync="rsync -Prutq --links --copy-unsafe-links" +#----- Decide between copying everything or just some key files. --------------------------# +full_transfer=boolean +#------------------------------------------------------------------------------------------# + + + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# Unless you are going to modify the scripts, you don't need to change anything beyond # +# this point. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + +#------------------------------------------------------------------------------------------# +# First check that the main path and e-mail have been set. If not, don't run. # +#------------------------------------------------------------------------------------------# +if [[ "x${here}" == "x" ]] || [[ "x${there}" == "x" ]] || + [[ "x${full_transfer}" == "xboolean" ]] +then + echo " You must set some variables before running the script:" + echo " Check variables \"here\", \"there\", and \"full_transfer}!" + exit 99 +fi +#------------------------------------------------------------------------------------------# + + + + +#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# +if [[ "${here}" == "${there}" ]] +then + echo " Source and destination paths are the same. Transfer is not needed." + exit 0 +elif [[ -s ${here}/transfer.lock ]] +then + echo " Script transfer is running. Skip transfer for the time being." + exit +else + echo "I am going to back up your run." > ${here}/transfer.lock +fi +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Create the output path in case it isn't there. # +#------------------------------------------------------------------------------------------# +if [[ ! -s ${there} ]] +then + echo "Create backup path: ${there}." + mkdir -p ${there} +fi +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# First, copy the files at the basal directory. # +#------------------------------------------------------------------------------------------# +echo " + Copy files from the main directory." +${frsync} ${here}/* ${there} +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Then copy the fixed directories. # +#------------------------------------------------------------------------------------------# +echo " + Copy executable." +${rrsync} ${here}/executable ${there} +echo " + Copy sit_utils." +${rrsync} ${here}/sit_utils ${there} +echo " + Copy Template." +${rrsync} ${here}/Template ${there} +#------------------------------------------------------------------------------------------# + + + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [[ ${ff} -lt ${npolys} ]] +do + let ff=${ff}+1 + let line=${ff}+3 + + + #---------------------------------------------------------------------------------------# + # Format count. # + #---------------------------------------------------------------------------------------# + if [[ ${npolys} -ge 10 ]] && [[ ${npolys} -lt 100 ]] + then + ffout=$(printf '%2.2i' ${ff}) + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 1000 ]] + then + ffout=$(printf '%3.3i' ${ff}) + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 10000 ]] + then + ffout=$(printf '%4.4i' ${ff}) + else + ffout=${ff} + fi + ffout="${ffout} of ${npolys}" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #----- Check whether the directories exist or not, and stop the script if they do. -----# + if [[ -s ${here}/${polyname} ]] + then + echo -n " + Copy ${polyname} (${ffout})... " + + #------------------------------------------------------------------------------------# + # Sync this directory. Decide between full or partial transfer. # + #------------------------------------------------------------------------------------# + if ${full_transfer} + then + #----- Copy the entire directory. ------------------------------------------------# + ${rrsync} ${here}/${polyname} ${there} + #---------------------------------------------------------------------------------# + else + #----- Copy the base directory and the R output. ---------------------------------# + mkdir -p ${there}/${polyname} + mkdir -p ${there}/${polyname}/histo + ${frsync} ${here}/${polyname}/* ${there}/${polyname} + ${rrsync} ${here}/${polyname}/rdata_month ${there}/${polyname} + #---------------------------------------------------------------------------------# + + + #----- Copy the first and last history file. -------------------------------------# + ahisto="${polyname}-S-${yeara}-${montha}-${datea}-${timea}00-g01.h5" + zhisto="${polyname}-S-${yearz}-${monthz}-${datez}-${timez}00-g01.h5" + ${frsync} ${here}/${polyname}/histo/${ahisto} ${there}/${polyname}/histo + ${frsync} ${here}/${polyname}/histo/${zhisto} ${there}/${polyname}/histo + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# + echo "Done!" + + else + #----- Directory is not found. ------------------------------------------------------# + echo " + Skip ${polyname} (${ffout})." + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + +#----- Clean-up stuff. --------------------------------------------------------------------# +echo " Unlock transfer.sh." +/bin/rm -f ${here}/transfer.lock +echo "==== transfer.sh execution ends. ====" +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/check_run.sh b/ED/Template/scripts/PBS/check_run.sh index 4bd3f5e8c..f2146e4ed 100755 --- a/ED/Template/scripts/PBS/check_run.sh +++ b/ED/Template/scripts/PBS/check_run.sh @@ -86,128 +86,129 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/cspost.sh b/ED/Template/scripts/PBS/cspost.sh deleted file mode 100755 index db4957d22..000000000 --- a/ED/Template/scripts/PBS/cspost.sh +++ /dev/null @@ -1,306 +0,0 @@ -#!/bin/bash -. ~/.bashrc -here=$(pwd) -thisqueue="moorcroft2b" # ! Queue where jobs should be submitted -#----- Check whether to use openlava or typical job submission. ---------------------------# -openlava="y" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Grab arguments and also set some defaults. # -#------------------------------------------------------------------------------------------# -nargs=$# # Number of arguments -args=$@ # List of arguments -ibg="0" # Background is white by default -rdata="RData_scenario" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Check whether this machine supports openlava or not (in case this is a openlava. # -#------------------------------------------------------------------------------------------# -thismach=$(hostname -s) -if [ ${thismach} == "rclogin01" ] && [ ${openlava} == "y" -o ${openlava} == "Y" ] -then - . /opt/openlava-2.0/etc/openlava-client.sh -elif [ ${thismach} != "rclogin01" ] && [ ${openlava} == "y" -o ${openlava} == "Y" ] -then - echo " This machine (${hostname}) doesn't support openlava, sorry!" - exit 39 -fi -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all arguments, and assign soil texture and temperature based on the # -# options. # -#------------------------------------------------------------------------------------------# -istext=16 -itemp=0 -irain=0 -if [ ${nargs} -gt 0 ] -then - nextstext="n" - nexttemp="n" - nextrain="n" - nextbg="n" - n=0 - for arg in ${args} - do - let n=${n}+1 - - if [ ${nextstext} == "y" ] - then - istext=${arg} - nextstext="n" - elif [ ${nexttemp} == "y" ] - then - itemp=${arg} - nexttemp="n" - elif [ ${nextrain} == "y" ] - then - irain=${arg} - nextrain="n" - elif [ ${nextbg} == "y" ] - then - ibg=${arg} - nextbg="n" - elif [ "x${arg}" == "x-s" ] - then - nextstext="y" - elif [ "x${arg}" == "x-r" ] - then - nextrain="y" - elif [ "x${arg}" == "x-t" ] - then - nexttemp="y" - elif [ "x${arg}" == "x-b" ] - then - nextbg="y" - else - echo "Not sure what you mean..." - echo "Argument ${n} (${arg}) doesn't make sense!" - exit 91 - fi - done -fi -#------------------------------------------------------------------------------------------# - - -bad=0 - - -#------------------------------------------------------------------------------------------# -# Check that soil texture makes sense. # -#------------------------------------------------------------------------------------------# -case ${istext} in -2|stext02) - stext="stext02" - ;; -6|stext06) - stext="stext06" - ;; -8|stext08) - stext="stext08" - ;; -11|stext11) - stext="stext11" - ;; -16|stext16) - stext="stext16" - ;; -*) - echo "Invalid 'stext' argument (${istext})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that temperature makes sense. # -#------------------------------------------------------------------------------------------# -case ${itemp} in -0|"t+000") - temp="t+000" - idxtemp="1" - ;; -1|"t+100") - temp="t+100" - idxtemp="2" - ;; -2|"t+200") - temp="t+200" - idxtemp="3" - ;; -3|"t+300") - temp="t+300" - idxtemp="4" - ;; -*) - echo "Invalid 'temp' argument (${itemp})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that rainfall makes sense. # -#------------------------------------------------------------------------------------------# -case ${irain} in -0|00|"r+000") - rain="r+000" - ;; -2|02|"r-020") - rain="r-020" - ;; -4|04|"r-040") - rain="r-040" - ;; -6|06|"r-060") - rain="r-060" - ;; -8|08|"r-080") - rain="r-080" - ;; -10|"r-100") - rain="r-100" - ;; -12|"r-120") - rain="r-120" - ;; -14|"r-140") - rain="r-140" - ;; -16|"r-160") - rain="r-160" - ;; -*) - echo "Invalid 'rain' argument (${irain})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that ibackground makes sense. # -#------------------------------------------------------------------------------------------# - -case ${ibg} in -0) - bg="ibg00" - ;; -1) - bg="ibg01" - ;; -2) - bg="ibg02" - ;; -*) - echo "Invalid 'bg' argument (${ibg})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Stop in case anything is wrongly set. # -#------------------------------------------------------------------------------------------# -if [ ${bad} -gt 0 ] -then - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Create a unique job name. # -#------------------------------------------------------------------------------------------# -job="cscen_${stext}_${rain}_${temp}_${bg}" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Define some R-related settings. # -#------------------------------------------------------------------------------------------# -R_Comm="R CMD BATCH --no-save --no-restore" -R_Out="${here}/.${job}_out.out" -R_Orig="${here}/compare_scenarios.r" -R_Submit="${here}/.${job}.r" -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Switch settings to the current configuration. # -#------------------------------------------------------------------------------------------# -/bin/cp ${R_Orig} ${R_Submit} -stext_ostr=$(grep stext.default ${R_Submit} | head -1) -temp_ostr=$(grep use.global ${R_Submit} | head -1) -rain_ostr=$(grep drain.default ${R_Submit} | head -1) -bg_ostr=$(grep ibackground ${R_Submit} | head -1) -rdata_ostr=$(grep rdata.path ${R_Submit} | head -1) - -stext_nstr="stext.default = \"${stext}\" # Default soil texture" -temp_nstr="use.global = ${idxtemp} # Which global to use (TRUE means all of them)" -rain_nstr="drain.default = \"${rain}\" # Default rainfall scenario" -bg_nstr="ibackground = ${ibg} # Target background colour:" -rdata_nstr="rdata.path = file.path(here,\"${rdata}\") # Path with R object." -sed -i s@"${stext_ostr}"@"${stext_nstr}"@g ${R_Submit} -sed -i s@"${rain_ostr}"@"${rain_nstr}"@g ${R_Submit} -sed -i s@"${temp_ostr}"@"${temp_nstr}"@g ${R_Submit} -sed -i s@"${bg_ostr}"@"${bg_nstr}"@g ${R_Submit} -sed -i s@"${rdata_ostr}"@"${rdata_nstr}"@g ${R_Submit} -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Create the script to submit to LSF. # -#------------------------------------------------------------------------------------------# -cspost="${here}/.${job}.sh" -csout="${here}/.${job}_lsf.out" -cscomm="${R_Comm} ${R_Submit} ${R_Out}" -status="${here}/${rdata}/status_stext_sim_${temp}.txt" -echo "#!/bin/bash" > ${cspost} -echo "/bin/rm -fr ${status}" >> ${cspost} -echo "while [ ! -s ${status} ]" >> ${cspost} -echo "do" >> ${cspost} -echo " sleep 3" >> ${cspost} -echo " ${cscomm}" >> ${cspost} -echo "done" >> ${cspost} -chmod +x ${cspost} -#------------------------------------------------------------------------------------------# - - - - -#------ Check whether to use openlava or LSF. ---------------------------------------------# -if [ 'x'${openlava} == 'xy' ] || [ 'x'${openlava} == 'xY' ] -then - bcall="iobsub -J ${job} -o ${csout}" -else - bcall="bsub -q ${thisqueue} -J ${job} -o ${csout}" -fi -bsub="${bcall} ${cspost} 1> /dev/null 2> /dev/null" -${bsub} -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/delall.sh b/ED/Template/scripts/PBS/delall.sh deleted file mode 100755 index 8718b930a..000000000 --- a/ED/Template/scripts/PBS/delall.sh +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure that you want to remove all files and directories? [y/N]" -else - echo "Are you sure that you want to remove all files? [y/N]" -fi -read proceed -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -echo " " -if [ "x${1}" == "x-d" ] -then - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output directories and files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -else - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -fi - -echo "This is PERMANENT, once they are gone, adieu, no chance to recover them!" -echo "Is that what you really want? [y/N]" -read proceed - -echo " " - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later do not say that I did not warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Deletion will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/epost.sh b/ED/Template/scripts/PBS/epost.sh index 808fe44b4..0e87dcabf 100755 --- a/ED/Template/scripts/PBS/epost.sh +++ b/ED/Template/scripts/PBS/epost.sh @@ -62,39 +62,47 @@ global_queue="" # Queue sim_memory=0 # Memory per simulation. If zero, then it will be # automatically determined by the maximum number of tasks # per node. +skip_end=true # Skip processing in case the R script has already loaded + # all files through the end of the simulation + # (true/false). This is only used for "monthly"-based + # scripts (those marked with (*) in the table below). #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# # Which scripts to run. # # # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # +# - read_monthly.r - (*) This reads the monthly mean files (results can then be used # +# for plot_monthly.r, plot_yearly.r, and others, but it doesn't plot # +# anything.) # +# - yearly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - monthly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - plot_monthly.r - (*) This creates several plots based on the monthly mean output. # +# - plot_yearly.r - (*) This creates plots with year time series. # +# - plot_ycomp.r - (*) This creates yearly comparisons based on the monthly mean # +# output. # +# - plot_povray.r - (*) This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # # # # The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what # +# caused the step to be rejected. # #------------------------------------------------------------------------------------------# rscripts="plot_yearly.r" #rscripts="yearly_ascii.r" @@ -159,7 +167,7 @@ monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late #------------------------------------------------------------------------------------------# # First check that the main path and e-mail have been set. If not, don't run. # #------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${global_queue}" == "x" ] || [ "x${rscript}" == "x" ] +if [[ "x${here}" == "x" ]] || [[ "x${global_queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] then echo " You must set some variables before running the script:" echo " Check variables \"here\", \"global_queue\" and \"rscript\"!" @@ -169,7 +177,7 @@ fi #----- Load settings. ---------------------------------------------------------------------# -if [ -s ${initrc} ] +if [[ -s ${initrc} ]] then . ${initrc} fi @@ -237,7 +245,7 @@ au*|ha*) #---------------------------------------------------------------------------------------# ;; esac -if [ ${n_cpt} -gt ${n_cpt_max} ] +if [[ ${n_cpt} -gt ${n_cpt_max} ]] then echo " Too many CPUs per task requested:" echo " Queue = ${global_queue}" @@ -276,6 +284,9 @@ read_monthly.r) yearly_ascii.r) epostkey="yasc" ;; +monthly_ascii.r) + epostkey="masc" + ;; r10_monthly.r) epostkey="rm10" ;; @@ -329,7 +340,7 @@ plot_fast.r) # If the script is here, then it could not find the script... And this should never # # happen, so interrupt the script! # #---------------------------------------------------------------------------------------# - echo " Script ${script} is not recognised by epost.sh!" + echo " Script ${rscript} is not recognised by epost.sh!" exit 1 #---------------------------------------------------------------------------------------# ;; @@ -342,18 +353,18 @@ esac #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_tpn} let node_memory=${n_tpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 else #------ Set memory and number of CPUs per task. ----------------------------------------# let n_tpn_try=${node_memory}/${sim_memory} - if [ ${n_tpn_try} -le ${n_tpn} ] + if [[ ${n_tpn_try} -le ${n_tpn} ]] then n_tpn=${n_tpn_try} let sim_memory=${node_memory}/${n_tpn} @@ -367,13 +378,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -390,7 +401,7 @@ echo "Number of polygons: ${npolys}..." # Loop over all polygons. # #------------------------------------------------------------------------------------------# ff=0 -while [ ${ff} -lt ${npolys} ] +while [[ ${ff} -lt ${npolys} ]] do #---------------------------------------------------------------------------------------# @@ -410,128 +421,144 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #------ Last month and year for monthly-based scripts. ---------------------------------# + if [[ ${monthz} -eq 1 ]] + then + rm_monthz=12 + let rm_yearz=${yearz}-1 + else + let rm_monthz=${monthz}-1 + rm_yearz=${yearz} + fi + #------ Update the time. ---------------------------------------------------------------# + let rm_whenz=12*${rm_yearz}+${rm_monthz} #---------------------------------------------------------------------------------------# @@ -667,11 +694,11 @@ do #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] + if [[ ${useperiod} == "f" ]] then metcyca=${eftyeara} metcycz=${eftyearz} - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then metcyca=${bioyeara} metcycz=${bioyearz} @@ -683,7 +710,7 @@ do #---------------------------------------------------------------------------------------# # Switch years in case this is a specific drought run. # #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] + if [[ ${droughtmark} == "TRUE" ]] then let yeara=${droughtyeara}-1 let yearz=${droughtyearz}+1 @@ -692,32 +719,21 @@ do - #----- Print a banner. -----------------------------------------------------------------# - if [ ${rscript} == "plot_census.r" ] && [ ${subcens} -eq 0 ] - then - echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." - else - echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." - fi - #---------------------------------------------------------------------------------------# - - - #---------------------------------------------------------------------------------------# # Set up the time and output variables according to the script. # #---------------------------------------------------------------------------------------# case ${rscript} in - read_monthly.r|yearly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) + read_monthly.r|yearly_ascii.r|monthly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) #------------------------------------------------------------------------------------# # Scripts that are based on monthly means. The set up is the same, the only # # difference is in the output names. # #------------------------------------------------------------------------------------# #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] + if [[ ${useperiod} == "t" ]] then #------ One meteorological cycle. Check the type of meteorological driver. ------# case ${metdriver} in - Sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) thisyeara=${metcyca} thisyearz=${metcycz} ;; @@ -730,34 +746,34 @@ do thisyearz=${metcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then echo " -> Shifting met cycle" let metcycle=${metcycz}-${metcyca}+1 let deltayr=${shiftcycle}*${metcycle} let thisyeara=${metcyca}+${deltayr} let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} ;; esac # ${metdriver} in #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "u" ] + elif [[ ${useperiod} == "u" ]] then #----- The user said which period to use. ----------------------------------------# thisyeara=${yusera} thisyearz=${yuserz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "f" ] + elif [[ ${useperiod} == "f" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${eftyeara} thisyearz=${eftyearz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${bioyeara} @@ -769,7 +785,7 @@ do thisyeara=${yeara} thisyearz=${yearz} #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] + fi # end [[ ${useperiod} == "t" ]] #------------------------------------------------------------------------------------# @@ -779,6 +795,53 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Check whether or not to submit the task. -------------------------------------# + if [[ ${rscript} == "plot_census.r" ]] && [[ ${subcens} -eq 0 ]] + then + #---- No need to submit the job if plot_census.r and place doesn't have census. --# + submit_now=false + #---------------------------------------------------------------------------------# + elif ${skip_end} + then + status="${here}/${polyname}/rdata_month/status_${polyname}.txt" + if [[ -s ${status} ]] + then + #----- Retrieve current status of the post-processing. ------------------------# + st_yearz=$(cat ${status} | awk '{print $1}') + st_monthz=$(cat ${status} | awk '{print $2}') + let st_whenz=12*${st_yearz}+${st_monthz} + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # Compare the processed time with the last time needed for processing. # + #------------------------------------------------------------------------------# + if [[ ${st_whenz} -ge ${rm_whenz} ]] + then + #----- Skip submission because it has reached the end. ---------------------# + submit_now=false + #---------------------------------------------------------------------------# + else + #----- Run script as it has not reached the end yet. -----------------------# + submit_now=true + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + else + #----- File not find, run the script. -----------------------------------------# + submit_now=true + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + else + #----- Submit job. ---------------------------------------------------------------# + submit_now=true + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# ;; plot_eval_ed.r) #------------------------------------------------------------------------------------# @@ -786,7 +849,7 @@ do # Petrolina (output variables exist only for 2004, so we don't need to process # # all years). # #------------------------------------------------------------------------------------# - if [ ${metdriver} == "Petrolina" ] + if [[ ${metdriver} == "Petrolina" ]] then thismetcyca=2004 thismetcycz=2004 @@ -806,7 +869,7 @@ do thisyearz=${thismetcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then #----- Always use the true met driver to find the cycle shift. ----------------# echo " -> Shifting met cycle" @@ -815,7 +878,7 @@ do let thisyeara=${thismetcyca}+${deltayr} let thisyearz=${thismetcycz}+${deltayr} #------------------------------------------------------------------------------# - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} #------------------------------------------------------------------------------------# @@ -826,6 +889,12 @@ do thismonthz=12 thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_budget.r|plot_rk4.r|plot_rk4pc.r|plot_photo.r|reject_ed.r) @@ -835,7 +904,7 @@ do # at the first time step), so we normally skip the first day. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -852,6 +921,12 @@ do thismonthz=${monthz} let thisdatea=${datea}+1 #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; @@ -860,7 +935,7 @@ do # Script with time-independent patch properties. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -877,13 +952,19 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_daily.r) #------------------------------------------------------------------------------------# # Script with daily means. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -900,6 +981,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_fast.r) @@ -907,7 +994,7 @@ do # Script with short-term averages (usually hourly). No need to skip any- # # thing. # #------------------------------------------------------------------------------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -924,6 +1011,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -984,8 +1077,14 @@ do #----- Make sure this is not the census script for a site we don't have census. --------# - if [ ${rscript} != "plot_census.r" ] || [ ${subcens} -ne 0 ] + if ${submit_now} then + #----- Submit script. ---------------------------------------------------------------# + echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." + #------------------------------------------------------------------------------------# + + + #----- Set script- and site-specific variables. -------------------------------------# epostjob="${epostkey}-${desc}-${polyname}" epostnow="${here}/${polyname}/${epostkey}_epost.sh" @@ -1017,7 +1116,7 @@ do case ${rscript} in plot_eval_ed.r) echo "/bin/rm -fr ${complete}" >> ${epostnow} - echo "while [ ! -s ${complete} ]" >> ${epostnow} + echo "while [[ ! -s ${complete} ]" >> ${epostnow} echo "do" >> ${epostnow} echo " sleep 3" >> ${epostnow} echo " ${epostexe}" >> ${epostnow} @@ -1065,7 +1164,7 @@ do if [[ ${nfail} -gt 0 ]] && [[ ${attempt} -eq ${nsubtry_max} ]] then echo " Failed. Giving up, check for errors in your script." - elif [ ${nfail} -eq 0 ] + elif [[ ${nfail} -eq 0 ]] then echo " Success." else @@ -1078,6 +1177,10 @@ do ;; esac #------------------------------------------------------------------------------------# + else + #----- Skip submission. -------------------------------------------------------------# + echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/last_histo.sh b/ED/Template/scripts/PBS/last_histo.sh deleted file mode 100755 index 4efd50824..000000000 --- a/ED/Template/scripts/PBS/last_histo.sh +++ /dev/null @@ -1,516 +0,0 @@ -#!/bin/bash -. ~/.bashrc - -#==========================================================================================# -#==========================================================================================# -# This script keeps only the latest few history files (in case it needs to resume the # -# simulation), and compresses analysis files. # -#------------------------------------------------------------------------------------------# -here="" # Main path -diskthere="" # Disk where the output files are -joborder="${here}/joborder.txt" # File with the job instructions -bzip2="/bin/gzip -9" # Program to compress files (with options) -checkhourly="y" # Check hourly files. -checkstatus="y" # Check status before compressing -#------ Calculator. -----------------------------------------------------------------------# -ccc="${HOME}/Util/calc.sh" # Calculator -#------ # of history files to keep (in odyssey's world, always keep more than one). -------# -retain=3 -#------------------------------------------------------------------------------------------# - - - - -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -# No need to change anything beyond this point unless you are developing the code. # -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# - - - -#------------------------------------------------------------------------------------------# -# Set the maximum number of days for each month. day[0] is a dummy variable. # -#------------------------------------------------------------------------------------------# -daymax=(0 31 28 31 30 31 30 31 31 30 31 30 31) -#------------------------------------------------------------------------------------------# - - - -#----- This script is normally ran with crontab. Make sure the main path is set. ---------# -if [ "x${here}" == "x" ] -then - echo " here = ${here} " - echo " Set up variable here before running email_reset.sh" - exit 92 -fi -#------------------------------------------------------------------------------------------# - - - -#-----Make sure last_histo.sh isn't running. ----------------------------------------------# -if [ -s ${here}/last_histo.lock ] -then - exit -else - echo "I'm going to clean or compress files. Lots of them!" > ${here}/last_histo.lock -fi -#------------------------------------------------------------------------------------------# - - - -#----- Make yes/no choices case insensitive. ----------------------------------------------# -checkhourly=$(echo ${checkhourly} | awk '{print substr($1,1,1)}' | tr '[:upper:]' '[:lower:]') -checkstatus=$(echo ${checkstatus} | awk '{print substr($1,1,1)}' | tr '[:upper:]' '[:lower:]') -#------------------------------------------------------------------------------------------# - - -#----- Find the disk here to create the "there" path. -------------------------------------# -moi=$(whoami) -namehere=$(basename ${here}) -diskhere=$(dirname ${here}) -while [ ${namehere} != ${moi} ] -do - namehere=$(basename ${diskhere}) - diskhere=$(dirname ${diskhere}) -done -if [ "x${diskthere}" == "x" ] -then - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -echo "Number of polygons: ${npolys}..." -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #--------------------------------------------------------------------------------------- - - - #----- Find time and minute. -----------------------------------------------------------# - houra=$(echo ${timea} | awk '{print substr($1,1,2)}') - minua=$(echo ${timea} | awk '{print substr($1,3,2)}') - hourz=$(echo ${timez} | awk '{print substr($1,1,2)}') - minuz=$(echo ${timez} | awk '{print substr($1,3,2)}') - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Set gfilout prefix according to ihrzrad. # - #---------------------------------------------------------------------------------------# - case ${ihrzrad} in - 1) - gpref="gap" - ;; - 2) - gpref="pix" - ;; - *) - gpref="dum" - ;; - esac - #---------------------------------------------------------------------------------------# - - - #----- Define the main path for this polygon. ------------------------------------------# - pypath="${there}/${polyname}" - sfilout="${pypath}/histo/${polyname}" - ffilout="${pypath}/analy/${polyname}" - gfilout="${pypath}/shade/${gpref}" - #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # If the directory exists, delete all history files but the last. # - #---------------------------------------------------------------------------------------# - if [ -s ${pypath} ] - then - echo "${ff} - Delete history files for polygon ${polyname}:" - - #---- First we delete all -Z- files. ------------------------------------------------# - nzed=$(/bin/ls -1 ${sfilout}-Z-*h5 2> /dev/null | wc -l) - if [ ${nzed} -gt 0 ] - then - zeds=$(/bin/ls -1 ${sfilout}-Z-*h5 2> /dev/null) - for zed in ${zeds} - do - echo -n " - Delete: $(basename ${zed})..." - /bin/nice /bin/rm -f ${zed} - echo " Gone!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we delete all -S- files except the last ${retain} ones. -------------------# - ness=$(/bin/ls -1 ${sfilout}-S-*h5 2> /dev/null | wc -l) - if [ ${ness} -gt ${retain} ] - then - let head=${ness}-${retain} - esses=$(/bin/ls -1 ${sfilout}-S-*h5 | head -${head}) - for ess in ${esses} - do - echo -n " - Delete: $(basename ${ess})..." - /bin/nice /bin/rm -f ${ess} - echo " Gone!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we compress all raster files except for the last one. ---------------------# - nrst=$(/bin/ls -1 ${gfilout}_raster_isi001_????-01.txt 2> /dev/null | wc -l) - if [ ${nrst} -gt 1 ] - then - let head=${nrst}-1 - rasters=$(/bin/ls -1 ${gfilout}_raster_isi001_????-01.txt | head -${head}) - for rst in ${rasters} - do - echo -n " - Compress: $(basename ${rst})..." - ${bzip2} ${rst} - echo " Compressed!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we compress all ptable files except for the last one. ---------------------# - nptb=$(/bin/ls -1 ${gfilout}_ptable_isi001_????-01.txt 2> /dev/null | wc -l) - if [ ${nptb} -gt 1 ] - then - let head=${nptb}-1 - ptables=$(/bin/ls -1 ${gfilout}_ptable_isi001_????-01.txt | head -${head}) - for ptb in ${ptables} - do - echo -n " - Compress: $(basename ${ptb})..." - ${bzip2} ${ptb} - echo " Compressed!" - done - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Decide whether to check the status before compressing files. # - #------------------------------------------------------------------------------------# - status="${pypath}/rdata_month/status_${polyname}.txt" - - #----- Check the status before compressing?. ----------------------------------------# - if [ "x${checkstatus}" == "xy" ] - then - #----- Check status of read_monthly.sh. ------------------------------------------# - if [ -s ${status} ] - then - #----- Compress files until the last processed file. --------------------------# - yeare=$(cat ${status} | awk '{print $1}') - monthe=$(cat ${status} | awk '{print $2}') - compress="y" - #------------------------------------------------------------------------------# - else - #----- Do not compress any file. ----------------------------------------------# - compress="n" - #------------------------------------------------------------------------------# - fi - #---------------------------------------------------------------------------------# - else - #----- Ignore checks, just go on and compress everything. ------------------------# - yeare=${yearz} - monthe=${monthz} - compress="y" - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - - - - - #------------------------------------------------------------------------------------# - # If compress is "y", then go on and compress files. # - #------------------------------------------------------------------------------------# - if [ "x${compress}" == "xy" ] - then - let year=${yeara}-1 - - - #---------------------------------------------------------------------------------# - # Loop over the years. # - #---------------------------------------------------------------------------------# - while [ ${year} -lt ${yeare} ] - do - #----- Update year and year string. -------------------------------------------# - let year=${year}+1 - yyyy=$(printf "%4.4i" ${year}) - #------------------------------------------------------------------------------# - - #----- Update daymax for February (check for leap year). ----------------------# - let leap400=${year}%400 - let leap100=${year}%100 - let leap004=${year}%4 - if [ ${leap400} -eq 0 ] || [ ${leap100} -ne 0 -a ${leap004} -eq 0 ] - then - daymax[2]=29 - else - daymax[2]=28 - fi - #------------------------------------------------------------------------------# - - - - - #------ Check last month. -----------------------------------------------------# - if [ ${year} -eq ${yeare} ] - then - monthl=${monthe} - else - monthl=12 - fi - #------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------# - # Loop over the months. # - #------------------------------------------------------------------------------# - month=0 - while [ ${month} -lt ${monthl} ] - do - #----- Update month and month string. --------------------------------------# - let month=${month}+1 - mm=$(printf "%2.2i" ${month}) - datel=${daymax[${month}]} - #---------------------------------------------------------------------------# - - - #----- Compress monthly mean file. -----------------------------------------# - qfile=${ffilout}-Q-${yyyy}-${mm}-00-000000-g01.h5 - if [ -s ${qfile} ] - then - echo -n " - Compress file: $(basename ${qfile})..." - ${bzip2} ${qfile} 2> /dev/null - echo "Zipped!" - fi - #---------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------# - # Check hourly files. # - #---------------------------------------------------------------------------# - if [ "x${checkhourly}" == "xy" ] || [ "x${checkhourly}" == "xY" ] - then - - echo " - Check hourly files: ${mm}/${yyyy}" - - - #------------------------------------------------------------------------# - # Loop over days. # - #------------------------------------------------------------------------# - date=0 - while [ ${date} -lt ${datel} ] - do - let date=${date}+1 - dd=$(printf "%2.2i" ${date}) - hourl=23 - hour=-1 - #---------------------------------------------------------------------# - # Loop over hours. # - #---------------------------------------------------------------------# - while [ ${hour} -lt ${hourl} ] - do - let hour=${hour}+1 - hh=$(printf "%2.2i" ${hour}) - - ifile=${ffilout}-I-${yyyy}-${mm}-${dd}-${hh}0000-g01.h5 - if [ -s ${ifile} ] - then - echo -n " * Compress file: $(basename ${ifile})..." - ${bzip2} ${ifile} 2> /dev/null - echo "Zipped!" - fi - #------------------------------------------------------------------# - done - #---------------------------------------------------------------------# - done - #------------------------------------------------------------------------# - fi - #---------------------------------------------------------------------------# - done - #------------------------------------------------------------------------------# - done - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - else - echo "${ff} - Directory doesn't exist" - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Keep this as the very last command. Release the directory, so last_histo.sh can # -# be called again. # -#------------------------------------------------------------------------------------------# -/bin/rm -f ${here}/last_histo.lock -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/read_monthly.sh b/ED/Template/scripts/PBS/read_monthly.sh deleted file mode 100755 index fb4f21a48..000000000 --- a/ED/Template/scripts/PBS/read_monthly.sh +++ /dev/null @@ -1,807 +0,0 @@ -#!/bin/bash -. ~/.bashrc -here="xxxxxxxxxxxxxxxxxxxxx" # ! Main path -myself=$(whoami) # ! You -diskthere="" # ! Disk where the output files are -thisqueue="qqqqqqqqqq" # ! Queue where jobs should be submitted -joborder="${here}/joborder.txt" # ! File with the job instructions -#----- Outroot is the main output directory. ----------------------------------------------# -outroot="xxxxxxxxxxxxxxxxxxxx" -submit="y" # y = Submit the script; n = Copy the script -#----- Plot only one meteorological cycle. ------------------------------------------------# -useperiod="a" # Which bounds should I use? (Ignored by plot_eval_ed.r) - # "a" -- All period - # "t" -- One eddy flux tower met cycle - # "u" -- User defined period, defined by the variables below. - # "f" -- Force the tower cycle. You may need to edit the script, though -yusera=1972 # First year to use -yuserz=2011 # Last year to use -#----- Yearly comparison . ----------------------------------------------------------------# -seasonmona=1 -#----- Census comparison. -----------------------------------------------------------------# -varcycle="FALSE" # Find the average mortality for various cycles (TRUE/FALSE). -#----- Hourly comparison. -----------------------------------------------------------------# -usedistrib="edf" # Which distribution to plot on top of histograms: - # norm -- Normal distribution - # sn -- Skewed normal distribution (requires package sn) - # edf -- Empirical distribution function (function density) -#----- Output format. ---------------------------------------------------------------------# -outform="c(\"pdf\")" # x11 - On screen (deprecated on shell scripts) - # png - Portable Network Graphics - # eps - Encapsulated Post Script - # pdf - Portable Document Format -#----- DBH classes. -----------------------------------------------------------------------# -idbhtype=3 # Type of DBH class - # 1 -- Every 10 cm until 100cm; > 100cm - # 2 -- 0-10; 10-20; 20-35; 35-50; 50-70; > 70 (cm) - # 3 -- 0-10; 10-35; 35-55; > 55 (cm) -#----- Force to run again from scratch. ---------------------------------------------------# -irerun=0 # Options for re-running: - # 0 -- never; updates only. - # 1 -- re-run only those that have not finished yet - # 2 -- re-run everything, including the finished ones. -#----- Default background colour. ---------------------------------------------------------# -background=0 # 0 -- White - # 1 -- Pitch black - # 2 -- Dark grey -#----- Trim the year comparison for tower years only? -------------------------------------# -efttrim="FALSE" -#----- Correction factor for respiration. -------------------------------------------------# -correct_gs=1.0 # Correction factor for growth and storage respiration -#----- Simple = 1 means that the output is going to be simple. ----------------------------# -simple=0 # 0 -- default - # 1 -- simplified output -#----- Path with R scripts that are useful. -----------------------------------------------# -rscpath="${HOME}/EDBRAMS/R-utils" -#----- bashrc (usually ${HOME}/.bashrc). --------------------------------------------------# -initrc="${HOME}/.bashrc" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Tell whether to plot pseudo-drought or not. # -#------------------------------------------------------------------------------------------# -droughtmark="FALSE" # Should I plot a rectangle to show the drought? - # capital letters only: TRUE means yes, FALSE means no -droughtyeara=1605 # Year that the first drought instance happens (even if it is - # just the last bit) -droughtyearz=1609 # Year that the last drought instance happens (even if it - # partial) -monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late in the - # year, put the last month first. -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Use the general path. # -#------------------------------------------------------------------------------------------# -case ${myself} in -marcosl|marcos.longo|mlongo) - rscpath="${HOME}/Util/Rsc" - ;; -esac -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Make sure the paths are set. # -#------------------------------------------------------------------------------------------# -if [ "y${here}" == "yxxxxxxxxxxxxxxxxxxxxx" ] || [ "y${here}" == "y" ] - [ "y${outroot}" == "yxxxxxxxxxxxxxxxxxxxxx" ] || [ "y${outroot}" == "y" ] - [ "y${thisqueue}" == "yqqqqqqqqqq" ] || [ "y${thisqueue}" == "y" ] -then - echo " here = ${here}" - echo " outroot = ${outroot}" - echo " queue = ${queue}" - echo " Set up variables here, outroot, and queue before using read_monthly.sh!!!" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -lock="${here}/read_monthly.lock" -if [ -s ${lock} ] -then - exit -else - echo "I am going to submit post-processors. Lots of them!" > ${lock} -fi -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Make sure that the directory there exists, if not, create all parent directories # -# needed. # -#------------------------------------------------------------------------------------------# -while [ ! -s ${outroot} ] -do - namecheck=$(basename ${outroot}) - dircheck=$(dirname ${outroot}) - while [ ! -s ${dircheck} ] && [ ${namecheck} != "/" ] - do - namecheck=$(basename ${dircheck}) - dircheck=$(dirname ${dircheck}) - done - - if [ ${namecheck} == "/" ] - then - echo "Invalid disk for variable outroot:" - echo " DISK = ${diskhere}" - exit 58 - elif [ ${namecheck} == "xxxxxxxx" ] || [ ${namecheck} == "xxx_XXX" ] || - [ ${namecheck} == "XXXXXXXXXXX" ] - then - echo " - Found this directory in your path: ${namecheck} ..." - echo " - Outroot given: ${outroot} ..." - echo " - It looks like you forgot to set up your outroot path, check it!" - exit 92 - else - echo "Making directory: ${dircheck}/${namecheck}" - mkdir ${dircheck}/${namecheck} - fi -done -#------------------------------------------------------------------------------------------# - - -#----- Find the disk here to create the "there" path. -------------------------------------# -moi=$(whoami) -namehere=$(basename ${here}) -diskhere=$(dirname ${here}) -while [ ${namehere} != ${moi} ] -do - namehere=$(basename ${diskhere}) - diskhere=$(dirname ${diskhere}) -done -if [ "x${diskthere}" == "x" ] -then - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -echo "Number of polygons: ${npolys}..." -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Set the correct script (full or simple). # -#------------------------------------------------------------------------------------------# -case ${simple} in -0) - read_monthly="read_monthly.r" - rmon="rmon" - rdata_path="rdata_month" - ;; -1) - read_monthly="read_simple.r" - rmon="rsim" - rdata_path="rdata_simple" - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - - #---------------------------------------------------------------------------------------# - # Format count. # - #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] - then - ffout=$(printf '%2.2i' ${ff}) - else - ffout=${ff} - fi - #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #----- Find time and minute. -----------------------------------------------------------# - houra=$(echo ${timea} | awk '{print substr($1,1,2)}') - minua=$(echo ${timea} | awk '{print substr($1,3,2)}') - hourz=$(echo ${timez} | awk '{print substr($1,1,2)}') - minuz=$(echo ${timez} | awk '{print substr($1,3,2)}') - #---------------------------------------------------------------------------------------# - - - #----- Find the last output time. ------------------------------------------------------# - let monthf=${monthz}-1 - if [ ${monthf} == 0 ] - then - monthf=12 - let yearf=${yearz}-1 - else - yearf=${yearz} - fi - #---------------------------------------------------------------------------------------# - - - #----- Retrieve some information from ED2IN. -------------------------------------------# - ED2IN="${here}/${polyname}/ED2IN" - iphysiol=$(grep -i NL%IPHYSIOL ${ED2IN} | awk '{print $3}') - iallom=$(grep -i NL%IALLOM ${ED2IN} | awk '{print $3}') - islhydro=$(grep -i NL%SOIL_HYDRO_SCHEME ${ED2IN} | awk '{print $3}') - metcyca=$(grep -i NL%METCYC1 ${ED2IN} | awk '{print $3}') - metcycz=$(grep -i NL%METCYCF ${ED2IN} | awk '{print $3}') - klight=$(grep -i NL%DDMORT_CONST ${ED2IN} | awk '{print $3}') - #---------------------------------------------------------------------------------------# - - - #---- Find the forest inventory cycle. -------------------------------------------------# - case ${polyiata} in - gyf|s67) - biocyca=2004 - biocycz=2009 - subcens=1 - ;; - s67) - biocyca=2001 - biocycz=2011 - subcens=1 - ;; - *) - biocyca=${metcyca} - biocycz=${metcycz} - subcens=0 - ;; - esac - #---------------------------------------------------------------------------------------# - - - - #---- The eddy flux tower cycles. ------------------------------------------------------# - case ${polyiata} in - gyf) - eftyeara=2004 - eftyearz=2012 - ;; - cax) - eftyeara=1999 - eftyearz=2003 - ;; - l[0-5][0-3]) - eftyeara=2006 - eftyearz=2016 - ;; - m34) - eftyeara=1999 - eftyearz=2006 - ;; - s67) - eftyeara=2001 - eftyearz=2010 - ;; - s77) - eftyeara=2001 - eftyearz=2005 - ;; - s83) - eftyeara=2000 - eftyearz=2003 - ;; - pnz) - eftyeara=2004 - eftyearz=2004 - ;; - ban) - eftyeara=2004 - eftyearz=2006 - ;; - rja) - eftyeara=1999 - eftyearz=2002 - ;; - fns) - eftyeara=1999 - eftyearz=2002 - ;; - bsb) - eftyeara=2006 - eftyearz=2011 - ;; - pdg) - eftyeara=2001 - eftyearz=2003 - ;; - hvd) - eftyeara=1992 - eftyearz=2003 - ;; - *) - eftyeara=${metcyca} - eftyearz=${metcycz} - ;; - esac - #---------------------------------------------------------------------------------------# - - - - #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] - then - metcyca=${eftyeara} - metcycz=${eftyearz} - fi - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Switch years in case this is a specific drought run. # - #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] - then - let yeara=${droughtyeara}-1 - let yearz=${droughtyearz}+1 - fi - #---------------------------------------------------------------------------------------# - - - if [ -s ${here}/${polyname} ] - then - - - #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] - then - #------ One meteorological cycle. Check the type of meteorological driver. ------# - if [ ${metdriver} != "Sheffield" ] - then - thisyeara=${metcyca} - thisyearz=${metcycz} - for i in ${shiftiata} - do - if [ "x${i}" == "x${polyiata}" ] - then - echo " -> Shifting met cycle" - let metcycle=${metcycz}-${metcyca}+1 - let deltayr=${shiftcycle}*${metcycle} - let thisyeara=${metcyca}+${deltayr} - let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] - done #end for i in ${shiftiata} - else - thisyeara=${metcyca} - thisyearz=${metcycz} - fi # end [ ${metdriver} != "Sheffield" ] - #---------------------------------------------------------------------------------# - - elif [ ${useperiod} == "u" ] - then - #----- The user said which period to use. ----------------------------------------# - thisyeara=${yusera} - thisyearz=${yuserz} - #---------------------------------------------------------------------------------# - - elif [ ${useperiod} == "f" ] - then - #----- The user said to use the eddy flux period. --------------------------------# - thisyeara=${eftyeara} - thisyearz=${eftyearz} - #---------------------------------------------------------------------------------# - - else - #----- Grab all years that the simulation is supposed to run. --------------------# - thisyeara=${yeara} - thisyearz=${yearz} - #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] - #------------------------------------------------------------------------------------# - - - - #----- Set up months and days. ------------------------------------------------------# - thismontha=${montha} - thismonthz=${monthz} - thisdatea=${datea} - #------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------# - # Define the job name, and the names of the output files. # - #------------------------------------------------------------------------------------# - epostout="${rmon}_epost.out" - epostsh="${rmon}_epost.sh" - epostlsf="${rmon}_epost.lsf" - epostjob="eb-${rmon}-${polyname}" - #------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------# - # Check the status of the run. # - #------------------------------------------------------------------------------------# - /bin/rm -f ${here}/${polyname}/statusrun.txt - /bin/rm -f ${here}/${polyname}/whichrun.r - /bin/cp -f ${here}/Template/whichrun.r ${here}/${polyname}/whichrun.r - whichrun="${here}/${polyname}/whichrun.r" - outwhich="${here}/${polyname}/outwhichrun.txt" - sed -i s@thispoly@${polyname}@g ${whichrun} - sed -i s@thisqueue@${queue}@g ${whichrun} - sed -i s@pathhere@${here}@g ${whichrun} - sed -i s@paththere@${there}@g ${whichrun} - sed -i s@thisyeara@${yeara}@g ${whichrun} - sed -i s@thismontha@${montha}@g ${whichrun} - sed -i s@thisdatea@${datea}@g ${whichrun} - sed -i s@thistimea@${timea}@g ${whichrun} - sed -i s@thischecksteady@FALSE@g ${whichrun} - sed -i s@thismetcyc1@${metcyc1}@g ${whichrun} - sed -i s@thismetcycf@${metcycf}@g ${whichrun} - sed -i s@thisnyearmin@10000@g ${whichrun} - sed -i s@thisststcrit@0.0@g ${whichrun} - R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - while [ ! -s ${here}/${polyname}/statusrun.txt ] - do - sleep 0.5 - done - year=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $2}') - month=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $3}') - date=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $4}') - time=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $5}') - runt=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $6}') - if [ ${runt} != "INITIAL" ] - then - runt="RESTORE" - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # We submit only the jobs that haven't finished. If the job has just finished, # - # we submit once again, but save a file to remember that this polygon is loaded. # - #------------------------------------------------------------------------------------# - status="${here}/${polyname}/${rdata_path}/status_${polyname}.txt" - rdata="${here}/${polyname}/${rdata_path}/${polyname}.RData" - if [ -s ${status} ] - then - yearl=$(cat ${status} | awk '{print $1}') - monthl=$(cat ${status} | awk '{print $2}') - if [ ${yearl} -eq ${yearf} ] && [ ${monthl} -eq ${monthf} ] - then - cestfini="y" - else - cestfini="n" - fi - lasttime=${monthl}/${yearl} - else - lasttime="Never" - cestfini="n" - fi - #------------------------------------------------------------------------------------# - - - - - #----- Print banner. ----------------------------------------------------------------# - echo " ${fflab} - ${polyname}" - echo " - ED-2.2 Status: ${runt}" - echo " - Last time processed: ${lasttime}. Finished: ${cestfini}" - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Decide whether to change the status to force running again. # - #------------------------------------------------------------------------------------# - case ${irerun} in - 0) - byeprev="n" - ;; - 1) - byeprev="y" - ;; - 2) - cestfini="n" - byeprev="y" - ;; - esac - #------------------------------------------------------------------------------------# - - - if [ ${runt} == "INITIAL" ] - then - submitnow="n" - echo "${ff} - ${polyname} : polygon hasn't started yet" - - elif [ ${runt} == "THE_END" ] && [ ${cestfini} == "y" ] - then - #----- Job has ended and all files have been processed. --------------------------# - submitnow="n" - #---------------------------------------------------------------------------------# - - echo "${ff} - ${polyname} : polygon is already loaded or queued for the last time" - else - #---------------------------------------------------------------------------------# - # Job is still running or it has started again... Remove the blocker and # - # re-submit if the post-processor is not queued. # - #---------------------------------------------------------------------------------# - #----- Check that the script is not in the queue. --------------------------------# - inqueue=$(bjobs -w -q ${thisqueue} -J ${epostjob} 2> /dev/null | wc -l) - if [ ${inqueue} -eq 0 ] - then - submitnow="y" - echo "${ff} - ${polyname}: submit post-processor script." - else - submitnow="n" - echo "${ff} - ${polyname}: post-processor job has already been queued." - fi - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Find out whether the job is on the queue. In case it is not, re-submit. # - #------------------------------------------------------------------------------------# - if [ "x${submitnow}" == "xy" ] - then - #----- Check whether to delete the previous post-processing or not. --------------# - if [ ${byeprev} == "y" ] - then - echo " * Delete previous post-processing..." - /bin/rm -fr ${status} ${rdata} - elif [ -s ${rdata} ] - then - echo " * Continuing previous post-processing..." - else - echo " * Starting new post-processing..." - fi - #---------------------------------------------------------------------------------# - - #----- Copy the R script from the Template folder to the local path. -------------# - cp -f ${here}/Template/${read_monthly} ${here}/${polyname} - scriptnow=${here}/${polyname}/${read_monthly} - #---------------------------------------------------------------------------------# - - - - #----- Switch the keywords by the current settings. ------------------------------# - sed -i s@thispoly@${polyname}@g ${scriptnow} - sed -i s@thisoutroot@${outroot}@g ${scriptnow} - sed -i s@thispath@${here}@g ${scriptnow} - sed -i s@thatpath@${there}@g ${scriptnow} - sed -i s@thisrscpath@${rscpath}@g ${scriptnow} - sed -i s@thisyeara@${thisyeara}@g ${scriptnow} - sed -i s@thismontha@${thismontha}@g ${scriptnow} - sed -i s@thisdatea@${thisdatea}@g ${scriptnow} - sed -i s@thishoura@${houra}@g ${scriptnow} - sed -i s@thisminua@${minua}@g ${scriptnow} - sed -i s@thisyearz@${thisyearz}@g ${scriptnow} - sed -i s@thismonthz@${thismonthz}@g ${scriptnow} - sed -i s@thisdatez@${datez}@g ${scriptnow} - sed -i s@thishourz@${hourz}@g ${scriptnow} - sed -i s@thisminuz@${minuz}@g ${scriptnow} - sed -i s@thisseasonmona@${seasonmona}@g ${scriptnow} - sed -i s@myphysiol@${iphysiol}@g ${scriptnow} - sed -i s@myallom@${iallom}@g ${scriptnow} - sed -i s@myslhydro@${slhydro}@g ${scriptnow} - sed -i s@mydroughtmark@${droughtmark}@g ${scriptnow} - sed -i s@mydroughtyeara@${droughtyeara}@g ${scriptnow} - sed -i s@mydroughtyearz@${droughtyearz}@g ${scriptnow} - sed -i s@mymonthsdrought@${monthsdrought}@g ${scriptnow} - sed -i s@myvarcycle@${varcycle}@g ${scriptnow} - sed -i s@thisoutform@${outform}@g ${scriptnow} - sed -i s@mydistrib@${usedistrib}@g ${scriptnow} - sed -i s@mymetcyca@${metcyca}@g ${scriptnow} - sed -i s@mymetcycz@${metcycz}@g ${scriptnow} - sed -i s@mybiocyca@${biocyca}@g ${scriptnow} - sed -i s@mybiocycz@${biocycz}@g ${scriptnow} - sed -i s@myidbhtype@${idbhtype}@g ${scriptnow} - sed -i s@mybackground@${background}@g ${scriptnow} - sed -i s@mycorrection@${correct_gs}@g ${scriptnow} - sed -i s@myklight@${klight}@g ${scriptnow} - sed -i s@myefttrim@${efttrim}@g ${scriptnow} - sed -i s@myeftyeara@${eftyeara}@g ${scriptnow} - sed -i s@myeftyearz@${eftyearz}@g ${scriptnow} - #---------------------------------------------------------------------------------# - - - - #----- Run R to get the plots. ---------------------------------------------------# - rbin="R CMD BATCH --no-save --no-restore" - comm="${rbin} ${scriptnow} ${here}/${polyname}/${epostout}" - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Create shell script with job instructions. # - #---------------------------------------------------------------------------------# - sbatchout="${here}/${polyname}/${epostlsf}" - epostnow="${here}/${polyname}/${epostsh}" - complete="${here}/${polyname}/eval_load_complete.txt" - rm -f ${epostnow} - echo "#$ -S /bin/bash" > ${epostnow} - echo "#$ -q ${thisqueue}" >> ${epostnow} - echo "#$ -o ${sbatchout}" >> ${epostnow} - echo "#$ -N ${epostjob}" >> ${epostnow} - echo "#$ -j y" >> ${epostnow} - echo "#$ -r n" >> ${epostnow} - echo " " >> ${epostnow} - echo ". ${initrc}" >> ${epostnow} - echo ${comm} >> ${epostnow} - chmod +x ${epostnow} - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Submit the job. # - #---------------------------------------------------------------------------------# - if [ "x${submit}" == "xy" ] || [ "x${submit}" == "xY" ] - then - qsub ${epostnow} 1> /dev/null 2> /dev/null - sleep 3 - fi - #---------------------------------------------------------------------------------# - - fi - #------------------------------------------------------------------------------------# - else - echo "${fflab} - ${polyname}: directory not found." - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - -/bin/rm -f ${lock} - diff --git a/ED/Template/scripts/PBS/reset.sh b/ED/Template/scripts/PBS/reset.sh deleted file mode 100755 index d91253da0..000000000 --- a/ED/Template/scripts/PBS/reset.sh +++ /dev/null @@ -1,424 +0,0 @@ -#!/bin/bash -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -desc=$(basename ${here}) - -#----- Executable name. -------------------------------------------------------------------# -execname="ed_2.2-opt" -execsrc="${HOME}/EDBRAMS/ED/build" -#------------------------------------------------------------------------------------------# - - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# If diskthere is empty, assume diskthere=diskhere. # -#------------------------------------------------------------------------------------------# -if [ "x${diskthere}" == "x" ] -then - diskthere=${diskhere} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Find where stuff to be delete are located. # -#------------------------------------------------------------------------------------------# -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" -else - echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" -fi -read proceed -#------------------------------------------------------------------------------------------# - -#----- Quit in case the user is not sure about. -------------------------------------------# -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs and delete all files!!!" -echo " Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Alright then, but in case you regret later don't say that I didn't warn you..." -echo "I'm giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - #------- Delete jobs. ------------------------------------------------------------------# - jobname="${desc}-${polyname}" - jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') - qdel ${jobid} - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Files will be deleted in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Replace the executable. # -#------------------------------------------------------------------------------------------# -cd ${here} -if [ -s ${here}/executable/${execname} ] -then - rm -frv ${here}/executable/${execname} - cp -fv ${execsrc}/${execname} ${here}/executable -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/sim_sitter.sh b/ED/Template/scripts/PBS/run_sitter.sh similarity index 98% rename from ED/Template/scripts/PBS/sim_sitter.sh rename to ED/Template/scripts/PBS/run_sitter.sh index f3cb01977..161d64e31 100755 --- a/ED/Template/scripts/PBS/sim_sitter.sh +++ b/ED/Template/scripts/PBS/run_sitter.sh @@ -9,6 +9,7 @@ the_end_msg="has finished" unknown_msg="status is unknown" sigsegv_msg="HAD SEGMENTATION VIOLATION" crashed_msg="RK4 PROBLEM" +hydfail_msg="HYDRODYNAMICS" metmiss_msg="DID NOT FIND MET DRIVERS" stopped_msg="UNKNOWN REASON" fstline_msg="Number of polygons:" @@ -65,6 +66,7 @@ do n_unknown=$(cat ${check_out} | grep "${unknown_msg}" | wc -l) n_sigsegv=$(cat ${check_out} | grep "${sigsegv_msg}" | wc -l) n_crashed=$(cat ${check_out} | grep "${crashed_msg}" | wc -l) + n_hydfail=$(cat ${check_out} | grep "${hydfail_msg}" | wc -l) n_metmiss=$(cat ${check_out} | grep "${metmiss_msg}" | wc -l) n_stopped=$(cat ${check_out} | grep "${stopped_msg}" | wc -l) let n_ongoing=${n_polygon}-${n_the_end} diff --git a/ED/Template/scripts/PBS/spawn_poly.sh b/ED/Template/scripts/PBS/spawn_poly.sh index 45cd510bb..6747dbbc2 100755 --- a/ED/Template/scripts/PBS/spawn_poly.sh +++ b/ED/Template/scripts/PBS/spawn_poly.sh @@ -10,6 +10,8 @@ here=$(pwd) moi=$(whoami) #----- Description of this simulation, used to create unique job names. -------------------# desc=$(basename ${here}) +#----- Source path for ED code and executable. --------------------------------------------# +srcpath="${HOME}/EDBRAMS/ED" #----- Select main file system path. ------------------------------------------------------# ordinateur=$(hostname -s) case ${ordinateur} in @@ -23,11 +25,13 @@ bioinit="${fs0}/Data/ed2_data/site_bio_data" alsinit="${fs0}/Data/ed2_data/lidar_spline_bio_data" intinit="${fs0}/Data/ed2_data/lidar_intensity_bio_data" lutinit="${fs0}/Data/ed2_data/lidar_lookup_bio_data" +ebainit="${d_path}/ed2_data/lidar_eba_bio_data" biotype=0 # 0 -- "default" setting (isizepft controls default/nounder) # 1 -- isizepft controls number of PFTs, whereas iage controls patches. # 2 -- airborne lidar initialisation using return counts ("default"). # 3 -- airborne lidar initialisation using intensity counts. # 4 -- airborne lidar/inventory hybrid initialisation ("lookup table"). + # 5 -- airborne lidar (EBA Transects). # For lidar initialisation (2-4), isizepft is the disturbance history key. #----- Path and file prefix for init_mode = 5. --------------------------------------------# restart="${fs0}/Data/ed2_data/restarts_XXX" @@ -39,7 +43,7 @@ shefhead='SHEF_NCEP_DRIVER_DS314' metmaindef="${fs0}/Data/ed2_data" packdatasrc="${fs0}/Data/2scratch" #----- Path with land use scenarios. ------------------------------------------------------# -lumain="${fs0}/Data/lu_scenarios" +lumain="${fs0}/Data/ed2_data/lcluc_scenarios" #----- Path with other input data bases (soil texture, DGD, land mask, etc). --------------# inpmain="${fs0}/Data/ed2_data" #----- If submit is "n", we create paths but skip submission. -----------------------------# @@ -62,13 +66,24 @@ dateh="01" # Day timeh="0000" # Hour #----- Default tolerance. -----------------------------------------------------------------# toldef="0.01" -#----- Executable names. ------------------------------------------------------------------# -execname="ed_2.2-opt" # Normal executable, for most queues #----- Initialisation scripts. ------------------------------------------------------------# -initrc="${HOME}/.bashrc" # Initialisation script for most nodes +initrc="${HOME}/.bashrc" # Initialisation script for most nodes +#----- Executable names. ------------------------------------------------------------------# +execname="ed_2.2-opt" # Normal executable, for most queues +checkexec=true # Check executable #----- Settings for this group of polygons. -----------------------------------------------# -global_queue="verylongq" # Queue -n_cpt=8 # Number of cpus per task (it will be limited by maximum) +init_only=true # Run model initialisation only? + # This can be useful when the initialisation step + # demands much more memory than the time steps (e.g., + # when using lidar data to initialisate the model). +if ${init_only} +then + global_queue="shortq" # Queue + n_cpt=1 # Number of cpus per task (it will be limited by maximum) +else + global_queue="verylongq" # Queue + n_cpt=8 # Number of cpus per task (it will be limited by maximum) +fi #------------------------------------------------------------------------------------------# #==========================================================================================# #==========================================================================================# @@ -138,11 +153,30 @@ echo "Number of polygons: ${npolys}..." # script. # #------------------------------------------------------------------------------------------# exec_full="${here}/executable/${execname}" -if [ ! -s ${exec_full} ] +exec_src="${srcpath}/build/${execname}" +if [[ ! -s ${exec_full} ]] then echo "Executable file : ${exec_full} is not in the executable directory" echo "Copy the executable to the file before running this script!" exit 99 +elif ${checkexec} +then + #----- Check whether the executable is up to date. -------------------------------------# + idiff=$(diff ${exec_full} ${exec_src} 2> /dev/null | wc -l) + if [[ ${idiff} -gt 0 ]] + then + #----- Executable is not up to date, warn user and offer to update it. --------------# + echo "Executable ${exec_full} is not the same as the most recently compiled file." + echo "Most recent: ${exec_src}." + echo "Do you want to update the executable? [y/N]" + read update + update=$(echo ${update} | tr '[:upper:]' '[:lower:]') + case "${update}" in + y*) rsync - Putv ${exec_src} ${exec_full} ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# @@ -238,7 +272,6 @@ echo " Memory per cpu: ${sim_memory}" echo " CPUs per node: ${n_cpn}" echo " CPUs per task: ${n_cpt}" echo " Queue: ${global_queue}" -echo " Job Name: ${jobname}" echo " Total polygon count: ${npolys}" echo " " echo "------------------------------------------------" @@ -267,128 +300,143 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case this is an "init_only" run, impose final time to be the initial time. # + #---------------------------------------------------------------------------------------# + if ${init_only} + then + yearz=${yeara} + monthz=${montha} + datez=${datea} + timez=${timea} + fi #---------------------------------------------------------------------------------------# @@ -465,20 +513,20 @@ do # This step is necessary because we may have killed the run while it was # # writing, and as a result, the file may be corrupt. # #------------------------------------------------------------------------------------# - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) if [ ${nhdf5} -gt 0 ] then h5fine=0 while [ ${h5fine} -eq 0 ] do - lasthdf5=$(ls -1 ${here}/${polyname}/histo/* | tail -1) + lasthdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 | tail -1) h5dump -H ${lasthdf5} 1> /dev/null 2> ${here}/badfile.txt if [ -s ${here}/badfile.txt ] then /bin/rm -fv ${lasthdf5} - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) if [ ${nhdf5} -eq 0 ] then h5fine=1 @@ -531,6 +579,35 @@ do #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Run the small R script to generate specific observation times. # + #---------------------------------------------------------------------------------------# + /bin/rm -f ${here}/${polyname}/gen_obstimes.r + /bin/cp -f ${here}/Template/gen_obstimes.r ${here}/${polyname}/gen_obstimes.r + obstimes="${here}/${polyname}/gen_obstimes.r" + outtimes="${here}/${polyname}/out_obstimes.txt" + sed -i~ s@thispoly@${polyname}@g ${obstimes} + sed -i~ s@thisqueue@${queue}@g ${obstimes} + sed -i~ s@pathhere@${here}@g ${obstimes} + sed -i~ s@paththere@${here}@g ${obstimes} + sed -i~ s@thisyeara@${yeara}@g ${obstimes} + sed -i~ s@thismontha@${montha}@g ${obstimes} + sed -i~ s@thisdatea@${datea}@g ${obstimes} + sed -i~ s@thistimea@${timea}@g ${obstimes} + sed -i~ s@thisyearz@${yearz}@g ${obstimes} + sed -i~ s@thismonthz@${monthz}@g ${obstimes} + sed -i~ s@thisdatez@${datez}@g ${obstimes} + sed -i~ s@thistimez@${timez}@g ${obstimes} + sed -i~ s@thislon@${polylon}@g ${obstimes} + sed -i~ s@thislat@${polylat}@g ${obstimes} + R CMD BATCH --no-save --no-restore ${obstimes} ${outtimes} + while [[ ! -s ${here}/${polyname}/${polyname}_obstimes.txt ]] + do + sleep 0.2 + done + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # This should no longer occur, but it runtype is set to INITIAL, replace it with # @@ -773,6 +850,11 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). -----------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# scentype="ERA_Interim" @@ -823,6 +905,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# scentype="WFDEI" @@ -911,6 +998,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1061,6 +1154,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1098,7 +1197,7 @@ do # Correct years so it is not tower-based or Sheffield. # #---------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) echo "Nothing" > /dev/null ;; *) @@ -1155,6 +1254,12 @@ do ;; esac ;; + sa2-ril) + ludatabase="${lumain}/SimAmazonia2/ril/sa2_ril_" + ;; + sa2-cvl) + ludatabase="${lumain}/SimAmazonia2/cvl/sa2_cvl_" + ;; lurcp26) ludatabase="${lumain}/luh-1.1+rcp26_image/luh-1.1+rcp26_image-" ;; @@ -1274,8 +1379,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-4.032,-3.584,-3.159,-2.757,-2.377,-2.021,-1.689,-1.382,-1.101," - polyslz2="-0.846,-0.620,-0.424,-0.260,-0.130,-0.040" + polyslz1="-5.000,-4.468,-3.963,-3.483,-3.030,-2.604,-2.205,-1.836,-1.495,-1.185," + polyslz2="-0.906,-0.660,-0.447,-0.271,-0.134,-0.040" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1309,6 +1414,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.934,-6.934,-5.999,-5.131,-4.329,-3.593,-2.925,-2.324,-1.790," + polyslz2="-1.325,-0.928,-0.600,-0.342,-0.155,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.223,-8.029,-6.919,-5.891,-4.946,-4.084,-3.305,-2.609,-1.995," polyslz2="-1.464,-1.015,-0.648,-0.364,-0.161,-0.040" @@ -1317,6 +1431,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.51,-9.118,-7.828,-6.640,-5.552,-4.563,-3.674,-2.883,-2.191" + polyslz2="-1.595,-1.096,-0.693,-0.383,-0.166,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -1416,8 +1539,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-3.967,-3.467,-3.000,-2.565,-2.164,-1.797,-1.462,-1.162,-0.895," - polyslz2="-0.662,-0.464,-0.300,-0.171,-0.077,-0.020" + polyslz1="-5.000,-4.397,-3.833,-3.307,-2.819,-2.371,-1.961,-1.590,-1.257,-0.964," + polyslz2="-0.709,-0.493,-0.316,-0.178,-0.080,-0.020" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1451,6 +1574,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.807,-6.706,-5.696,-4.775,-3.942,-3.195,-2.533,-1,954,-1.456," + polyslz2="-1.037,-0.694,-0.424,-0.225,-0.092,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.076,-7.766,-6.569,-5.482,-4.504,-3.631,-2.862,-2.194,-1.622," polyslz2="-1.145,-0.759,-0.458,-0.239,-0.096,-0.020" @@ -1705,7 +1837,7 @@ do #----- Check whether to use SFILIN as restart or history. ------------------------------# - if [ ${runt} == "RESTORE" ] && [ ${forcehisto} -eq 1 ] + if [[ ${runt} == "RESTORE" ]] && [[ ${forcehisto} -eq 1 ]] then runt="HISTORY" year=${yearh} @@ -1713,125 +1845,192 @@ do date=${dateh} time=${timeh} thissfilin=${fullygrown} - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 5 ] + elif [[ ${runt} == "RESTORE" ]] then - if [ ! -s ${restart} ] - then - echo " Directory restart does not exist!" - echo " Change the variable restart at the beginning of the script" - exit 44 - else - runt="RESTORE" - thissfilin=${restart} - fi - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 6 ] - then - thissfilin=${fullygrown} - - - - #------------------------------------------------------------------------------------# - # Find the biometric files. This has been checked in spawn_poly.sh so they are # - # correct. Add a dummy name in case this is not supposed to be a biomass # - # initialisation run. # - #------------------------------------------------------------------------------------# - case ${biotype} in - 0) - #----- isizepft controls everything, and iage is ignored. ------------------------# - case ${isizepft} in - 0) - #----- Frankeinstein's under storey. ------------------------------------------# - thissfilin="${bioinit}/${polyiata}_default." - ;; - 1) - #----- No under storey. -------------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_nounder." - ;; - 2) - #----- ALS initialisation. ----------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_alsinit." - ;; - *) - #----- Invalid option. Stop the script. ---------------------------------------# - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 57 - ;; - esac + case ${initmode} in + 5|7) + #---------------------------------------------------------------------------------# + # Initialise ED2 with hdf5 files, which should be in directory restart. # + #---------------------------------------------------------------------------------# + if [[ ! -s ${restart} ]] + then + echo " Directory restart does not exist!" + echo " Change the variable restart at the beginning of the script" + exit 44 + else + runt="RESTORE" + thissfilin=${restart} + fi #---------------------------------------------------------------------------------# ;; - 1) + 1|2|3|6|8) #---------------------------------------------------------------------------------# - # 'isizepft' controls how many PFTs to use. # + # Find the biometric files. This has been checked in spawn_poly.sh so they # + # are correct. Add a dummy name in case this is not supposed to be a biomass # + # initialisation run. # #---------------------------------------------------------------------------------# - case ${isizepft} in - 0|5) - pftname="pft05" - ;; - 2) - pftname="pft02" + case ${biotype} in + 0) + #----- isizepft controls everything, and iage is ignored. ---------------------# + case ${isizepft} in + 0) + #----- Frankeinstein's under storey. ---------------------------------------# + thissfilin="${bioinit}/${polyiata}_default." + ;; + 1) + #----- No under storey. ----------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_nounder." + ;; + 2) + #----- ALS initialisation. -------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_alsinit." + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initialised with these ISIZEPFT and INITMODE!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------# - # 'iage' controls how many patches to use. # - #---------------------------------------------------------------------------------# - case ${iage} in 1) - agename="age01" + #------------------------------------------------------------------------------# + # 'isizepft' controls how many PFTs to use. # + #------------------------------------------------------------------------------# + case ${isizepft} in + 0|5) + pftname="pft05" + ;; + 2) + pftname="pft02" + ;; + esac + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # 'iage' controls how many patches to use. # + #------------------------------------------------------------------------------# + case ${iage} in + 1) + agename="age01" + ;; + *) + agename="age00" + ;; + esac + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether the site has the PFT and age structure. # + #------------------------------------------------------------------------------# + case ${polyiata} in + hvd|s77|fns|cau|and|par|tap|dcm) + thissfilin="${bioinit}/${polyiata}_default." + ;; + cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) + thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + ;; + *) + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " IAGE: ${iage}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 59 + ;; + esac + #------------------------------------------------------------------------------# ;; - *) - agename="age00" + 2) + #------------------------------------------------------------------------------# + # ALS initialisation. ISIZEPFT has disturbance history information. # + #------------------------------------------------------------------------------# + case ${polyiata} in + l[0-5][0-3]) + thissfilin="${alsinit}/${polyiata}." + ;; + *) + thissfilin="${alsinit}/${polyiata}_${isizepft}." + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - - - - - #---------------------------------------------------------------------------------# - # Check whether the site has the PFT and age structure. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - hvd|s77|fns|cau|and|par|tap|dcm) - thissfilin="${bioinit}/${polyiata}_default." + 3) + #------------------------------------------------------------------------------# + # ALS initialisation using intensity. ISIZEPFT has disturbance history # + # information. # + #------------------------------------------------------------------------------# + thissfilin="${intinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) - thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + 4) + #------------------------------------------------------------------------------# + # ALS initialisation using the lookup table. ISIZEPFT has disturbance # + # history information. # + #------------------------------------------------------------------------------# + thissfilin="${lutinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - *) - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " IAGE: ${iage}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 59 + 5) + #----- isizepft controls actual or majestic initialisation. -------------------# + case ${isizepft} in + 0) + #----- Actual sampling. ----------------------------------------------------# + thissfilin="${ebainit}/eba_actual_default." + #---------------------------------------------------------------------------# + ;; + 1) + #----- Majestic sampling. --------------------------------------------------# + thissfilin="${ebainit}/eba_majestic_default." + #---------------------------------------------------------------------------# + ;; + 2) + #----- Actual sampling + land use (pasture/cropland/plantation). -----------# + thissfilin="${ebainit}/eba_luactual_default." + #---------------------------------------------------------------------------# + ;; + 3) + #----- Majestic sampling + land use (pasture/cropland/plantation). ---------# + thissfilin="${ebainit}/eba_lumajestic_default." + #---------------------------------------------------------------------------# + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------# ;; - 2) - #---------------------------------------------------------------------------------# - # ALS initialisation. ISIZEPFT has disturbance history information. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - l[0-5][0-3]) - thissfilin="${alsinit}/${polyiata}." - ;; - *) - thissfilin="${alsinit}/${polyiata}_${isizepft}." - ;; - esac + *) + #----- No initial file needed; set the history file. -----------------------------# + thissfilin=${here}/${polyname}/histo/${polyname} #---------------------------------------------------------------------------------# ;; + #---------------------------------------------------------------------------------# esac #------------------------------------------------------------------------------------# else + #----- Set the history file. --------------------------------------------------------# thissfilin=${here}/${polyname}/histo/${polyname} + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -1998,6 +2197,7 @@ do sed -i~ s@mydbhharv@${dbhharv}@g ${ED2IN} sed -i~ s@mybioharv@${bioharv}@g ${ED2IN} sed -i~ s@myskidarea@${skidarea}@g ${ED2IN} + sed -i~ s@myskiddbhthresh@${skiddbhthresh}@g ${ED2IN} sed -i~ s@myskidsmall@${skidsmall}@g ${ED2IN} sed -i~ s@myskidlarge@${skidlarge}@g ${ED2IN} sed -i~ s@myfellingsmall@${fellingsmall}@g ${ED2IN} @@ -2081,7 +2281,7 @@ do echo "Polygon population has gone extinct. No need to re-submit it." submit_now=false ;; - "CRASHED"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") + "CRASHED"|"HYDFAIL"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") echo "Polygon has serious errors. Script will not submit the job this time." submit_now=false ;; diff --git a/ED/Template/scripts/PBS/stopalljobs.sh b/ED/Template/scripts/PBS/stopalljobs.sh deleted file mode 100755 index 1aa6e1a85..000000000 --- a/ED/Template/scripts/PBS/stopalljobs.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bash -here=$(pwd) -joborder="${here}/joborder.txt" -desc=$(basename ${here}) - -#----- Determine the number of polygons to stop. ------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 - -echo "Are you sure that you want to stop all jobs? [y/N]" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs... Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Alright then, but in case you regret later don't say that I didn't warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #------- Delete jobs. ------------------------------------------------------------------# - jobname="${desc}-${polyname}" - jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') - qdel ${jobid} - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - - diff --git a/ED/Template/scripts/SLURM/check_run.sh b/ED/Template/scripts/SLURM/check_run.sh index 42ef6ad18..64f209cd3 100755 --- a/ED/Template/scripts/SLURM/check_run.sh +++ b/ED/Template/scripts/SLURM/check_run.sh @@ -2,7 +2,7 @@ here=$(pwd) joborder="${here}/joborder.txt" desc=$(basename ${here}) -jobname="${desc}-sims" +jobname="${desc}-sims*" moi=$(whoami) outform="JobName%200,State%12" #----- Determine the number of polygons to run. -------------------------------------------# @@ -10,6 +10,26 @@ let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 echo "Number of polygons: ${npolys}..." + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*) + cluster="CANNON" + ;; +sdumont*) + cluster="SDUMONT" + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + polya=1 polyz=${npolys} @@ -75,147 +95,184 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. -------------# + taskname="${polyname}" + #------------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. -----------------------# + taskname="${desc}-${polyname}" + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Set some variables to check whether the simulation is running. # #---------------------------------------------------------------------------------------# stdout="${here}/${polyname}/serial_out.out" stderr="${here}/${polyname}/serial_out.err" - lsfout="${here}/${polyname}/serial_lsf.out" skipper="${here}/${polyname}/skipper.txt" #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# # Check whether the simulation is still running, and if not, why it isn't. # #---------------------------------------------------------------------------------------# if [ -s ${stdout} ] then + + #----- Set task inquire command. ----------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Multi-task job, search for specific task. ---------------------------------# + stask="stask --noheader -u ${moi} -t ${taskname} -j ${jobname}" + #---------------------------------------------------------------------------------# + ;; + CANNON) + #----- Single-task jobs, search the task using the job name. ---------------------# + stask="stask --noheader -u ${moi} -j ${taskname}" + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + + #----- Check whether the simulation is running, and when in model time it is. -------# - stask="stask --noheader -u ${moi} -t ${polyname} -j ${jobname}" running=$(${stask} -o "${outform}" | grep "RUNNING" | wc -l) pending=$(${stask} -o "${outform}" | grep "PENDING" | wc -l) suspended=$(${stask} -o "${outform}" | grep "SUSPENDED" | wc -l) @@ -247,9 +304,10 @@ do #----- Check for other possible outcomes. -------------------------------------------# - stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) - crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) - the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) + stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) + crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) + hydfail=$(grep "Plant Hydrodynamics is off-track." ${stdout} | wc -l) + the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) #------------------------------------------------------------------------------------# @@ -271,6 +329,9 @@ do elif [ ${crashed} -gt 0 ] then echo -e "${ffout}: ${polyname} HAS CRASHED (RK4 PROBLEM)... <===========" + elif [ ${hydfail} -gt 0 ] + then + echo -e "${ffout}: ${polyname} HAS CRASHED (HYDRODYNAMICS)... <===========" elif [ ${metmiss} -gt 0 ] then echo -e "${ffout}: ${polyname} DID NOT FIND MET DRIVERS... <===========" diff --git a/ED/Template/scripts/SLURM/clean_scratch.sh b/ED/Template/scripts/SLURM/clean_scratch.sh deleted file mode 100755 index 43766e350..000000000 --- a/ED/Template/scripts/SLURM/clean_scratch.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -myself=$(whoami) - -#----- Check which queue we will clean. ---------------------------------------------------# -if [ "x${1}" == "x" ] -then - echo -n "Which queue do you want to clean?" - read queue -else - queue=${1} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Select the nodes to be deleted. # -#------------------------------------------------------------------------------------------# -case ${queue} in -moorcroft_6100a) - nodes="moorcroft01 moorcroft02 moorcroft03 moorcroft04" - ;; -moorcroft_6100b) - nodes="moorcroft05 moorcroft06 moorcroft07 moorcroft08 moorcroft09 - moorcroft10 moorcroft11 moorcroft12 moorcroft13 moorcroft14 - moorcroft15 moorcroft16 moorcroft17 moorcroft18 moorcroft19 - moorcroft20 moorcroft21 moorcroft22 moorcroft23 moorcroft24 - moorcroft25 moorcroft26 moorcroft27 moorcroft28 moorcroft29 - moorcroft30 moorcroft31 moorcroft32 moorcroft33 moorcroft34 - moorcroft35 moorcroft36 moorcroft37 moorcroft38 moorcroft39 - moorcroft40 moorcroft41 moorcroft42 moorcroft43 moorcroft44" - ;; -moorcroft2a) - nodes="hero4001 hero4002 hero4003 hero4004 hero4005 hero4006 - hero4007 hero4008 hero4009 hero4010 hero4011" - ;; -moorcroft2b) - nodes="hero4014 hero4015 hero4016 hero4101 hero4102 hero4103 - hero4104 hero4105 hero4106 hero4107 hero4108" - ;; -moorcroft2c) - nodes="hero4109 hero4110 hero4111 hero4112 hero4113 hero4114 hero4115 hero4116" - ;; -wofsy) - nodes="wofsy011 wofsy012 wofsy013 wofsy014 wofsy021 wofsy022 wofsy023 wofsy024" - ;; -camd) - nodes="camd04 camd05 camd06 camd07 camd09 camd10 camd11 camd13" - ;; -unrestricted_parallel) - nodes="hero3103 hero3104 hero3107 hero3108 hero3109 hero3110 - hero3111 hero3112 hero3113 hero3114 hero3115 hero3116 - hero3201 hero3202 hero3203 hero3204 hero3205 hero3206 - hero3207 hero3208 hero3209 hero3210 hero3211 hero3212 - hero3213 hero3214 hero3215 hero3216" - ;; -unrestricted_serial) - nodes="hero1301 hero1912 soph57 soph58 soph59 soph60 soph61 soph62 soph63 soph64" - ;; -long_serial) - nodes="soph01 soph02 soph03 soph04 soph05 soph06 soph07 soph08 - soph09 soph10 soph11 soph12 soph13 soph14 soph15 soph16 - soph17 soph18 soph19 soph20 soph22 soph23 soph24 soph25 - soph26 soph27 soph28 soph29 soph30 soph31 soph32 soph33 - soph34 soph35 soph36 soph37 soph38 soph39 soph40 soph41 - soph42 soph43 soph44 soph45 soph46 soph47 soph48 soph49 - soph51 soph52 soph53 soph54 soph55 soph56" - ;; -*) - echo " I cannot recognise queue ${queue}..." - exit 39 - ;; -esac -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Delete the files in all nodes that the queue uses. # -#------------------------------------------------------------------------------------------# -for node in ${nodes} -do - echo -n " Scheduling files for deletion - node ${node}..." - ssh ${node} /bin/mv /scratch/${myself} /scratch/goodbye-${myself} 1> /dev/null 2>&1 - ssh ${node} rm -fr /scratch/goodbye-${myself} 1> /dev/null 2>&1 & - echo "Done!" -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/delall.sh b/ED/Template/scripts/SLURM/delall.sh deleted file mode 100755 index d06c12487..000000000 --- a/ED/Template/scripts/SLURM/delall.sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/bash -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -if [ "x${diskthere}" == "x" ] -then - diskthere=${diskhere} - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure that you want to remove all files and directories? [y/N]" -else - echo "Are you sure that you want to remove all files? [y/N]" -fi -read proceed -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -echo " " -if [ "x${1}" == "x-d" ] -then - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output directories and files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -else - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -fi - -echo "This is PERMANENT, once they are gone, adieu, no chance to recover them!" -echo "Is that what you really want? [y/N]" -read proceed - -echo " " - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later do not say that I did not warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Deletion will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/epost.sh b/ED/Template/scripts/SLURM/epost.sh index 7159f9c09..f0c0c8163 100755 --- a/ED/Template/scripts/SLURM/epost.sh +++ b/ED/Template/scripts/SLURM/epost.sh @@ -67,8 +67,14 @@ optsrc="-n" # Option for .bashrc (for special submission setti # In case none is needed, leave it blank (""). #----- Settings for this group of polygons. -----------------------------------------------# global_queue="" # Queue +reservation="" # Reservation +overcommit="" # Ignore maximum task limit for partition? (true/false) partial=false # Partial submission (false will ignore polya and npartial # and send all polygons. +skip_end=true # Skip processing in case the R script has already loaded + # all files through the end of the simulation + # (true/false). This is only used for "monthly"-based + # scripts (those marked with (*) in the table below). polya=501 # First polygon to submit npartial=100 # Maximum number of polygons to include in this bundle # (actual number will be adjusted for total number of @@ -84,35 +90,39 @@ runtime="00:00:00" # Simulation time in hours. If zero, then it will #------------------------------------------------------------------------------------------# -# Which script to run (multiple scripts are not allowed). # +# Which scripts to run. # # # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # +# - read_monthly.r - (*) This reads the monthly mean files (results can then be used # +# for plot_monthly.r, plot_yearly.r, and others, but it doesn't plot # +# anything.) # +# - yearly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - monthly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - plot_monthly.r - (*) This creates several plots based on the monthly mean output. # +# - plot_yearly.r - (*) This creates plots with year time series. # +# - plot_ycomp.r - (*) This creates yearly comparisons based on the monthly mean # +# output. # +# - plot_povray.r - (*) This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # # # # The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what # +# caused the step to be rejected. # #------------------------------------------------------------------------------------------# rscript="" #rscript="yearly_ascii.r" @@ -177,7 +187,7 @@ monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late #------------------------------------------------------------------------------------------# # First check that the main path and e-mail have been set. If not, don't run. # #------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${global_queue}" == "x" ] || [ "x${rscript}" == "x" ] +if [[ "x${here}" == "x" ]] || [[ "x${global_queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] then echo " You must set some variables before running the script:" echo " Check variables \"here\", \"global_queue\" and \"rscript\"!" @@ -187,85 +197,37 @@ fi #----- Load settings. ---------------------------------------------------------------------# -if [ -s ${initrc} ] +if [[ -s ${initrc} ]] then . ${initrc} fi #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Configurations depend on the global_queue. # -#------------------------------------------------------------------------------------------# -case ${ordinateur} in +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in rclogin*|holy*|moorcroft*|rcnx*) - #----- Odyssey queues. -----------------------------------------------------------------# - case ${global_queue} in - "general") - n_nodes_max=166 - n_cpt=1 - n_tpn=32 - runtime_max="7-00:00:00" - node_memory=262499 - ;; - "shared,huce_intel"|"huce_intel,shared") - n_nodes_max=276 - n_cpt=1 - n_tpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared") - n_nodes_max=456 - n_cpt=1 - n_tpn=48 - runtime_max="7-00:00:00" - node_memory=192892 - ;; - "huce_intel") - n_nodes_max=276 - n_cpt=1 - n_tpn=24 - runtime_max="14-00:00:00" - node_memory=126820 - ;; - "huce_amd") - n_nodes_max=65 - n_cpt=1 - n_tpn=32 - runtime_max="14-00:00:00" - node_memory=262499 - ;; - "moorcroft_amd") - n_nodes_max=8 - n_cpt=1 - n_tpn=64 - runtime_max="infinite" - node_memory=256302 - ;; - "moorcroft_6100") - n_nodes_max=35 - n_cpt=1 - n_tpn=12 - runtime_max="infinite" - node_memory=22150 - ;; - "unrestricted") - n_nodes_max=8 - n_cpt=1 - n_tpn=64 - runtime_max="31-00:00:00" - node_memory=262499 - ;; - *) - echo "Global queue ${global_queue} is not recognised!" - exit - ;; - esac - #---------------------------------------------------------------------------------------# + cluster="CANNON" ;; sdumont*) - #----- SantosDumont. -------------------------------------------------------------------# + cluster="SDUMONT" + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Configurations depend on the global_queue and cluster. # +#------------------------------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #----- Set parameters according to partitions. -----------------------------------------# case ${global_queue} in cpu_long|nvidia_long) n_nodes_max=10 @@ -309,13 +271,70 @@ sdumont*) esac #---------------------------------------------------------------------------------------# ;; -*) - #----- Computer is not listed. Crash. -------------------------------------------------# - echo " Invalid computer ${ordinateur}. Check queue settings in the script." - exit 31 +CANNON) + #----- Set parameters according to partitions. -----------------------------------------# + case ${global_queue} in + "commons") + n_nodes_max=5 + n_cpt=1 + n_tpn=32 + runtime_max="14-00:00:00" + node_memory=126820 + ;; + "huce_cascade") + n_nodes_max=30 + n_cpt=1 + n_tpn=48 + runtime_max="14-00:00:00" + node_memory=183240 + ;; + "huce_intel") + n_nodes_max=150 + n_cpt=1 + n_tpn=24 + runtime_max="14-00:00:00" + node_memory=122090 + ;; + "shared,huce_intel"|"huce_intel,shared") + n_nodes_max=150 + n_cpt=1 + n_tpn=24 + runtime_max="7-00:00:00" + node_memory=122090 + ;; + "shared") + n_nodes_max=220 + n_cpt=1 + n_tpn=48 + runtime_max="7-00:00:00" + node_memory=183240 + ;; + "test") + n_nodes_max=9 + n_cpt=1 + n_tpn=48 + runtime_max="8:00:00" + node_memory=183240 + ;; + "unrestricted") + n_nodes_max=4 + n_cpt=1 + n_tpn=48 + runtime_max="infinite" + node_memory=183240 + ;; + *) + echo "Global queue ${global_queue} is not recognised!" + exit + ;; + esac #---------------------------------------------------------------------------------------# ;; esac +#------------------------------------------------------------------------------------------# + + +#----- Set the number of tasks. -----------------------------------------------------------# let n_tasks_max=${n_nodes_max}*${n_tpn} #------------------------------------------------------------------------------------------# @@ -459,6 +478,9 @@ read_monthly.r) yearly_ascii.r) epostkey="yasc" ;; +monthly_ascii.r) + epostkey="masc" + ;; r10_monthly.r) epostkey="rm10" ;; @@ -512,7 +534,7 @@ plot_fast.r) # If the script is here, then it could not find the script... And this should never # # happen, so interrupt the script! # #---------------------------------------------------------------------------------------# - echo " Script ${script} is not recognised by epost.sh!" + echo " Script ${rscript} is not recognised by epost.sh!" exit 1 #---------------------------------------------------------------------------------------# ;; @@ -522,32 +544,21 @@ esac -#----- Set script information. ------------------------------------------------------------# -epoststo="${epostkey}_epost.sto" -epostste="${epostkey}_epost.ste" -epostout="${epostkey}_epost.out" -epostjob="${epostkey}-${desc}" -epostexe="R CMD BATCH --no-save --no-restore ${rscript} ${epostout}" -#------------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_tpn} let node_memory=${n_tpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 else #------ Set memory and number of CPUs per task. ----------------------------------------# let n_tpn_try=${node_memory}/${sim_memory} - if [ ${n_tpn_try} -le ${n_tpn} ] + if [[ ${n_tpn_try} -le ${n_tpn} ]] then n_tpn=${n_tpn_try} let sim_memory=${node_memory}/${n_tpn} @@ -563,13 +574,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -585,7 +596,7 @@ if ${partial} then let ff=${polya}-1 let polyz=${ff}+${npartial} - if [ ${polyz} -gt ${npolys} ] + if [[ ${polyz} -gt ${npolys} ]] then polyz=${npolys} fi @@ -593,6 +604,7 @@ then sbatch="${here}/sub_${rprefix}_${partlabel}.sh" obatch="${here}/out_${rprefix}_${partlabel}.log" ebatch="${here}/err_${rprefix}_${partlabel}.log" + epostjob="${epostkey}-${desc}_${partlabel}" else ff=0 polya=1 @@ -600,91 +612,143 @@ else sbatch="${here}/sub_${rprefix}.sh" obatch="${here}/out_${rprefix}.log" ebatch="${here}/err_${rprefix}.log" + epostjob="${epostkey}-${desc}" fi let ntasks=1+${polyz}-${polya} #------------------------------------------------------------------------------------------# + + #----- Summary for this submission preparation. Then give 5 seconds for user to cancel. --# echo "------------------------------------------------" echo " Submission summary: " echo "" echo " Memory per cpu: ${sim_memory}" echo " Tasks per node: ${n_tpn}" -echo " Queue: ${global_queue}" +echo " Partition: ${global_queue}" echo " Run time: ${runtime}" echo " First polygon: ${polya}" echo " Last polygon: ${polyz}" -echo " Job Name: ${epostjob}" echo " Total polygon count: ${npolys}" echo " " echo " Partial submission: ${partial}" echo " Automatic submission: ${submit}" echo " " echo " R script: ${rscript}" +echo " Submission script: $(basename ${sbatch})" echo "------------------------------------------------" echo "" +echo "" +echo -n " Waiting five seconds before proceeding... " sleep 5 +echo "Done!" #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Initialise executable. # +# Initialise executable. The main executable will have different settings depending # +# on whether this is to be a multi-task single job, or multiple single-task jobs. # #------------------------------------------------------------------------------------------# -rm -fr ${sbatch} -touch ${sbatch} -chmod u+x ${sbatch} -echo "#!/bin/bash" >> ${sbatch} -echo "#SBATCH --ntasks=${ntasks} # Number of tasks" >> ${sbatch} -echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${sbatch} -echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} -echo "#SBATCH --job-name=${epostjob} # Job name" >> ${sbatch} -echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} -echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} -echo "#SBATCH --output=${here}/out_epost.out # Standard output path" >> ${sbatch} -echo "#SBATCH --error=${here}/out_epost.err # Standard error path" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Get plenty of memory." >> ${sbatch} -echo "ulimit -s unlimited" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Initial settings." >> ${sbatch} -echo "here=\"${here}\" # Main path" >> ${sbatch} -echo "rscript=\"${rscript}\" # R Script" >> ${sbatch} -echo "rstdout=\"${epostout}\" # Standard output" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Print information about this job." >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"----- Summary of current job ---------------------------------\"" >> ${sbatch} -echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} -echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} -echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} -echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} -echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} -echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} -echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} -echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} -echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} -echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} -echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Define home in case home is not set" >> ${sbatch} -echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export HOME=\$(echo ~)" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Load modules and settings." >> ${sbatch} -echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Task list." >> ${sbatch} +case "${cluster}" in +SDUMONT) + #----- Initialise script to submit a single multi-task job. ----------------------------# + rm -fr ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "#SBATCH --ntasks=${ntasks} # Number of tasks" >> ${sbatch} + echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${sbatch} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} + if [[ "${reservation}" != "" ]] + then + echo "#SBATCH --reservation=${reservation} # Reserved nodes" >> ${sbatch} + fi + echo "#SBATCH --job-name=${epostjob} # Job name" >> ${sbatch} + echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} + echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "rscript=\"${rscript}\" # R Script" >> ${sbatch} + echo "rstdout=\"${epostout}\" # Standard output" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Print information about this job." >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"----- Summary of current job ------------------------------\"" >> ${sbatch} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} + echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +CANNON) + #----- Initialise script to submit multiple single-task jobs. --------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +esac #------------------------------------------------------------------------------------------# @@ -694,7 +758,7 @@ echo "#----- Task list." > # Loop over all polygons. # #------------------------------------------------------------------------------------------# n_submit=0 -while [ ${ff} -lt ${polyz} ] +while [[ ${ff} -lt ${polyz} ]] do let ff=${ff}+1 let line=${ff}+3 @@ -703,13 +767,13 @@ do #---------------------------------------------------------------------------------------# # Format count. # #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] + if [[ ${npolys} -ge 10 ]] && [[ ${npolys} -lt 100 ]] then ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 1000 ]] then ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 10000 ]] then ffout=$(printf '%4.4i' ${ff}) else @@ -726,128 +790,144 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #------ Last month and year for monthly-based scripts. ---------------------------------# + if [[ ${monthz} -eq 1 ]] + then + rm_monthz=12 + let rm_yearz=${yearz}-1 + else + let rm_monthz=${monthz}-1 + rm_yearz=${yearz} + fi + #------ Update the time. ---------------------------------------------------------------# + let rm_whenz=12*${rm_yearz}+${rm_monthz} #---------------------------------------------------------------------------------------# @@ -983,11 +1063,11 @@ do #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] + if [[ ${useperiod} == "f" ]] then metcyca=${eftyeara} metcycz=${eftyearz} - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then metcyca=${bioyeara} metcycz=${bioyearz} @@ -999,7 +1079,7 @@ do #---------------------------------------------------------------------------------------# # Switch years in case this is a specific drought run. # #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] + if [[ ${droughtmark} == "TRUE" ]] then let yeara=${droughtyeara}-1 let yearz=${droughtyearz}+1 @@ -1008,32 +1088,21 @@ do - #----- Print a banner. -----------------------------------------------------------------# - if [ ${rscript} == "plot_census.r" ] && [ ${subcens} -eq 0 ] - then - echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." - else - echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." - fi - #---------------------------------------------------------------------------------------# - - - #---------------------------------------------------------------------------------------# # Set up the time and output variables according to the script. # #---------------------------------------------------------------------------------------# case ${rscript} in - read_monthly.r|yearly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) + read_monthly.r|yearly_ascii.r|monthly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) #------------------------------------------------------------------------------------# # Scripts that are based on monthly means. The set up is the same, the only # # difference is in the output names. # #------------------------------------------------------------------------------------# #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] + if [[ ${useperiod} == "t" ]] then #------ One meteorological cycle. Check the type of meteorological driver. ------# case ${metdriver} in - Sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) thisyeara=${metcyca} thisyearz=${metcycz} ;; @@ -1046,34 +1115,34 @@ do thisyearz=${metcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then echo " -> Shifting met cycle" let metcycle=${metcycz}-${metcyca}+1 let deltayr=${shiftcycle}*${metcycle} let thisyeara=${metcyca}+${deltayr} let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} ;; esac # ${metdriver} in #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "u" ] + elif [[ ${useperiod} == "u" ]] then #----- The user said which period to use. ----------------------------------------# thisyeara=${yusera} thisyearz=${yuserz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "f" ] + elif [[ ${useperiod} == "f" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${eftyeara} thisyearz=${eftyearz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${bioyeara} @@ -1085,7 +1154,7 @@ do thisyeara=${yeara} thisyearz=${yearz} #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] + fi # end [[ ${useperiod} == "t" ]] #------------------------------------------------------------------------------------# @@ -1095,6 +1164,53 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Check whether or not to submit the task. -------------------------------------# + if [[ ${rscript} == "plot_census.r" ]] && [[ ${subcens} -eq 0 ]] + then + #---- No need to submit the job if plot_census.r and place doesn't have census. --# + submit_now=false + #---------------------------------------------------------------------------------# + elif ${skip_end} + then + status="${here}/${polyname}/rdata_month/status_${polyname}.txt" + if [[ -s ${status} ]] + then + #----- Retrieve current status of the post-processing. ------------------------# + st_yearz=$(cat ${status} | awk '{print $1}') + st_monthz=$(cat ${status} | awk '{print $2}') + let st_whenz=12*${st_yearz}+${st_monthz} + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # Compare the processed time with the last time needed for processing. # + #------------------------------------------------------------------------------# + if [[ ${st_whenz} -ge ${rm_whenz} ]] + then + #----- Skip submission because it has reached the end. ---------------------# + submit_now=false + #---------------------------------------------------------------------------# + else + #----- Run script as it has not reached the end yet. -----------------------# + submit_now=true + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + else + #----- File not find, run the script. -----------------------------------------# + submit_now=true + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + else + #----- Submit job. ---------------------------------------------------------------# + submit_now=true + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# ;; plot_eval_ed.r) #------------------------------------------------------------------------------------# @@ -1102,7 +1218,7 @@ do # Petrolina (output variables exist only for 2004, so we don't need to process # # all years). # #------------------------------------------------------------------------------------# - if [ ${metdriver} == "Petrolina" ] + if [[ ${metdriver} == "Petrolina" ]] then thismetcyca=2004 thismetcycz=2004 @@ -1122,7 +1238,7 @@ do thisyearz=${thismetcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then #----- Always use the true met driver to find the cycle shift. ----------------# echo " -> Shifting met cycle" @@ -1131,7 +1247,7 @@ do let thisyeara=${thismetcyca}+${deltayr} let thisyearz=${thismetcycz}+${deltayr} #------------------------------------------------------------------------------# - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} #------------------------------------------------------------------------------------# @@ -1142,6 +1258,12 @@ do thismonthz=12 thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_budget.r|plot_rk4.r|plot_rk4pc.r|plot_photo.r|reject_ed.r) @@ -1151,7 +1273,7 @@ do # at the first time step), so we normally skip the first day. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1168,6 +1290,12 @@ do thismonthz=${monthz} let thisdatea=${datea}+1 #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; @@ -1176,7 +1304,7 @@ do # Script with time-independent patch properties. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1193,13 +1321,19 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_daily.r) #------------------------------------------------------------------------------------# # Script with daily means. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1216,6 +1350,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_fast.r) @@ -1223,7 +1363,7 @@ do # Script with short-term averages (usually hourly). No need to skip any- # # thing. # #------------------------------------------------------------------------------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1240,6 +1380,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -1273,7 +1419,7 @@ do sed -i s@thisseasonmona@${seasonmona}@g ${scriptnow} sed -i s@myphysiol@${iphysiol}@g ${scriptnow} sed -i s@myallom@${iallom}@g ${scriptnow} - sed -i s@myslhydro@${slhydro}@g ${scriptnow} + sed -i s@myslhydro@${islhydro}@g ${scriptnow} sed -i s@mydroughtmark@${droughtmark}@g ${scriptnow} sed -i s@mydroughtyeara@${droughtyeara}@g ${scriptnow} sed -i s@mydroughtyearz@${droughtyearz}@g ${scriptnow} @@ -1297,6 +1443,112 @@ do #---------------------------------------------------------------------------------------# + #----- Initialise script. --------------------------------------------------------------# + epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" + complete="${here}/${polyname}/eval_load_complete.txt" + epoststo="${here}/${polyname}/${epostkey}_epost.sto" + epostste="${here}/${polyname}/${epostkey}_epost.ste" + epostout="${here}/${polyname}/${epostkey}_epost.out" + epostexe="R CMD BATCH --no-save --no-restore ${rscript} ${epostout}" + rm -fr ${epostsh} + touch ${epostsh} + chmod u+x ${epostsh} + #---------------------------------------------------------------------------------------# + + + #----- The script header must check which type of submission to use. -------------------# + case "${cluster}" in + SDUMONT) + #----- Task name with the prefix. ---------------------------------------------------# + eposttask="${polyname}" + #------------------------------------------------------------------------------------# + + + #----- Header doesn't need to have SBATCH instructions. -----------------------------# + echo "#!/bin/bash" >> ${epostsh} + echo "main=\"${here}/${polyname}\"" >> ${epostsh} + echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} + echo "yeara=${thisyeara}" >> ${epostsh} + echo "yearz=${thisyearz}" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + + ;; + CANNON) + #----- Task name with the prefix. ---------------------------------------------------# + eposttask="${epostkey}-${desc}-${polyname}" + #------------------------------------------------------------------------------------# + + + #----- Header must have SBATCH instructions. ----------------------------------------# + echo "#!/bin/bash" >> ${epostsh} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${epostsh} + echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${epostsh} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${epostsh} + if [[ "${reservation}" != "" ]] + then + echo "#SBATCH --reservation=${reservation} # Reserved nodes" >> ${epostsh} + fi + echo "#SBATCH --job-name=${eposttask} # Task name" >> ${epostsh} + echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${epostsh} + echo "#SBATCH --time=${runtime} # Time for job" >> ${epostsh} + echo "#SBATCH --output=${epoststo} # Standard output path" >> ${epostsh} + echo "#SBATCH --error=${epostste} # Standard error path" >> ${epostsh} + echo "#SBATCH --chdir=${here}/${polyname} # Main directory" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Get plenty of memory." >> ${epostsh} + echo "ulimit -s unlimited" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Initial settings." >> ${epostsh} + echo "here=\"${here}\" # Main path" >> ${epostsh} + echo "rscript=\"${rscript}\" # R Script" >> ${epostsh} + echo "rstdout=\"${epostout}\" # Standard output" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Print information about this job." >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"----- Summary of current job -------------------------\"" >> ${epostsh} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${epostsh} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${epostsh} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${epostsh} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${epostsh} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${epostsh} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${epostsh} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${epostsh} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${epostsh} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${epostsh} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${epostsh} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${epostsh} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${epostsh} + echo "echo \"------------------------------------------------------\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Define home in case home is not set" >> ${epostsh} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} + echo "then" >> ${epostsh} + echo " export HOME=\$(echo ~)" >> ${epostsh} + echo "fi" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Load modules and settings." >> ${epostsh} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${epostsh} + echo "" >> ${epostsh} + echo "main=\"${here}/${polyname}\"" >> ${epostsh} + echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} + echo "yeara=${thisyeara}" >> ${epostsh} + echo "yearz=${thisyearz}" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + + ;; + esac + #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# @@ -1306,28 +1558,6 @@ do case ${rscript} in plot_eval_ed.r) #----- Create script that will run R until all files have been read. ----------------# - epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" - complete="${here}/${polyname}/eval_load_complete.txt" - rm -fr ${epostsh} - touch ${epostsh} - chmod u+x ${epostsh} - echo "#!/bin/bash" >> ${epostsh} - echo "main=\"${here}/${polyname}\"" >> ${epostsh} - echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} - echo "yeara=${thisyeara}" >> ${epostsh} - echo "yearz=${thisyearz}" >> ${epostsh} - echo "" >> ${epostsh} - echo "" >> ${epostsh} - echo "#--- Define home in case home is not set" >> ${epostsh} - echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} - echo "then" >> ${epostsh} - echo " export HOME=\$(echo ~)" >> ${epostsh} - echo "fi" >> ${epostsh} - echo "" >> ${epostsh} - echo ". \${HOME}/.bashrc" >> ${epostsh} - echo "" >> ${epostsh} - echo "cd \${main}" >> ${epostsh} - echo "" >> ${epostsh} echo "let itmax=\${yearz}-\${yeara}+2" >> ${epostsh} echo "" >> ${epostsh} echo "/bin/rm -fr \${complete}" >> ${epostsh} @@ -1342,24 +1572,6 @@ do ;; *) #----- Create script that will run R until all files have been read. ----------------# - epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" - rm -fr ${epostsh} - touch ${epostsh} - chmod u+x ${epostsh} - echo "#!/bin/bash" >> ${epostsh} - echo "main=\"${here}/${polyname}\"" >> ${epostsh} - echo "" >> ${epostsh} - echo "" >> ${epostsh} - echo "#--- Define home in case home is not set" >> ${epostsh} - echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} - echo "then" >> ${epostsh} - echo " export HOME=\$(echo ~)" >> ${epostsh} - echo "fi" >> ${epostsh} - echo "" >> ${epostsh} - echo ". \${HOME}/.bashrc" >> ${epostsh} - echo "" >> ${epostsh} - echo "cd \${main}" >> ${epostsh} - echo "" >> ${epostsh} echo "${epostexe}" >> ${epostsh} echo "" >> ${epostsh} #------------------------------------------------------------------------------------# @@ -1370,9 +1582,36 @@ do - #----- Make sure this is not the census script for a site we don't have census. --------# - if [ ${rscript} != "plot_census.r" ] || [ ${subcens} -ne 0 ] + #----- In case of single task jobs, add commands to complete the job. ------------------# + case "${cluster}" in + CANNON) + #----- Wait for the processing to finish before killing it, and write runtime info. -# + echo "" >> ${epostsh} + echo "" >> ${epostsh} + echo "#----- Make sure that jobs complete before terminating script" >> ${epostsh} + echo "wait" >> ${epostsh} + echo "" >> ${epostsh} + echo "#----- Report efficiency of this job" >> ${epostsh} + echo "seff \${SLURM_JOBID}" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Decide whether or not to submit task. # + #---------------------------------------------------------------------------------------# + if ${submit_now} then + #----- Submit script. ---------------------------------------------------------------# + echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." + #------------------------------------------------------------------------------------# + + #----- Update the list of scripts to be included in the batch. ----------------------# let n_submit=${n_submit}+1 #------------------------------------------------------------------------------------# @@ -1380,15 +1619,32 @@ do - #----- Append job to submission list. -----------------------------------------------# - srun="srun --nodes=1 --ntasks=1" - srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" - srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" - srun="${srun} --job-name=${polyname}" - srun="${srun} --chdir=\${here}/${polyname}" - srun="${srun} --output=\${here}/${polyname}/${epoststo}" - srun="${srun} --error=\${here}/${polyname}/${epostste}" - echo "${srun} ${epostsh} &" >> ${sbatch} + #----- Decide how to submit the job. ------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Append task to main job submission script. --------------------------------# + srun="srun --nodes=1 --ntasks=1" + srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" + srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" + srun="${srun} --job-name=${eposttask}" + srun="${srun} --chdir=\${here}/${polyname}" + srun="${srun} --output=\${here}/${polyname}/${epoststo}" + srun="${srun} --error=\${here}/${polyname}/${epostste}" + echo "${srun} ${epostsh} &" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + + #----- Add task submission command to the main script. ---------------------------# + echo "echo \" + Submit post-processing for: ${polyname}.\"" >> ${sbatch} + echo "sbatch ${epostsh}" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + else + #----- Skip submission. -------------------------------------------------------------# + echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -1400,40 +1656,62 @@ done #------------------------------------------------------------------------------------------# # Make sure job list doesn't request too many nodes. # #------------------------------------------------------------------------------------------# -if [ ${n_submit} -gt ${n_tasks_max} ] +if ! ${overcommit} && [[ ${n_submit} -gt ${n_tasks_max} ]] then echo " Number of jobs to submit: ${n_submit}" echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" echo " Reduce the number of simulations or try another queue..." exit 99 +elif ${submit} +then + echo " Submitting jobs." + #------- How we submit depends on the cluster. -----------------------------------------# + case "${cluster}" in + SDUMONT) + #------------------------------------------------------------------------------------# + # Single multi-task job. Submit the main script using sbatch. # + #------------------------------------------------------------------------------------# + sbatch ${sbatch} + #------------------------------------------------------------------------------------# + ;; + CANNON) + #------------------------------------------------------------------------------------# + # Multiple single-task jobs. Run the script, the sbatch commands are in there. # + #------------------------------------------------------------------------------------# + ${sbatch} + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# else - #----- Find the right number of nodes to submit. ---------------------------------------# - let n_nodes=(${n_submit}+${n_tpn}-1)/${n_tpn} - let n_tasks=(${n_submit}+${n_nodes}-1)/${n_nodes} - sed -i~ s@mynnodes@${n_nodes}@g ${sbatch} - sed -i~ s@myntasks@${n_tasks}@g ${sbatch} + #------- Provide instructions to the user for a later submission. ----------------------# + case "${cluster}" in + SDUMONT) + #----- Instruct the user to use sbatch. ---------------------------------------------# + echo "-------------------------------------------------------------------------" + echo " To submit the simulations, you must use sbatch. " + echo " Copy and paste the following command in the terminal. " + echo " " + echo " sbatch ${sbatch}" + echo " " + #------------------------------------------------------------------------------------# + ;; + CANNON) + #----- Instruct the user NOT to use sbatch. -----------------------------------------# + echo "-------------------------------------------------------------------------" + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo "-------------------------------------------------------------------------" + echo " Do NOT use sbatch ${sbatch}." + echo " Instead, call the following script directly in your terminal." + echo " " + echo " ${sbatch}" + echo " " + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# - - -#----- Make sure the script waits until all tasks are completed... ------------------------# -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Make sure that jobs complete before terminating script" >> ${sbatch} -echo "wait" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Report efficiency of this job" >> ${sbatch} -echo "seff \${SLURM_JOBID}" >> ${sbatch} -echo "" >> ${sbatch} -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# In case all looks good, go for it! # -#------------------------------------------------------------------------------------------# -if ${submit} -then - sbatch ${sbatch} -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/reset.sh b/ED/Template/scripts/SLURM/reset.sh deleted file mode 100755 index f5d1e0015..000000000 --- a/ED/Template/scripts/SLURM/reset.sh +++ /dev/null @@ -1,398 +0,0 @@ -#!/bin/sh -here=$(pwd) -moi=$(whoami) -diskthere="/n/moorcroftfs2" -joborder="${here}/joborder.txt" - -desc=$(basename ${here}) - -#----- Executable name. -------------------------------------------------------------------# -execname="ed_2.2-opt" -execsrc="${HOME}/EDBRAMS/ED/build" -#------------------------------------------------------------------------------------------# - - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" -else - echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" -fi -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs and delete all files!!!" -echo " Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later don't say that I did not warn you..." -echo "I'm giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - scancel -n ${desc}-${polyname} -p ${queue} -done -#------------------------------------------------------------------------------------------# - - -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Files will be deleted in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Replace the executable. # -#------------------------------------------------------------------------------------------# -cd ${here} -if [ -s ${here}/executable/${execname} ] -then - rm -frv ${here}/executable/${execname} - cp -fv ${execsrc}/${execname} ${here}/executable -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/run_sitter.sh b/ED/Template/scripts/SLURM/run_sitter.sh index e5da240cf..63b80b35a 100755 --- a/ED/Template/scripts/SLURM/run_sitter.sh +++ b/ED/Template/scripts/SLURM/run_sitter.sh @@ -32,6 +32,7 @@ situtils="${here}/sit_utils" # runtitle -- Full name of this simulation, this is used only in the e-mail subject. # #------------------------------------------------------------------------------------------# desc=$(basename ${here}) +jobname="${desc}-sims*" runtitle="Simulation group: ${desc}" #------------------------------------------------------------------------------------------# @@ -50,6 +51,11 @@ check_out="/tmp/check_run_${$}.out" #------------------------------------------------------------------------------------------# +#------ User name. ------------------------------------------------------------------------# +moi=$(whoami) # User name +#------------------------------------------------------------------------------------------# + + #------ Calculator. -----------------------------------------------------------------------# ccc="${HOME}/util/calc.sh" # Calculator #------------------------------------------------------------------------------------------# @@ -66,7 +72,7 @@ ststcrit=0.01 # Maximum change allowed between two cycles #------------------------------------------------------------------------------------------# # E-mail options (normally only the first three options may require changes. # -# email1day -- Should I e-mail once a day (1) or every time I run (0)? # +# emailevery -- Should I e-mail everytime (true) or every frqemail (false)? # # recipient -- To which e-mail should I send the update? # # mailprog -- Which e-mail program to use? mutt works best, I installed in my util # # directory. Give a try, if it doesn't work you may need to install # @@ -85,7 +91,7 @@ ststcrit=0.01 # Maximum change allowed between two cycles # pendfile -- File with pending status # # email1day -- Reminder so the script knows whether an e-mail has been sent or not. # #------------------------------------------------------------------------------------------# -email1day=1 +emailevery=false recipient="" mailprog=$(which mutt) frqemail="" @@ -118,10 +124,18 @@ frqtouch="" #----- Format for checking simulations. ---------------------------------------------------# -outform="JobName%200,State%12" +outform="JobId%20,JobName%200,State%12" #------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +# Optional feature to reset stalled polygons. This feature is particularly useful # +# when using serial_requeue, as some jobs land in faulty nodes. This feature is currently # +# available for CANNON only. # +#------------------------------------------------------------------------------------------# +stall_reset=true +nstall=2 +#------------------------------------------------------------------------------------------# @@ -180,7 +194,7 @@ fi #----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -if [ -s ${here}/run_sitter.lock ] +if [[ -s ${here}/run_sitter.lock ]] then exit else @@ -190,6 +204,26 @@ fi + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*) + cluster="CANNON" + ;; +sdumont*) + cluster="SDUMONT" + stall_reset=false + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + #------ Move to the current directory. ----------------------------------------------------# cd ${here} #------------------------------------------------------------------------------------------# @@ -205,13 +239,13 @@ sed -i~ s@"${hereline}"@"here=\"${here}\""@g ${transfer} #----- Determine the number of polygons to run. -------------------------------------------# let n_polygon=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${n_polygon} -lt 100 ] +if [[ ${n_polygon} -lt 100 ]] then ndig=2 -elif [ ${n_polygon} -lt 1000 ] +elif [[ ${n_polygon} -lt 1000 ]] then ndig=3 -elif [ ${n_polygon} -lt 10000 ] +elif [[ ${n_polygon} -lt 10000 ]] then ndig=4 else @@ -223,9 +257,8 @@ echo "Number of polygons: ${n_polygon}..." -#----- Set job name. ----------------------------------------------------------------------# +#----- Set job prefix. --------------------------------------------------------------------# desc=$(basename ${here}) -jobname="${desc}-sims" #------------------------------------------------------------------------------------------# @@ -235,7 +268,7 @@ jobname="${desc}-sims" if [[ ${delay1st_min} -gt 0 ]] then let nsl=${delay1st_min}+1 - while [ ${nsl} -gt 1 ] + while [[ ${nsl} -gt 1 ]] do let nsl=${nsl}-1 case ${nsl} in @@ -259,7 +292,7 @@ fi #------------------------------------------------------------------------------------------# n_ongoing=9999 iter=0 -while [ ${n_ongoing} -gt 0 ] +while [[ ${n_ongoing} -gt 0 ]] do #------ Update iteration counter. ------------------------------------------------------# let iter=${iter}+1 @@ -267,11 +300,13 @@ do #---- Reset count of polygons. ---------------------------------------------------------# n_running=0 + n_stalled=0 n_suspend=0 n_the_end=0 n_unknown=0 n_sigsegv=0 n_crashed=0 + n_hydfail=0 n_metmiss=0 n_stopped=0 #---------------------------------------------------------------------------------------# @@ -281,10 +316,10 @@ do #---------------------------------------------------------------------------------------# # Check whether it's time to update simulation setting files. # #---------------------------------------------------------------------------------------# - if [ ${frqtouch} -gt 0 ] + if [[ ${frqtouch} -gt 0 ]] then let xtouch=${iter}%${frqtouch} - if [ ${xtouch} -eq 0 ] + if [[ ${xtouch} -eq 0 ]] then echo " Touch main files." touch ${here}/*.sh @@ -301,7 +336,7 @@ do #----- Transfer files. -----------------------------------------------------------------# - if [ ! -s ${translock} ] + if [[ ! -s ${translock} ]] then echo " Backup files." nice nohup ${transfer} 1> ${here}/out_transfer.out 2>&1 & @@ -310,9 +345,19 @@ do #----- Move current check to the last check. -------------------------------------------# - rm -f ${lastcheck} - mv ${outcheck} ${lastcheck} - touch ${outcheck} + if [[ -s "${outcheck}" ]] + then + nlnout=$(cat ${outcheck} | wc -l) + if [[ ${nlnout} -eq ${n_polygon} ]] + then + rm -f ${lastcheck} + mv ${outcheck} ${lastcheck} + touch ${outcheck} + else + rm -f ${outcheck} + touch ${outcheck} + fi + fi #---------------------------------------------------------------------------------------# @@ -321,7 +366,7 @@ do # Go through all polygons. # #---------------------------------------------------------------------------------------# ff=0 - while [ ${ff} -lt ${n_polygon} ] + while [[ ${ff} -lt ${n_polygon} ]] do #------------------------------------------------------------------------------------# @@ -340,131 +385,148 @@ do # latitude. # #------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. ----------# + taskname="${polyname}" + #---------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. --------------------# + taskname="${desc}-${polyname}" + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# @@ -474,6 +536,11 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). --------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ------------------------------------# scentype="ERA_Interim" @@ -524,6 +591,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ------------------------------------------# scentype="WFDEI" @@ -613,6 +685,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -763,6 +841,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -800,7 +884,7 @@ do # Correct years so it is not tower-based or Sheffield. # #------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|WFDE5*|WFDEI*|Sheffield) echo "Nothing" > /dev/null ;; *) @@ -848,7 +932,7 @@ do # again. # #------------------------------------------------------------------------------------# statrun=${here}/${polyname}/statusrun.txt - if [ -s ${statrun} ] + if [[ -s ${statrun} ]] then #----- Obtain previous status. ---------------------------------------------------# yearh_old=$(cat ${statrun} | awk '{print $2}') @@ -866,7 +950,7 @@ do #----- In case the simulation never started, force it to be INITIAL. -------------# - if [ ${yearh_old} -eq ${yeara} ] && [ ${monthh_old} -eq ${montha} ] + if [[ ${yearh_old} -eq ${yeara} ]] && [[ ${monthh_old} -eq ${montha} ]] then yearh_old=${yeara} monthh_old=${montha} @@ -892,10 +976,25 @@ do scb_old="NA" npa_old="NA" fi - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Initially assume stall=0. This will be checked and updated only if the # + # simulation is running. Also retrieve the previous stall count if there is one, # + # in case we must update the stall check. # + #------------------------------------------------------------------------------------# + stall=0 + #----- Load previous stall. ---------------------------------------------------------# + if [[ -s ${lastcheck} ]] + then + stall_old=$(cat ${lastcheck} | grep ${polyname} | awk '{print $8}') + else + stall_old=0 + fi + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# # We only check those polygons that may be running, so the check doesn't take too # @@ -907,7 +1006,7 @@ do whichrun=${here}/${polyname}/whichrun.r outwhich=${here}/${polyname}/outwhich.txt R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - if [ -s ${statrun} ] + if [[ -s ${statrun} ]] then yearh=$(cat ${statrun} | awk '{print $2}') monthh=$(cat ${statrun} | awk '{print $3}') @@ -935,41 +1034,9 @@ do - #------------------------------------------------------------------------------------# - # Check whether the simulations are stalled. # - #------------------------------------------------------------------------------------# - case ${runt} in - "HISTORY") - #----- Check whether the runs are stalled. ---------------------------------------# - if [ ${yearh} == ${yearh_old} ] && [ ${monthh} == ${monthh_old} ] && - [ ${dateh} == ${dateh_old} ] && [ ${timeh} == ${timeh_old} ] - then - stall_old=$(cat ${lastcheck} | grep ${polyname} | awk '{print $8}') - let stall=${stall_old}+1 - else - stall=0 - fi - #---------------------------------------------------------------------------------# - ;; - *) - #----- Not in history, simulations are unlikely to be stalled. -------------------# - stall=0 - #---------------------------------------------------------------------------------# - ;; - esac - #------------------------------------------------------------------------------------# - - - #----- Write polygon check into a single table. -------------------------------------# - output="${polyname} ${polylon} ${polylat} ${yearh} ${monthh} ${dateh} ${timeh}" - output="${output} ${stall} ${runt} ${agb} ${bsa} ${lai} ${scb} ${npa}" - echo ${output} >> ${outcheck} - #------------------------------------------------------------------------------------# - - #----- Update files that may be used to check status or to re-submit. ---------------# - if [ ${xtouch} -eq 0 ] + if [[ ${xtouch} -eq 0 ]] then touch ${here}/${polyname}/*.r touch ${here}/${polyname}/ED2IN @@ -983,10 +1050,25 @@ do #------------------------------------------------------------------------------------# # Check whether the simulation is still running, and if not, why it isn't. # #------------------------------------------------------------------------------------# - if [ -s ${stdout} ] + if [[ -s ${stdout} ]] then + #----- Set task inquire command. -------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Multi-task job, search for specific task. ------------------------------# + stask="stask --noheader -u ${moi} -t ${taskname} -j ${jobname}" + #------------------------------------------------------------------------------# + ;; + CANNON) + #----- Single-task jobs, search the task using the job name. ------------------# + stask="stask --noheader -u ${moi} -j ${taskname}" + #------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------# + + #----- Check whether the simulation is running, and when in model time it is. ----# - stask="stask --noheader -u $(whoami) -t ${polyname} -j ${jobname} " running=$(${stask} -o "${outform}" | grep "RUNNING" | wc -l) pending=$(${stask} -o "${outform}" | grep "PENDING" | wc -l) suspended=$(${stask} -o "${outform}" | grep "SUSPENDED" | wc -l) @@ -996,8 +1078,54 @@ do + #---------------------------------------------------------------------------------# + # Check whether the simulations are stalled. # + #---------------------------------------------------------------------------------# + if [[ ${running} -gt 0 ]] + then + #----- Check whether the runs are stalled. ------------------------------------# + if [[ ${yearh} == ${yearh_old} ]] && [[ ${monthh} == ${monthh_old} ]] && + [[ ${dateh} == ${dateh_old} ]] && [[ ${timeh} == ${timeh_old} ]] + then + let stall=${stall_old}+1 + else + stall=0 + fi + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether to kill and resubmit the job. # + #------------------------------------------------------------------------------# + if ${stall_reset} && [[ ${stall} -ge ${nstall} ]] + then + #------- Set stalled flag to one so it is clear the run is not running. ----# + stalled=true + #---------------------------------------------------------------------------# + else + #------- Set stalled flag to zero. It is either running or something else. -# + stalled=false + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + + else + #----- Not in history, simulations are unlikely to be stalled. ----------------# + stall=0 + stalled=false + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + + + + #----- Check for segmentation violations. ----------------------------------------# - if [ -s ${stderr} ] + if [[ -s ${stderr} ]] then segv1=$(grep -i "sigsegv" ${stderr} | wc -l) segv2=$(grep -i "segmentation fault" ${stderr} | wc -l) @@ -1018,50 +1146,157 @@ do #----- Check for other possible outcomes. ----------------------------------------# - stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) - crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) - the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) + stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) + crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) + hydfail=$(grep "Plant Hydrodynamics is off-track." ${stdout} | wc -l) + the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# # Plot a message so the user knows what is going on. # #---------------------------------------------------------------------------------# - if [ ${pending} -gt 0 ] + if [[ ${pending} -gt 0 ]] then let n_pending=${n_pending}+1 echo -e "${ffout}: ${polyname} is pending..." - elif [ ${suspended} -gt 0 ] + elif [[ ${suspended} -gt 0 ]] then let n_suspend=${n_suspend}+1 echo -e "${ffout}: ${polyname} is SUSPENDED." - elif [ ${running} -gt 0 ] && [ ${sigsegv} -eq 0 ] + elif ${stalled} + then + let n_stalled=${n_stalled}+1 + echo -e "${ffout}: ${polyname} is STALLED (${stall} - ${runtime})." + + #------------------------------------------------------------------------------# + # Kill jobs, it must be stalled. # + #------------------------------------------------------------------------------# + jobid="enter_loop" + kcnt=0 + while [[ "${jobid}" != "" ]] && [[ ${kcnt} -lt 10 ]] + do + #----- Ensure to eliminate potential duplicates. ---------------------------# + let kcnt=${kcnt}+1 + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + echo " - Cancel Job ${jobid} (${taskname})." + scancel ${jobid} + fi + #---------------------------------------------------------------------------# + done + if [[ ${kcnt} -ge 10 ]] + then + #------ The script is bogus. -----------------------------------------------# + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " JOB NUMBER IS LIKELY INCORRECT IN STASK. STOPPING THE SCRIPT. " + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " Output of stask command:" + ${stask} -o "${outform}" + echo " Resulting JobId:" + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + echo " Job Line=${jobln}" + echo " JobId=${jobid}" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 99 + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + #----- Re-submit job. ---------------------------------------------------------# + echo " - Submit New job (${taskname})." + callserial="${here}/${polyname}/callserial.sh" + sbatch ${callserial} + stall=0 + #------------------------------------------------------------------------------# + + elif [[ ${running} -gt 0 ]] && [[ ${sigsegv} -eq 0 ]] then let n_running=${n_running}+1 echo -e "${ffout}: ${polyname} is running (${runtime})." - elif [ ${sigsegv} -gt 0 ] + elif [[ ${sigsegv} -gt 0 ]] then let n_sigsegv=${n_sigsegv}+1 echo -e "${ffout}: ${polyname} HAD SEGMENTATION VIOLATION." - elif [ ${crashed} -gt 0 ] + elif [[ ${crashed} -gt 0 ]] then let n_crashed=${n_crashed}+1 echo -e "${ffout}: ${polyname} HAS CRASHED (RK4 PROBLEM)." - elif [ ${metmiss} -gt 0 ] + elif [[ ${hydfail} -gt 0 ]] + then + let n_hydfail=${n_hydfail}+1 + echo -e "${ffout}: ${polyname} HAS CRASHED (HYDRODYNAMICS)." + elif [[ ${metmiss} -gt 0 ]] then let n_metmiss=${n_metmiss}+1 echo -e "${ffout}: ${polyname} DID NOT FIND MET DRIVERS." - elif [ ${stopped} -gt 0 ] + elif [[ ${stopped} -gt 0 ]] then let n_stopped=${n_stopped}+1 echo -e "${ffout}: ${polyname} STOPPED (UNKNOWN REASON)." - elif [ ${the_end} -gt 0 ] + elif [[ ${the_end} -gt 0 ]] then let n_the_end=${n_the_end}+1 echo -e "${ffout}: ${polyname} has finished." else let n_unknown=${n_unknown}+1 echo -e "${ffout}: ${polyname} status is UNKNOWN." + + #------------------------------------------------------------------------------# + # Kill jobs, it must be stalled. # + #------------------------------------------------------------------------------# + jobid="enter_loop" + kcnt=0 + while [[ "${jobid}" != "" ]] && [[ ${kcnt} -lt 10 ]] + do + #----- Ensure to eliminate potential duplicates. ---------------------------# + let kcnt=${kcnt}+1 + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + echo " - Cancel Job ${jobid} (${taskname})." + scancel ${jobid} + fi + #---------------------------------------------------------------------------# + done + if [[ ${kcnt} -ge 10 ]] + then + #------ The script is bogus. -----------------------------------------------# + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " JOB NUMBER IS LIKELY INCORRECT IN STASK. STOPPING THE SCRIPT. " + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " Output of stask command:" + ${stask} -o "${outform}" + echo " Resulting JobId:" + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + echo " JobLine=${jobid}" + echo " JobId=${jobid}" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 99 + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + #----- Re-submit job. ---------------------------------------------------------# + echo " - Submit New job (${taskname})." + callserial="${here}/${polyname}/callserial.sh" + sbatch ${callserial} + #------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------# else @@ -1072,32 +1307,10 @@ do - #------------------------------------------------------------------------------------# - # Update the history time for ED2IN so it doesn't start from the beginning in # - # case the job is resubmitted automatically. # - #------------------------------------------------------------------------------------# - if [ -s ${stdout} ] - then - ED2IN="${here}/${polyname}/ED2IN" - runtype_new=" NL%RUNTYPE = 'HISTORY'" - sfilin_new=" NL%SFILIN = '${here}/${polyname}/histo/${polyname}'" - itimeh_new=" NL%ITIMEH = ${timeh}" - idateh_new=" NL%IDATEH = ${dateh}" - imonthh_new=" NL%IMONTHH = ${monthh}" - iyearh_new=" NL%IYEARH = ${yearh}" - runtype_old=$(grep -i "NL%RUNTYPE" ${ED2IN} | grep -v "\!") - sfilin_old=$(grep -i "NL%SFILIN" ${ED2IN} | grep -v "\!") - itimeh_old=$(grep -i "NL%ITIMEH" ${ED2IN} ) - idateh_old=$(grep -i "NL%IDATEH" ${ED2IN} ) - imonthh_old=$(grep -i "NL%IMONTHH" ${ED2IN} ) - iyearh_old=$(grep -i "NL%IYEARH" ${ED2IN} ) - sed -i~ s@"${runtype_old}"@"${runtype_new}"@g ${ED2IN} - sed -i~ s@"${sfilin_old}"@"${sfilin_new}"@g ${ED2IN} - sed -i~ s@"${itimeh_old}"@"${itimeh_new}"@g ${ED2IN} - sed -i~ s@"${idateh_old}"@"${idateh_new}"@g ${ED2IN} - sed -i~ s@"${imonthh_old}"@"${imonthh_new}"@g ${ED2IN} - sed -i~ s@"${iyearh_old}"@"${iyearh_new}"@g ${ED2IN} - fi + #----- Write polygon check into a single table. -------------------------------------# + output="${polyname} ${polylon} ${polylat} ${yearh} ${monthh} ${dateh} ${timeh}" + output="${output} ${stall} ${runt} ${agb} ${bsa} ${lai} ${scb} ${npa}" + echo ${output} >> ${outcheck} #------------------------------------------------------------------------------------# done #---------------------------------------------------------------------------------------# @@ -1107,17 +1320,18 @@ do #---------------------------------------------------------------------------------------# # Run the post processing. # #---------------------------------------------------------------------------------------# - if [ ${frqpost} -gt 0 ] + if [[ ${frqpost} -gt 0 ]] then let xpost=${iter}%${frqpost} - if [ -s "${here}/epost.sh" ] && [ ${xpost} -eq 0 -o ${n_ongoing} -eq 0 ] + + if [[ ${xpost} -eq 0 ]] || [[ ${n_ongoing} -eq 0 ]] then echo " Run post-processing." ${here}/epost.sh echo " Compress/clean files." - ${here}/last_histo.sh + sbatch ${here}/last_histo.sh fi fi #---------------------------------------------------------------------------------------# @@ -1141,6 +1355,7 @@ do n_metmiss=$(grep METMISS ${outcheck} | wc -l) n_bad_met=$(grep BAD_MET ${outcheck} | wc -l) n_crashed=$(grep CRASHED ${outcheck} | wc -l) + n_hydfail=$(grep HYDFAIL ${outcheck} | wc -l) n_stopped=$(grep STOPPED ${outcheck} | wc -l) n_extinct=$(grep EXTINCT ${outcheck} | wc -l) n_ststate=$(grep STSTATE ${outcheck} | wc -l) @@ -1151,9 +1366,11 @@ do echo "------- Simulation status. --------------------------------------" >> ${statfile} echo " Number of polygons that have never started : ${n_initial}" >> ${statfile} echo " Number of polygons that have partially run : ${n_running}" >> ${statfile} + echo " Number of polygons that have stalled : ${n_stalled}" >> ${statfile} echo " Number of polygons that haven't found met drivers : ${n_metmiss}" >> ${statfile} echo " Number of polygons that have bad met drivers : ${n_bad_met}" >> ${statfile} - echo " Number of polygons that have crashed : ${n_crashed}" >> ${statfile} + echo " Number of polygons that have crashed (RK4) : ${n_crashed}" >> ${statfile} + echo " Number of polygons that have crashed (Hydrodyn.) : ${n_hydfail}" >> ${statfile} echo " Number of polygons that have mysteriously stopped : ${n_stopped}" >> ${statfile} echo " Number of polygons that became desert : ${n_extinct}" >> ${statfile} echo " Number of polygons that have reached steady state : ${n_ststate}" >> ${statfile} @@ -1173,10 +1390,6 @@ do echo " " >> ${emailbody} cat ${statfile} >> ${emailbody} echo " " >> ${emailbody} - cat ${recefile} >> ${emailbody} - echo " " >> ${emailbody} - cat ${queuefile} >> ${emailbody} - echo " " >> ${emailbody} cat ${tailfile} >> ${emailbody} echo " " >> ${emailbody} #----- Check whether to append some plots. ---------------------------------------------# @@ -1185,7 +1398,7 @@ do attach="" for fichier in ${R_figlist} do - if [ -s ${fichier} ] + if [[ -s ${fichier} ]] then attach="${attach} -a ${fichier}" fi @@ -1209,17 +1422,17 @@ do #---------------------------------------------------------------------------------------# # Check whether to send the e-mail or not. # #---------------------------------------------------------------------------------------# - if [ ${email1day} -eq 0 ] + if ${emailevery} then #----- Always send e-mail. -----------------------------------------------------------# sendemail=true #-------------------------------------------------------------------------------------# - elif [ -s ${emailday} ] + elif [[ -s ${emailday} ]] then #----- E-mail has been sent. Check whether it is time to send again. ---------------# elast=$(cat ${emailday}) - let elast=${elapsed}-${elast} - if [ ${elast} -gt ${frqemail} ] + let ediff=${elapsed}-${elast} + if [[ ${ediff} -ge ${frqemail} ]] then #----- Time to send another e-mail. ----------------------------------------------# sendemail=true @@ -1257,11 +1470,11 @@ do # In case any simulation is still on the works, take a break before checking # # again. # #---------------------------------------------------------------------------------------# - if [ ${n_ongoing} -gt 0 ] + if [[ ${n_ongoing} -gt 0 ]] then echo " + Take a break before checking again." let nsl=${wait_minutes}+1 - while [ ${nsl} -gt 1 ] + while [[ ${nsl} -gt 1 ]] do let nsl=${nsl}-1 case ${nsl} in @@ -1281,12 +1494,6 @@ do echo "===================================================================" echo "" #---------------------------------------------------------------------------------------# - - - #----- Clean-up stuff. -----------------------------------------------------------------# - echo " + Delete some temporary files..." - /bin/rm -f ${queuefile} ${recefile} - #---------------------------------------------------------------------------------------# done #------------------------------------------------------------------------------------------# @@ -1297,7 +1504,7 @@ done # transferring the files. # #------------------------------------------------------------------------------------------# nwait=0 -while [ -s ${translock} ] +while [[ -s ${translock} ]] do let nwait=${nwait}+1 echo " + Attempt ${nwait}, script transfer is running. Wait 10 minutes and try again." diff --git a/ED/Template/scripts/SLURM/sim_sitter.sh b/ED/Template/scripts/SLURM/sim_sitter.sh deleted file mode 100755 index ca6ae2732..000000000 --- a/ED/Template/scripts/SLURM/sim_sitter.sh +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash - -#----- Main settings. Do look at run_sitter.sh and epost.sh for additional settings. -----# -here=$(pwd) # Current path. -there="/path/to/permanent/storage" # Permanent storage path (leave empty for no transfer) -email="myself\@myserver.com" # Your e-mail. Put a backslash before the @ -queue="myqueue" # Queue to run run_sitter.sh and epost.sh -runtime="infinite" # Run time request -memory=2048 # Requested memory (Mb) -sbatch=$(which sbatch) # SLURM command to submit job. -rscript="read_monthly.r" # Which script to run with epost.sh. See options below. - # Multiple scripts are allowed, put spaces between - # them. (e.g. rscript="plot_monthly.r plot_fast.r") -frqemail=43200 # How often to send emails on simulation status? -delay1st_min=20 # Time (in minutes) to wait before the first check - # (needed in case the run_sitter script is submitted - # before the simulation starts. In case the - # simulation is already running, it is fine to set - # this to zero). -wait_minutes=60 # Waiting time before checking run again (in minutes) -frqpost=3 # How often to run post-processing and file management - # This number is in iterations. Zero means never. -frqtouch=0 # How often to touch executable, scripts, and Template? - # This number is in iterations. Zero means never. -checkhourly="n" # Check hourly files. -checkstatus="y" # Check status before compressing -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Which scripts to run. # -# # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # -# # -# The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # -#------------------------------------------------------------------------------------------# - - -#----- Make sure e-mail and queue are pre-defined. ----------------------------------------# -if [[ "x${email}" == "x" ]] || [[ "x${queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] -then - echo "---------------------------------------------------------------------------------" - echo " The following variables must be set. In case any of them are empty, check" - echo " your script sim_sitter.sh." - echo " " - echo " email = ${email}" - echo " queue = ${queue}" - echo " rscript = ${rscript}" - echo " " - echo "---------------------------------------------------------------------------------" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - -#----- Make substitutions. ----------------------------------------------------------------# -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/run_sitter.sh -sed -i~ s@"recipient=\"\""@"recipient=\"${email}\""@g ${here}/run_sitter.sh -sed -i~ s@"frqemail=\"\""@"frqemail=${frqemail}"@g ${here}/run_sitter.sh -sed -i~ s@"delay1st_min=\"\""@"delay1st_min=${delay1st_min}"@g ${here}/run_sitter.sh -sed -i~ s@"wait_minutes=\"\""@"wait_minutes=${wait_minutes}"@g ${here}/run_sitter.sh -sed -i~ s@"frqpost=\"\""@"frqpost=${frqpost}"@g ${here}/run_sitter.sh -sed -i~ s@"frqtouch=\"\""@"frqtouch=${frqtouch}"@g ${here}/run_sitter.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/epost.sh -sed -i~ s@"global_queue=\"\""@"global_queue=\"${queue}\""@g ${here}/epost.sh -sed -i~ s@"rscript=\"\""@"rscript=\"${rscript}\""@g ${here}/epost.sh -sed -i~ s@"submit=false"@"submit=true"@g ${here}/epost.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/transfer.sh -sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${here}/transfer.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/last_histo.sh -sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${here}/last_histo.sh -sed -i~ s@"checkhourly=\"\""@"checkhourly=\"${checkhourly}\""@g ${here}/last_histo.sh -sed -i~ s@"checkstatus=\"\""@"checkstatus=\"${checkstatus}\""@g ${here}/last_histo.sh -#------------------------------------------------------------------------------------------# - - -#----- Job preferences. -------------------------------------------------------------------# -joblog="${here}/out_sitter.out" -jobpref=$(basename ${here}) -jobname="${jobpref}-control" -jobmain="${jobpref}-sims" -#------------------------------------------------------------------------------------------# - - -#------ Check ID of main job name, so it includes a dependency. ---------------------------# -mainid=$(sjobs | grep -i ${jobmain} | grep -v CANCELLED | grep -v COMPLETED | grep -v COMPLETING | grep -v FAILED | awk '{print $1}') -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Check whether to submit the job. # -#------------------------------------------------------------------------------------------# -if [[ "x${mainid}" == "x" ]] -then - echo " Job name ${jobmain} was not found, so the run_sitter.sh job will not be queued." - goahead="n" -elif [[ -s "${here}/run_sitter.lock" ]] || [[ -s "${here}/transfer.lock" ]] -then - echo " Lock file found for run_sitter.sh and/or transfer.lock." - echo " The scripts may be already running." - echo " Submit the script anyway [y|N]?" - read goahead -else - goahead="y" -fi -goahead="$(echo ${goahead} | tr '[:upper:]' '[:lower:]')" -#------------------------------------------------------------------------------------------# - - -#----- Submit run_sitter.sh in batch mode. ------------------------------------------------# -comm="${sbatch} -p ${queue} --mem-per-cpu=${memory} -t ${runtime} -o ${joblog}" -comm="${comm} -J ${jobname} -n 1 --dependency=after:${mainid}" -comm="${comm} --wrap=\"${here}/run_sitter.sh\"" -case ${goahead} in -y|yes) - /bin/rm -f ${here}/run_sitter.lock - /bin/rm -f ${here}/transfer.lock - echo ${comm} - ${comm} - ;; -*) - bann="Script run_sitter was not submitted. In case you want to submit manually" - bann="${bann} this is the command:" - echo ${bann} - echo " " - echo ${comm} - ;; -esac -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/spawn_poly.sh b/ED/Template/scripts/SLURM/spawn_poly.sh index 7b3146087..4cc98dbdb 100755 --- a/ED/Template/scripts/SLURM/spawn_poly.sh +++ b/ED/Template/scripts/SLURM/spawn_poly.sh @@ -10,23 +10,23 @@ here=$(pwd) moi=$(whoami) #----- Description of this simulation, used to create unique job names. -------------------# desc=$(basename ${here}) +#----- Source path for ED code and executable. --------------------------------------------# +srcpath="${HOME}/EDBRAMS/ED" #----- Original and scratch main data paths. ----------------------------------------------# ordinateur=$(hostname -s) -case ${ordinateur} in - sdumont*) export d_path="${SCRATCH}/Data" ;; - rclogin*|holy*|moorcroft*|rcnx*) export d_path="${HOME}/data" ;; - *) echo " Invalid computer ${ordinateur}. Check script header."; exit ;; -esac +d_path="${HOME}/data" #----- Path where biomass initialisation files are: ---------------------------------------# bioinit="${d_path}/ed2_data/site_bio_data" alsinit="${d_path}/ed2_data/lidar_spline_bio_data" intinit="${d_path}/ed2_data/lidar_intensity_bio_data" lutinit="${d_path}/ed2_data/lidar_lookup_bio_data" +ebainit="${d_path}/ed2_data/lidar_eba_bio_data" biotype=0 # 0 -- "default" setting (isizepft controls default/nounder) # 1 -- isizepft controls number of PFTs, whereas iage controls patches. # 2 -- airborne lidar initialisation using return counts ("default"). # 3 -- airborne lidar initialisation using intensity counts. # 4 -- airborne lidar/inventory hybrid initialisation ("lookup table"). + # 5 -- airborne lidar (EBA Transects). # For lidar initialisation (2-4), isizepft is the disturbance history key. #----- Path and file prefix for init_mode = 5. --------------------------------------------# restart="${d_path}/ed2_data/restarts_XXX" @@ -38,7 +38,7 @@ shefhead='SHEF_NCEP_DRIVER_DS314' metmaindef="${d_path}/ed2_data" packdatasrc="${d_path}/to_scratch" #----- Path with land use scenarios. ------------------------------------------------------# -lumain="${d_path}/ed2_data/land_use" +lumain="${d_path}/ed2_data/lcluc_scenarios" #----- Path with other input data bases (soil texture, DGD, land mask, etc). --------------# inpmain="${d_path}/ed2_data" #----- Should the met driver be copied to local scratch disks? ----------------------------# @@ -59,19 +59,20 @@ dateh="01" # Day timeh="0000" # Hour #----- Default tolerance. -----------------------------------------------------------------# toldef="0.01" -#----- Executable names. ------------------------------------------------------------------# -execname="ed_2.2-opt" # Normal executable, for most queues #----- Initialisation scripts. ------------------------------------------------------------# initrc="${HOME}/.bashrc" # Initialisation script for most nodes #----- Initialisation scripts. ------------------------------------------------------------# optsrc="-n" # Option for .bashrc (for special submission settings) # In case none is needed, leave it blank (""). #----- Submit job automatically? (It may become false if something prevents submission). --# -submit=false +submit=false # This checks whether to submit runs or not. +on_the_fly=false # In case submit=true and this is the CANNON cluster, on_the_fly allows + # directories are jobs to be submitted as the directories are ready. +#----- Executable names. ------------------------------------------------------------------# +execname="ed_2.2-opt" # Normal executable, for most queues +checkexec=true # Check executable #----- Settings for this group of polygons. -----------------------------------------------# global_queue="shared,huce_intel" # Queue -sim_memory=0 # Memory per simulation. Zero uses queue's default -n_cpt=12 # Number of cpus per task (Zero uses queue's maximum) partial=false # Partial submission (false will ignore polya and npartial # and send all polygons. polya=21 # First polygon to submit @@ -79,7 +80,20 @@ npartial=300 # Maximum number of polygons to include in this # (actual number will be adjusted for total number of # polygons if needed be). dttask=2 # Time to wait between task submission -runtime="00:00:00" # Requested runtime. Zero uses the queue's maximum. +init_only=false # Run model initialisation only? + # This can be useful when the initialisation step + # demands much more memory than the time steps (e.g., + # when using lidar data to initialisate the model). +if ${init_only} +then + sim_memory=64000 # Memory per simulation. Zero uses queue's default + n_cpt=1 # Number of cpus per task (Zero uses queue's maximum) + runtime="01-00:00:00" # Requested runtime. Zero uses the queue's maximum. +else + sim_memory=3072 # Memory per simulation. Zero uses queue's default + n_cpt=12 # Number of cpus per task (Zero uses queue's maximum) + runtime="07-00:00:00" # Requested runtime. Zero uses the queue's maximum. +fi #------------------------------------------------------------------------------------------# #==========================================================================================# @@ -123,6 +137,64 @@ squeue="squeue --noheader -u ${moi}" #------------------------------------------------------------------------------------------# +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case "${host}" in +rclogin*|holy*|moorcroft*|rcnx*) + #----- Cluster is CANNON (formerly known as ODYSSEY). ----------------------------------# + cluster="CANNON" + #---------------------------------------------------------------------------------------# + ;; +sdumont*) + #----- Cluster is SDUMONT. Ironically perhaps, we cannot submit jobs on the fly. -------# + cluster="SDUMONT" + on_the_fly=false + #---------------------------------------------------------------------------------------# + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + cluster=$(echo ${cluster} | tr '[:lower:]' '[:upper:]') + case "${cluster}" in + CANNON|CANNO|CANN|CAN|CA|C) + #----- Set cluster to CANNON. -------------------------------------------------------# + cluster="CANNON" + #------------------------------------------------------------------------------------# + ;; + ODYSSEY|ODYSSE|ODYSS|ODYS|ODY|OD|O) + #----- Set cluster to CANNON. -------------------------------------------------------# + cluster="CANNON" + echo " - Odyssey is now known as Cannon. Using Cannon settings." + #------------------------------------------------------------------------------------# + ;; + SDUMONT|SDUMON|SDUMO|SDUM|SDU|SD|S) + #----- Cluster is SDUMONT. Ironically perhaps, we cannot submit jobs on the fly. ----# + cluster="SDUMONT" + on_the_fly=false + #------------------------------------------------------------------------------------# + ;; + *) + #----- Unknown cluster. -------------------------------------------------------------# + echo " Cluster ${cluster} is not recognised. Pick either CANNON or SDUMONT." + echo " (or edit the script to add the new cluster)." + exit 92 + #------------------------------------------------------------------------------------# + ;; + esac + ;; +esac +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# Do not let on_the_fly if submit is false. # +#------------------------------------------------------------------------------------------# +if ! ${submit} +then + on_the_fly=false +fi +#------------------------------------------------------------------------------------------# + + #----- Set the main path for the site, pseudo past and Sheffield met drivers. -------------# if ${copy2scratch} then @@ -136,13 +208,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -186,67 +258,41 @@ done # script. # #------------------------------------------------------------------------------------------# exec_full="${here}/executable/${execname}" -if [ ! -s ${exec_full} ] +exec_src="${srcpath}/build/${execname}" +if [[ ! -s ${exec_full} ]] then echo "Executable file : ${exec_full} is not in the executable directory" echo "Copy the executable to the file before running this script!" exit 99 +elif ${checkexec} +then + #----- Check whether the executable is up to date. -------------------------------------# + idiff=$(diff ${exec_full} ${exec_src} 2> /dev/null | wc -l) + if [[ ${idiff} -gt 0 ]] + then + #----- Executable is not up to date, warn user and offer to update it. --------------# + echo "Executable ${exec_full} is not the same as the most recently compiled file." + echo "Most recent: ${exec_src}." + echo "Do you want to update the executable? [y/N]" + read update + update=$(echo ${update} | tr '[:upper:]' '[:lower:]') + case "${update}" in + y*) rsync - Putv ${exec_src} ${exec_full} ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Configurations depend on the global_queue. # +# Configurations depend on the global_queue and cluster. # #------------------------------------------------------------------------------------------# -case ${ordinateur} in -rclogin*|holy*|moorcroft*|rcnx*) - #----- Odyssey queues. -----------------------------------------------------------------# - case ${global_queue} in - "serial_requeue") - n_nodes_max=900 - n_cpt_max=12 - n_cpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared,huce_intel"|"huce_intel,shared") - n_nodes_max=276 - n_cpt_max=12 - n_cpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared") - n_nodes_max=456 - n_cpt_max=24 - n_cpn=48 - runtime_max="7-00:00:00" - node_memory=192892 - ;; - "huce_intel") - n_nodes_max=276 - n_cpt_max=12 - n_cpn=24 - runtime_max="14-00:00:00" - node_memory=126820 - ;; - "unrestricted") - n_nodes_max=8 - n_cpt_max=24 - n_cpn=48 - runtime_max="infinite" - node_memory=262499 - ;; - *) - echo "Global queue ${global_queue} is not recognised!" - exit - ;; - esac - #---------------------------------------------------------------------------------------# - ;; -sdumont*) - #----- SantosDumont. -------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #----- Set parameters according to partitions. -----------------------------------------# case ${global_queue} in cpu_long|nvidia_long) n_nodes_max=10 @@ -290,15 +336,78 @@ sdumont*) esac #---------------------------------------------------------------------------------------# ;; -*) - #----- Computer is not listed. Crash. -------------------------------------------------# - echo " Invalid computer ${ordinateur}. Check queue settings in the script." - exit 31 +CANNON) + #----- Set parameters according to partitions. -----------------------------------------# + case ${global_queue} in + "commons") + n_nodes_max=5 + n_cpt_max=18 + n_cpn=32 + runtime_max="14-00:00:00" + node_memory=244660 + ;; + "huce_cascade") + n_nodes_max=30 + n_cpt_max=48 + n_cpn=24 + runtime_max="14-00:00:00" + node_memory=183240 + ;; + "huce_intel") + n_nodes_max=150 + n_cpt_max=12 + n_cpn=24 + runtime_max="14-00:00:00" + node_memory=122090 + ;; + "serial_requeue") + n_nodes_max=900 + n_cpt_max=24 + n_cpn=48 + runtime_max="7-00:00:00" + node_memory=30362 + ;; + "shared,huce_intel"|"huce_intel,shared") + n_nodes_max=150 + n_cpt_max=12 + n_cpn=24 + runtime_max="7-00:00:00" + node_memory=122090 + ;; + "shared") + n_nodes_max=220 + n_cpt_max=24 + n_cpn=48 + runtime_max="7-00:00:00" + node_memory=183240 + ;; + "test") + n_nodes_max=9 + n_cpt_max=24 + n_cpn=48 + runtime_max="08:00:00" + node_memory=183240 + ;; + "unrestricted") + n_nodes_max=4 + n_cpt_max=24 + n_cpn=48 + runtime_max="infinite" + node_memory=183240 + ;; + *) + echo "Global queue ${global_queue} is not recognised!" + exit + ;; + esac #---------------------------------------------------------------------------------------# ;; esac #------------------------------------------------------------------------------------------# -if [ ${n_cpt} -gt ${n_cpt_max} ] + + +#----- Check that the resources requested are reasonable. ---------------------------------# +if [[ ${n_cpt} -gt ${n_cpt_max} ]] then echo " Too many CPUs per task requested:" echo " Queue = ${global_queue}" @@ -435,36 +544,31 @@ esac #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_cpn} let node_memory=${n_cpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 -else - #------ Set memory and number of CPUs per task. ----------------------------------------# - let n_cpn_try=${node_memory}/${sim_memory} - if [ ${n_cpn_try} -le ${n_cpn} ] - then - n_cpn=${n_cpn_try} - let sim_memory=${node_memory}/${n_cpn} - else - let node_memory=${n_cpn}*${sim_memory} - fi - #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# +#----- Limit the memory per CPU based on the simulation memory. ---------------------------# +let cpu_memory=${sim_memory}/${n_cpt} +#------------------------------------------------------------------------------------------# + + #---- Partial or complete. ----------------------------------------------------------------# + if ${partial} then let ff=${polya}-1 let polyz=${ff}+${npartial} - if [ ${polyz} -gt ${npolys} ] + if [[ ${polyz} -gt ${npolys} ]] then polyz=${npolys} fi @@ -491,19 +595,20 @@ let ntasks=1+${polyz}-${polya} echo "------------------------------------------------" echo " Submission summary: " echo "" -echo " Memory per cpu: ${sim_memory}" +echo " Memory per task: ${sim_memory}" +echo " Memory per cpu: ${cpu_memory}" echo " CPUs per node: ${n_cpn}" echo " CPUs per task: ${n_cpt}" -echo " Queue: ${global_queue}" +echo " Partition: ${global_queue}" echo " Run time: ${runtime}" echo " First polygon: ${polya}" echo " Last polygon: ${polyz}" echo " Potl. task count: ${ntasks}" -echo " Job Name: ${jobname}" echo " Total polygon count: ${npolys}" echo " " echo " Partial submission: ${partial}" echo " Automatic submission: ${submit}" +echo " Script: $(basename ${sbatch})" echo "------------------------------------------------" echo "" echo -n " Waiting five seconds before proceeding... " @@ -514,88 +619,132 @@ echo "Done!" #------------------------------------------------------------------------------------------# -# Check whether there is already a job submitted that looks like this one. # -#------------------------------------------------------------------------------------------# -queued=$(${squeue} -o "${outform}" | grep ${jobname} | wc -l) -if [ ${queued} -gt 0 ] -then - echo "There is already a job called \"${jobname}\" running." - echo "New submissions must have different names: be creative!" - exit 99 -fi +# Initialise executable. This depends on the cluster because in some of them it is # +# better to submit a single multi-task job, whereas in others it makes more sense to # +# submit individual jobs. # #------------------------------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #---------------------------------------------------------------------------------------# + # Check whether there is already a job submitted that looks like this one. # + #---------------------------------------------------------------------------------------# + queued=$(${squeue} -o "${outform}" | grep ${jobname} | wc -l) + if [[ ${queued} -gt 0 ]] + then + echo "There is already a job called \"${jobname}\" running." + echo "New submissions must have different names: be creative!" + exit 99 + fi + #---------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Initialise executable. # -#------------------------------------------------------------------------------------------# -rm -f ${sbatch} -touch ${sbatch} -chmod u+x ${sbatch} -echo "#!/bin/bash" >> ${sbatch} -echo "#SBATCH --ntasks=myntasks # Number of tasks" >> ${sbatch} -echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${sbatch} -echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} -echo "#SBATCH --job-name=${jobname} # Job name" >> ${sbatch} -echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} -echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} -echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} -echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Initial settings." >> ${sbatch} -echo "here=\"${here}\" # Main path" >> ${sbatch} -echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Print information about this job." >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"----- Summary of current job ---------------------------------\"" >> ${sbatch} -echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} -echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} -echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} -echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} -echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} -echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} -echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} -echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} -echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} -echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} -echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "echo \"----- Global settings for this array of simulations ----------\"" >> ${sbatch} -echo "echo \" Main path: \${here}\"" >> ${sbatch} -echo "echo \" Executable: \${exec}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Define home in case home is not set" >> ${sbatch} -echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export HOME=\$(echo ~)" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Load modules and settings." >> ${sbatch} -echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Get plenty of memory." >> ${sbatch} -echo "ulimit -s unlimited" >> ${sbatch} -echo "ulimit -u unlimited" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Set OpenMP parameters" >> ${sbatch} -echo "if [ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export OMP_NUM_THREADS=1" >> ${sbatch} -echo "else" >> ${sbatch} -echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Task list." >> ${sbatch} + #----- Initialise script to submit a single multi-task job. ----------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "#SBATCH --ntasks=myntasks # Number of tasks" >> ${sbatch} + echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${sbatch} + echo "#SBATCH --cores-per-socket=${n_cpt} # Min. # of cores per socket" >> ${sbatch} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} + echo "#SBATCH --job-name=${jobname} # Job name" >> ${sbatch} + echo "#SBATCH --mem-per-cpu=${cpu_memory} # Memory per CPU" >> ${sbatch} + echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Print information about this job." >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"----- Summary of current job ------------------------------\"" >> ${sbatch} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} + echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Set OpenMP parameters" >> ${sbatch} + echo "if [ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export OMP_NUM_THREADS=1" >> ${sbatch} + echo "else" >> ${sbatch} + echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +CANNON) + #----- Initialise script to submit multiple single-task jobs. --------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Job list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +esac #------------------------------------------------------------------------------------------# @@ -604,7 +753,7 @@ echo "#----- Task list." > # Loop over all polygons. # #------------------------------------------------------------------------------------------# n_submit=0 -while [ ${ff} -lt ${polyz} ] +while [[ ${ff} -lt ${polyz} ]] do let ff=${ff}+1 let line=${ff}+3 @@ -613,13 +762,13 @@ do #---------------------------------------------------------------------------------------# # Format count. # #---------------------------------------------------------------------------------------# - if [ ${npolys} -lt 100 ] + if [[ ${npolys} -lt 100 ]] then ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -lt 1000 ] + elif [[ ${npolys} -lt 1000 ]] then ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -lt 10000 ] + elif [[ ${npolys} -lt 10000 ]] then ffout=$(printf '%4.4i' ${ff}) else @@ -635,142 +784,190 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case this is an "init_only" run, impose final time to be the initial time. # + #---------------------------------------------------------------------------------------# + if ${init_only} + then + yearz=${yeara} + monthz=${montha} + datez=${datea} + timez=${timea} + fi + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. -------------# + taskname="${polyname}" + #------------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. -----------------------# + taskname="${desc}-${polyname}" + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Check whether there is already a job submitted that looks like this one. # + #------------------------------------------------------------------------------------# + queued=$(${squeue} -o "${outform}" | grep ${taskname} | wc -l) + if [[ ${queued} -gt 0 ]] + then + echo "There is already a job called \"${taskname}\" running." + echo "New submissions must have different names: be creative!" + exit 99 + fi + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Decide units for restart files. # #---------------------------------------------------------------------------------------# let elapseda=12*${yeara}+${montha} let elapsedz=12*${yearz}+${monthz} let nmonths=${elapsedz}-${elapseda} - if [ ${nmonths} -ge 240 ] + if [[ ${nmonths} -ge 240 ]] then iunitstate=3 - elif [ ${nmonths} -ge 3 ] + elif [[ ${nmonths} -ge 3 ]] then iunitstate=2 else @@ -780,7 +977,7 @@ do #----- Check whether the directories exist or not, and stop the script if they do. -----# - if [ -s ${here}/${polyname} ] + if [[ -s ${here}/${polyname} ]] then echo -n "${ffout} ${polyname}: updating files..." @@ -804,7 +1001,7 @@ do #---------------------------------------------------------------------------------------# # Make sure that we have a reasonable tolerance. # #---------------------------------------------------------------------------------------# - if [ "x${oldtol}" == "xmytoler" -o "x${oldtol}" == "x" ] + if [[ "x${oldtol}" == "xmytoler" ]] || [[ "x${oldtol}" == "x" ]] then toler=${toldef} else @@ -822,28 +1019,28 @@ do # we simply copy the template, and assume initial run. Otherwise, we must find out # # where the simulation was when it stopped. # #---------------------------------------------------------------------------------------# - if [ -s ${here}/${polyname} ] + if [[ -s ${here}/${polyname} ]] then #------------------------------------------------------------------------------------# # This step is necessary because we may have killed the run while it was # # writing, and as a result, the file may be corrupt. # #------------------------------------------------------------------------------------# - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) - if [ ${nhdf5} -gt 0 ] + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) + if [[ ${nhdf5} -gt 0 ]] then h5fine=0 - while [ ${h5fine} -eq 0 ] + while [[ ${h5fine} -eq 0 ]] do - lasthdf5=$(ls -1 ${here}/${polyname}/histo/* | tail -1) + lasthdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 | tail -1) h5dump -H ${lasthdf5} 1> /dev/null 2> ${here}/badfile.txt - if [ -s ${here}/badfile.txt ] + if [[ -s ${here}/badfile.txt ]] then /bin/rm -fv ${lasthdf5} - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) - if [ ${nhdf5} -eq 0 ] + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) + if [[ ${nhdf5} -eq 0 ]] then h5fine=1 fi @@ -883,7 +1080,7 @@ do sed -i~ s@thisnyearmin@10000@g ${whichrun} sed -i~ s@thisststcrit@0.0@g ${whichrun} R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - while [ ! -s ${here}/${polyname}/statusrun.txt ] + while [[ ! -s ${here}/${polyname}/statusrun.txt ]] do sleep 0.2 done @@ -895,13 +1092,42 @@ do #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Run the small R script to generate specific observation times. # + #---------------------------------------------------------------------------------------# + /bin/rm -f ${here}/${polyname}/gen_obstimes.r + /bin/cp -f ${here}/Template/gen_obstimes.r ${here}/${polyname}/gen_obstimes.r + obstimes="${here}/${polyname}/gen_obstimes.r" + outtimes="${here}/${polyname}/out_obstimes.txt" + sed -i~ s@thispoly@${polyname}@g ${obstimes} + sed -i~ s@thisqueue@${queue}@g ${obstimes} + sed -i~ s@pathhere@${here}@g ${obstimes} + sed -i~ s@paththere@${here}@g ${obstimes} + sed -i~ s@thisyeara@${yeara}@g ${obstimes} + sed -i~ s@thismontha@${montha}@g ${obstimes} + sed -i~ s@thisdatea@${datea}@g ${obstimes} + sed -i~ s@thistimea@${timea}@g ${obstimes} + sed -i~ s@thisyearz@${yearz}@g ${obstimes} + sed -i~ s@thismonthz@${monthz}@g ${obstimes} + sed -i~ s@thisdatez@${datez}@g ${obstimes} + sed -i~ s@thistimez@${timez}@g ${obstimes} + sed -i~ s@thislon@${polylon}@g ${obstimes} + sed -i~ s@thislat@${polylat}@g ${obstimes} + R CMD BATCH --no-save --no-restore ${obstimes} ${outtimes} + while [[ ! -s ${here}/${polyname}/${polyname}_obstimes.txt ]] + do + sleep 0.2 + done + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # To ensure simulations can be requeued, we no longer set RUNTYPE to INITIAL or # # HISTORY (except when we should force history). Instead, we select RESTORE and let # # the model decide between initial or history. # #---------------------------------------------------------------------------------------# - if [ "${runt}" == "INITIAL" ] || [ "${runt}" == "HISTORY" ] + if [[ "${runt}" == "INITIAL" ]] || [[ "${runt}" == "HISTORY" ]] then runt="RESTORE" fi @@ -1139,6 +1365,16 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). -----------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; + ERA5_CHIRPS) + #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# + scentype="ERA_Interim" + iscenario="ERAINT_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# scentype="ERA_Interim" @@ -1189,6 +1425,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# scentype="WFDEI" @@ -1277,6 +1518,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1427,6 +1674,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1464,7 +1717,7 @@ do # Correct years so it is not tower-based or Sheffield. # #---------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) echo "Nothing" > /dev/null ;; *) @@ -1521,6 +1774,12 @@ do ;; esac ;; + sa2-ril) + ludatabase="${lumain}/SimAmazonia2/ril/sa2_ril_" + ;; + sa2-cvl) + ludatabase="${lumain}/SimAmazonia2/cvl/sa2_cvl_" + ;; lurcp26) ludatabase="${lumain}/luh-1.1+rcp26_image/luh-1.1+rcp26_image-" ;; @@ -1538,7 +1797,7 @@ do # Stop the script if anthropogenic dataset is invalid and this is a simulation # # with anthropogenic disturbance. # #------------------------------------------------------------------------------------# - if [ ${ianthdisturb} -eq 1 ] + if [[ ${ianthdisturb} -eq 1 ]] then echo " Polygon: ${polyname}" echo " IATA: ${polyiata}" @@ -1558,13 +1817,13 @@ do # Define whether we use the met cycle to define the first and last year, or the # # default year. # #---------------------------------------------------------------------------------------# - if [ ${yeara} -eq 0 ] + if [[ ${yeara} -eq 0 ]] then thisyeara=${metcyc1} else thisyeara=${yeara} fi - if [ ${yearz} -eq 0 ] + if [[ ${yearz} -eq 0 ]] then thisyearz=${metcycf} else @@ -1641,8 +1900,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-4.032,-3.584,-3.159,-2.757,-2.377,-2.021,-1.689,-1.382,-1.101," - polyslz2="-0.846,-0.620,-0.424,-0.260,-0.130,-0.040" + polyslz1="-5.000,-4.468,-3.963,-3.483,-3.030,-2.604,-2.205,-1.836,-1.495,-1.185," + polyslz2="-0.906,-0.660,-0.447,-0.271,-0.134,-0.040" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1676,6 +1935,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.934,-6.934,-5.999,-5.131,-4.329,-3.593,-2.925,-2.324,-1.790," + polyslz2="-1.325,-0.928,-0.600,-0.342,-0.155,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.223,-8.029,-6.919,-5.891,-4.946,-4.084,-3.305,-2.609,-1.995," polyslz2="-1.464,-1.015,-0.648,-0.364,-0.161,-0.040" @@ -1684,6 +1952,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.51,-9.118,-7.828,-6.640,-5.552,-4.563,-3.674,-2.883,-2.191" + polyslz2="-1.595,-1.096,-0.693,-0.383,-0.166,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -1783,8 +2060,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-3.967,-3.467,-3.000,-2.565,-2.164,-1.797,-1.462,-1.162,-0.895," - polyslz2="-0.662,-0.464,-0.300,-0.171,-0.077,-0.020" + polyslz1="-5.000,-4.397,-3.833,-3.307,-2.819,-2.371,-1.961,-1.590,-1.257,-0.964," + polyslz2="-0.709,-0.493,-0.316,-0.178,-0.080,-0.020" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1818,6 +2095,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.807,-6.706,-5.696,-4.775,-3.942,-3.195,-2.533,-1,954,-1.456," + polyslz2="-1.037,-0.694,-0.424,-0.225,-0.092,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.076,-7.766,-6.569,-5.482,-4.504,-3.631,-2.862,-2.194,-1.622," polyslz2="-1.145,-0.759,-0.458,-0.239,-0.096,-0.020" @@ -1826,6 +2112,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.34,-8.818,-7.432,-6.179,-5.055,-4.057,-3.182,-2.425,-1.782" + polyslz2="-1.248,-0.820,-0.490,-0.252,-0.099,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -2072,7 +2367,7 @@ do #----- Check whether to use SFILIN as restart or history. ------------------------------# - if [ ${runt} == "RESTORE" ] && [ ${forcehisto} -eq 1 ] + if [[ ${runt} == "RESTORE" ]] && [[ ${forcehisto} -eq 1 ]] then runt="HISTORY" year=${yearh} @@ -2080,141 +2375,192 @@ do date=${dateh} time=${timeh} thissfilin=${fullygrown} - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 5 ] - then - if [ ! -s ${restart} ] - then - echo " Directory restart does not exist!" - echo " Change the variable restart at the beginning of the script" - exit 44 - else - runt="RESTORE" - thissfilin=${restart} - fi - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 6 ] + elif [[ ${runt} == "RESTORE" ]] then - thissfilin=${fullygrown} - - - - #------------------------------------------------------------------------------------# - # Find the biometric files. This has been checked in spawn_poly.sh so they are # - # correct. Add a dummy name in case this is not supposed to be a biomass # - # initialisation run. # - #------------------------------------------------------------------------------------# - case ${biotype} in - 0) - #----- isizepft controls everything, and iage is ignored. ------------------------# - case ${isizepft} in - 0) - #----- Frankeinstein's under storey. ------------------------------------------# - thissfilin="${bioinit}/${polyiata}_default." - ;; - 1) - #----- No under storey. -------------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_nounder." - ;; - 2) - #----- ALS initialisation. ----------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_alsinit." - ;; - *) - #----- Invalid option. Stop the script. ---------------------------------------# - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 57 - ;; - esac - #---------------------------------------------------------------------------------# - ;; - - 1) + case ${initmode} in + 5|7) #---------------------------------------------------------------------------------# - # 'isizepft' controls how many PFTs to use. # + # Initialise ED2 with hdf5 files, which should be in directory restart. # #---------------------------------------------------------------------------------# - case ${isizepft} in - 0|5) - pftname="pft05" - ;; - 2) - pftname="pft02" - ;; - esac + if [[ ! -s ${restart} ]] + then + echo " Directory restart does not exist!" + echo " Change the variable restart at the beginning of the script" + exit 44 + else + runt="RESTORE" + thissfilin=${restart} + fi #---------------------------------------------------------------------------------# + ;; + 1|2|3|6|8) #---------------------------------------------------------------------------------# - # 'iage' controls how many patches to use. # + # Find the biometric files. This has been checked in spawn_poly.sh so they # + # are correct. Add a dummy name in case this is not supposed to be a biomass # + # initialisation run. # #---------------------------------------------------------------------------------# - case ${iage} in - 1) - agename="age01" - ;; - *) - agename="age00" + case ${biotype} in + 0) + #----- isizepft controls everything, and iage is ignored. ---------------------# + case ${isizepft} in + 0) + #----- Frankeinstein's under storey. ---------------------------------------# + thissfilin="${bioinit}/${polyiata}_default." + ;; + 1) + #----- No under storey. ----------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_nounder." + ;; + 2) + #----- ALS initialisation. -------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_alsinit." + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initialised with these ISIZEPFT and INITMODE!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Check whether the site has the PFT and age structure. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - hvd|s77|fns|cau|and|par|tap|dcm) - thissfilin="${bioinit}/${polyiata}_default." + 1) + #------------------------------------------------------------------------------# + # 'isizepft' controls how many PFTs to use. # + #------------------------------------------------------------------------------# + case ${isizepft} in + 0|5) + pftname="pft05" + ;; + 2) + pftname="pft02" + ;; + esac + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # 'iage' controls how many patches to use. # + #------------------------------------------------------------------------------# + case ${iage} in + 1) + agename="age01" + ;; + *) + agename="age00" + ;; + esac + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether the site has the PFT and age structure. # + #------------------------------------------------------------------------------# + case ${polyiata} in + hvd|s77|fns|cau|and|par|tap|dcm) + thissfilin="${bioinit}/${polyiata}_default." + ;; + cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) + thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + ;; + *) + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " IAGE: ${iage}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 59 + ;; + esac + #------------------------------------------------------------------------------# ;; - cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) - thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + 2) + #------------------------------------------------------------------------------# + # ALS initialisation. ISIZEPFT has disturbance history information. # + #------------------------------------------------------------------------------# + case ${polyiata} in + l[0-5][0-3]) + thissfilin="${alsinit}/${polyiata}." + ;; + *) + thissfilin="${alsinit}/${polyiata}_${isizepft}." + ;; + esac + #------------------------------------------------------------------------------# ;; - *) - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " IAGE: ${iage}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 59 + 3) + #------------------------------------------------------------------------------# + # ALS initialisation using intensity. ISIZEPFT has disturbance history # + # information. # + #------------------------------------------------------------------------------# + thissfilin="${intinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - ;; - 2) - #---------------------------------------------------------------------------------# - # ALS initialisation. ISIZEPFT has disturbance history information. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - l[0-5][0-3]) - thissfilin="${alsinit}/${polyiata}." + 4) + #------------------------------------------------------------------------------# + # ALS initialisation using the lookup table. ISIZEPFT has disturbance # + # history information. # + #------------------------------------------------------------------------------# + thissfilin="${lutinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - *) - thissfilin="${alsinit}/${polyiata}_${isizepft}." + 5) + #----- isizepft controls actual or majestic initialisation. -------------------# + case ${isizepft} in + 0) + #----- Actual sampling. ----------------------------------------------------# + thissfilin="${ebainit}/eba_actual_default." + #---------------------------------------------------------------------------# + ;; + 1) + #----- Majestic sampling. --------------------------------------------------# + thissfilin="${ebainit}/eba_majestic_default." + #---------------------------------------------------------------------------# + ;; + 2) + #----- Actual sampling + land use (pasture/cropland/plantation). -----------# + thissfilin="${ebainit}/eba_luactual_default." + #---------------------------------------------------------------------------# + ;; + 3) + #----- Majestic sampling + land use (pasture/cropland/plantation). ---------# + thissfilin="${ebainit}/eba_lumajestic_default." + #---------------------------------------------------------------------------# + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------# ;; - 3) - #---------------------------------------------------------------------------------# - # ALS initialisation using intensity. ISIZEPFT has disturbance history # - # information. # - #---------------------------------------------------------------------------------# - thissfilin="${intinit}/${polyiata}_${isizepft}." + *) + #----- No initial file needed; set the history file. -----------------------------# + thissfilin=${here}/${polyname}/histo/${polyname} #---------------------------------------------------------------------------------# ;; - 4) - #---------------------------------------------------------------------------------# - # ALS initialisation using the lookup table. ISIZEPFT has disturbance history # - # information. # - #---------------------------------------------------------------------------------# - thissfilin="${lutinit}/${polyiata}_${isizepft}." #---------------------------------------------------------------------------------# - ;; esac #------------------------------------------------------------------------------------# else + #----- Set the history file. --------------------------------------------------------# thissfilin=${here}/${polyname}/histo/${polyname} + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -2381,6 +2727,7 @@ do sed -i~ s@mydbhharv@${dbhharv}@g ${ED2IN} sed -i~ s@mybioharv@${bioharv}@g ${ED2IN} sed -i~ s@myskidarea@${skidarea}@g ${ED2IN} + sed -i~ s@myskiddbhthresh@${skiddbhthresh}@g ${ED2IN} sed -i~ s@myskidsmall@${skidsmall}@g ${ED2IN} sed -i~ s@myskidlarge@${skidlarge}@g ${ED2IN} sed -i~ s@myfellingsmall@${fellingsmall}@g ${ED2IN} @@ -2426,11 +2773,137 @@ do exec_sub=${exec_full} ;; esac + #---------------------------------------------------------------------------------------# + + - #----- Change the callserial.sh file. --------------------------------------------------# + #----- Script names. -------------------------------------------------------------------# + tempserial="${here}/Template/callserial.sh" callserial="${here}/${polyname}/callserial.sh" - rm -f ${callserial} - cp -f ${here}/Template/callserial.sh ${callserial} + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Set script callserial.sh. Depending on the settings (single multi-task jobs or # + # multiple single-task jobs), we must update the header. # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #------------------------------------------------------------------------------------# + # Single multi task job, callserial.sh doesn't need header updates. # + #------------------------------------------------------------------------------------# + /bin/rm -f ${callserial} + /bin/cp -f ${tempserial} ${callserial} + #------------------------------------------------------------------------------------# + ;; + CANNON) + #------------------------------------------------------------------------------------# + # Update header with sbatch instructions for multiple single task jobs. # + #------------------------------------------------------------------------------------# + + #----- Output files. ----------------------------------------------------------------# + obatch="${here}/${polyname}/serial_slm.out" + ebatch="${here}/${polyname}/serial_slm.err" + #------------------------------------------------------------------------------------# + + #----- Initialise the callserial.sh file. -------------------------------------------# + rm -f ${callserial} + touch ${callserial} + chmod u+x ${callserial} + echo "#!/bin/bash" >> ${callserial} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${callserial} + echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${callserial} + echo "#SBATCH --cores-per-socket=${n_cpt} # Min. # of cores/socket" >> ${callserial} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${callserial} + echo "#SBATCH --job-name=${taskname} # Job name" >> ${callserial} + echo "#SBATCH --mem-per-cpu=${cpu_memory} # Memory per CPU" >> ${callserial} + echo "#SBATCH --time=${runtime} # Time for job" >> ${callserial} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${callserial} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${callserial} + echo "#SBATCH --chdir=${here}/${polyname} # Main directory" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Initial settings." >> ${callserial} + echo "here=\"${here}\" # Main path" >> ${callserial} + echo "exec=\"${exec_full}\" # Executable" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Print information about this job." >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"----- Summary of current job -----------------------\"" >> ${callserial} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${callserial} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${callserial} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${callserial} + echo "echo \" Partition: \${SLURM_JOB_PARTITION}\"" >> ${callserial} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${callserial} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${callserial} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${callserial} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${callserial} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${callserial} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${callserial} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${callserial} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${callserial} + echo "echo \"----------------------------------------------------\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "" >> ${callserial} + echo "echo \"----- Global settings for this simulation. ---\"" >> ${callserial} + echo "echo \" Main path: \${here}\"" >> ${callserial} + echo "echo \" Executable: \${exec}\"" >> ${callserial} + echo "echo \"----------------------------------------------------\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Define home in case home is not set" >> ${callserial} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${callserial} + echo "then" >> ${callserial} + echo " export HOME=\$(echo ~)" >> ${callserial} + echo "fi" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Load modules and settings." >> ${callserial} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Get plenty of memory." >> ${callserial} + echo "ulimit -s unlimited" >> ${callserial} + echo "ulimit -u unlimited" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Set OpenMP parameters" >> ${callserial} + echo "if [[ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]]" >> ${callserial} + echo "then" >> ${callserial} + echo " export OMP_NUM_THREADS=1" >> ${callserial} + echo "else" >> ${callserial} + echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${callserial} + echo "fi" >> ${callserial} + echo "" >> ${callserial} + #------------------------------------------------------------------------------------# + + + + #----- Append the template callserial.sh, skipping the first line. ------------------# + tail -n +2 ${tempserial} >> ${callserial} + #------------------------------------------------------------------------------------# + + + #----- Make sure the script waits until all tasks are completed... ------------------# + echo "" >> ${callserial} + echo "" >> ${callserial} + echo "#----- Ensure that jobs complete before terminating script." >> ${callserial} + echo "wait" >> ${callserial} + echo "" >> ${callserial} + echo "#----- Report efficiency of this job." >> ${callserial} + echo "seff \${SLURM_JOBID}" >> ${callserial} + echo "" >> ${callserial} + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# + + + #----- Substitute placeholders with specific data. -------------------------------------# sed -i s@thisroot@${here}@g ${callserial} sed -i s@thispoly@${polyname}@g ${callserial} sed -i s@myname@${moi}@g ${callserial} @@ -2459,9 +2932,16 @@ do "EXTINCT") echo "Polygon population has gone extinct. No need to re-submit it." ;; - "CRASHED"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") - echo "Polygon has serious errors. Script will not submit any job this time." - submit=false + "CRASHED"|"HYDFAIL"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") + #----- Decide whether to skip this job submission or every job submission. ----------# + if ${on_the_fly} + then + echo "Polygon has serious errors. Script will not submit this job." + else + echo "Polygon has serious errors. Script will not submit any job this time." + submit=false + fi + #------------------------------------------------------------------------------------# ;; "RESTORE"|"HISTORY") @@ -2471,25 +2951,79 @@ do #------------------------------------------------------------------------------------# echo " Polygon scheduled for submission." let n_submit=${n_submit}+1 - let dtwait=${dtwait}+2 #------------------------------------------------------------------------------------# - #----- Append job to submission list. -----------------------------------------------# - srun="srun --nodes=1 --ntasks=1 --cpu_bind=cores" - srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" - srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" - srun="${srun} --job-name=${polyname}" - srun="${srun} --chdir=\${here}/${polyname}" - srun="${srun} --output=\${here}/${polyname}/serial_slm.out" - srun="${srun} --error=\${here}/${polyname}/serial_slm.err" - echo "${srun} \${here}/${polyname}/callserial.sh &" >> ${sbatch} - echo "sleep ${dttask}" >> ${sbatch} + #------------------------------------------------------------------------------------# + # Set command to the main script. Again, this depends on the type of job # + # submission. # + #------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #---------------------------------------------------------------------------------# + # Append task in the single multi-task job script. # + #---------------------------------------------------------------------------------# + srun="srun --nodes=1 --ntasks=1 --cpu_bind=cores" + srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" + srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" + srun="${srun} --job-name=${polyname}" + srun="${srun} --chdir=\${here}/${polyname}" + srun="${srun} --output=\${here}/${polyname}/serial_slm.out" + srun="${srun} --error=\${here}/${polyname}/serial_slm.err" + echo "${srun} \${here}/${polyname}/callserial.sh &" >> ${sbatch} + echo "sleep ${dttask}" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + #---------------------------------------------------------------------------------# + # Make sure we don't exceed the maximum number of jobs. # + #---------------------------------------------------------------------------------# + if [[ ${n_submit} -gt ${n_tasks_max} ]] && ${on_the_fly} + then + echo " Number of jobs to submit: ${n_submit}" + echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" + echo " Reduce the number of simulations or try another queue..." + echo " Appending remaining jobs to $(basename ${sbatch}) for later submission." + on_the_fly=false + fi + #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # If on the fly, submit the job now. Otherwise, append job to sbatch. # + #---------------------------------------------------------------------------------# + if ${on_the_fly} + then + #----- Submit job on the fly. -------------------------------------------------# + sbatch ${callserial} + #------------------------------------------------------------------------------# + else + #------------------------------------------------------------------------------# + # Append submission to the script to submit the multiple single-task jobs. # + #------------------------------------------------------------------------------# + echo "echo \" + ${ffout}/${ntasks}. Submit job: ${polyname}.\"" >> ${sbatch} + echo "sbatch ${callserial}" >> ${sbatch} + echo "sleep ${dttask}" >> ${sbatch} + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + + ;; + esac #------------------------------------------------------------------------------------# ;; *) - echo "Unknown polygon state (${runt})! Script will not submit any job this time." - submit=false + #------------------------------------------------------------------------------------# + # Unknown state, either skip this job submission, or every job submission. # + #------------------------------------------------------------------------------------# + if ${on_the_fly} + then + echo "Unknown polygon state (${runt})! Script will not submit this job." + else + echo "Unknown polygon state (${runt})! Script will not submit any job this time." + submit=false + fi + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -2497,41 +3031,86 @@ done #------------------------------------------------------------------------------------------# - #------------------------------------------------------------------------------------------# -# Make sure job list doesn't request too many nodes. # +# Update the main submission script to reflect the correct number of tasks (done only # +# when running a single multi-task job). # #------------------------------------------------------------------------------------------# -if [ ${n_submit} -gt ${n_tasks_max} ] -then - echo " Number of jobs to submit: ${n_submit}" - echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" - echo " Reduce the number of simulations or try another queue..." - exit 99 -else +case "${cluster}" in +SDUMONT) #----- Update the number of tasks in batch script. -------------------------------------# sed -i~ s@myntasks@${n_submit}@g ${sbatch} #---------------------------------------------------------------------------------------# -fi + ;; +esac #------------------------------------------------------------------------------------------# -#----- Make sure the script waits until all tasks are completed... ------------------------# -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Make sure that jobs complete before terminating script" >> ${sbatch} -echo "wait" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Report efficiency of this job" >> ${sbatch} -echo "seff \${SLURM_JOBID}" >> ${sbatch} -echo "" >> ${sbatch} -#------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# In case all looks good, go for it! # +# Make sure job list doesn't request too many nodes. # #------------------------------------------------------------------------------------------# -if ${submit} +if ! ${on_the_fly} then - sbatch ${sbatch} + if [[ ${n_submit} -gt ${n_tasks_max} ]] + then + echo " Number of jobs to submit: ${n_submit}" + echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" + echo " Reduce the number of simulations or try another queue..." + exit 99 + elif ${submit} + then + echo " Submitting jobs." + #------- How we submit depends on the cluster. --------------------------------------# + case "${cluster}" in + SDUMONT) + #---------------------------------------------------------------------------------# + # Single multi-task job. Submit the main script using sbatch. # + #---------------------------------------------------------------------------------# + sbatch ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + #---------------------------------------------------------------------------------# + # Multiple single-task jobs. Run the script, the sbatch commands are in # + # there. # + #---------------------------------------------------------------------------------# + ${sbatch} + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + else + #------- Provide instructions to the user for a later submission. -------------------# + case "${cluster}" in + SDUMONT) + #----- Instruct the user to use sbatch. ------------------------------------------# + echo "-------------------------------------------------------------------------" + echo " To submit the simulations, you must use sbatch. " + echo " Copy and paste the following command in the terminal. " + echo " " + echo " sbatch ${sbatch}" + echo " " + #---------------------------------------------------------------------------------# + ;; + CANNON) + #----- Instruct the user NOT to use sbatch. --------------------------------------# + echo "-------------------------------------------------------------------------" + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo "-------------------------------------------------------------------------" + echo " Do NOT use sbatch ${sbatch}." + echo " Instead, call the following script directly in your terminal." + echo " " + echo " ${sbatch}" + echo " " + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/transfer.sh b/ED/Template/scripts/SLURM/transfer.sh deleted file mode 100755 index f2c39f890..000000000 --- a/ED/Template/scripts/SLURM/transfer.sh +++ /dev/null @@ -1,304 +0,0 @@ -#!/bin/bash - -#==========================================================================================# -#==========================================================================================# -# Main settings: # -#------------------------------------------------------------------------------------------# -#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# -here="" -#----- Location to create the copy of these files. ----------------------------------------# -there="" -#----- File containing the list of jobs and their settings: -------------------------------# -joborder="${here}/joborder.txt" -#----- Command to be used for rsync. ------------------------------------------------------# -frsync="rsync -Putq --links --copy-unsafe-links" -rrsync="rsync -Prutq --links --copy-unsafe-links" -#------------------------------------------------------------------------------------------# - - - - - -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -# Unless you are going to modify the scripts, you don't need to change anything beyond # -# this point. # -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# - - -#------------------------------------------------------------------------------------------# -# First check that the main path and e-mail have been set. If not, don't run. # -#------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${there}" == "x" ] -then - echo " You must set some variables before running the script:" - echo " Check variables \"here\" and \"there\"!" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -if [[ "${here}" == "${there}" ]] -then - echo " Source and destination paths are the same. Transfer is not needed." - exit 0 -elif [[ -s ${here}/transfer.lock ]] -then - echo " Script transfer is running. Skip transfer for the time being." - exit -else - echo "I am going to back up your run." > ${here}/transfer.lock -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Create the output path in case it isn't there. # -#------------------------------------------------------------------------------------------# -if [ ! -s ${there} ] -then - echo "Create backup path: ${there}." - mkdir -p ${there} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# First, copy the files at the basal directory. # -#------------------------------------------------------------------------------------------# -echo " + Copy files from the main directory." -${frsync} ${here}/* ${there} -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Then copy the fixed directories. # -#------------------------------------------------------------------------------------------# -echo " + Copy executable." -${rrsync} ${here}/executable ${there} -echo " + Copy sit_utils." -${rrsync} ${here}/sit_utils ${there} -echo " + Copy Template." -${rrsync} ${here}/Template ${there} -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - - #---------------------------------------------------------------------------------------# - # Format count. # - #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] - then - ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] - then - ffout=$(printf '%4.4i' ${ff}) - else - ffout=${ff} - fi - ffout="${ffout} of ${npolys}" - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #----- Check whether the directories exist or not, and stop the script if they do. -----# - if [ -s ${here}/${polyname} ] - then - echo -n " + Copy ${polyname} (${ffout})." - - #----- Sync this directory. ---------------------------------------------------------# - ${rrsync} ${here}/${polyname} ${there} - #------------------------------------------------------------------------------------# - - echo "Done!" - else - echo " + Skip ${polyname} (${ffout})." - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - -#----- Clean-up stuff. --------------------------------------------------------------------# -echo " Unlock transfer.sh." -/bin/rm -f ${here}/transfer.lock -echo "==== transfer.sh execution ends. ====" -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/sit_utils/plot.region.r b/ED/Template/sit_utils/plot.region.r index bcf263c39..97e907dd4 100644 --- a/ED/Template/sit_utils/plot.region.r +++ b/ED/Template/sit_utils/plot.region.r @@ -4,6 +4,8 @@ #------------------------------------------------------------------------------------------# rm(list=ls()) graphics.off() +gc() +options(warn=0) #==========================================================================================# #==========================================================================================# @@ -16,10 +18,16 @@ graphics.off() #----- Paths. -----------------------------------------------------------------------------# -main = "/n/moorcroftfs2/mlongo/EDBRAMS/final_ed/trop_southam/pve+sas" # Main path. -here = file.path(main,"sit_utils") # This path -srcdir = "/n/home00/mlongo/util/Rsc" # Source directory. -outroot = here # Directory for figures +main = "mypath" # Main path. +here = file.path(main,"sit_utils") # This path +srcdir = c( "/home/mlongo/Util/Rsc" # Possible paths with libraries + , "/Users/mlongo/Util/Rsc" # R will select the first + , "/prj/prjidfca/marcosl/Util/Rsc" # one that is found. + , "/prj/bramsolam/marcos.longo/Util/Rsc" # + , "/scratch/bramsolam/marcos.longo/Util/Rsc" # + , "/n/home00/mlongo/Util/Rsc" # + )#end c # +outroot = here # Directory for figures #------------------------------------------------------------------------------------------# @@ -38,22 +46,56 @@ mycheck = file.path(here,"mycheck.txt" ) #----- Plot options. ----------------------------------------------------------------------# -outform = c("png","eps","pdf") # Formats for output file. Supported formats are: - # - "X11" - for printing on screen - # - "eps" - for postscript printing - # - "png" - for PNG printing - # - "pdf" - for PDF printing -depth = 96 # PNG resolution, in pixels per inch -paper = "letter" # Paper size, to define the plot shape -ptsz = 14 # Font size. -lwidth = 2.5 # Line width -inset = 0.01 # inset between legend and edge of plot region. -fracexp = 0.40 # Expand the y axis by this amount. -ncolours = 20 # Number of colours to split the real variables -mtext.xoff = -8.50 # Offset for the x label -mtext.yoff = -1.00 # Offset for the y label -mtext.xadj = 0.50 # Offset for the x label -mtext.yadj = 0.65 # Offset for the y label +outform = c("png") # Formats for output file. Supported formats are: + # - "X11" - for printing on screen + # - "eps" - for postscript printing + # - "png" - for PNG printing + # - "pdf" - for PDF printing +depth = 96 # PNG resolution, in pixels per inch +paper = "letter" # Paper size, to define the plot shape +ptsz = 16 # Font size. +lwidth = 2.5 # Line width +inset = 0.01 # inset between legend and edge of plot region. +fracexp = 0.40 # Expand the y axis by this amount. +ncolours = 20 # Number of colours to split the real variables +st.leg = 1./5. +ey.leg = 1./6. +#------------------------------------------------------------------------------------------# + + +#------ List of variables to make the maps. -----------------------------------------------# +n = 0 +outvars = list() +n = n + 1 +outvars[[n]] = list( vnam = "lai" + , desc = "Leaf area index" + , unit = "m2lom2" + , csch = "pubugn" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "bsa" + , desc = "Basal area" + , unit = "cm2om2" + , csch = "bupu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "agb" + , desc = "Aboveground carbon" + , unit = "kgcom2" + , csch = "ylgnbu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "scb" + , desc = "Soil carbon" + , unit = "kgcom2" + , csch = "orrd" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "npa" + , desc = "Patch count" + , unit = "empty" + , csch = "magma" + )#end list #------------------------------------------------------------------------------------------# @@ -72,10 +114,18 @@ mtext.yadj = 0.65 # Offset for the y label #==========================================================================================# #==========================================================================================# +#----- Check that directory main has been set. --------------------------------------------# +if (! dir.exists(main)){ + cat (" Main: ",main,"\n") + stop(" Directory main is incorrect or has not been set!!!") +}#end if +#------------------------------------------------------------------------------------------# + #----- Loading some packages and scripts. -------------------------------------------------# +srcdir = (srcdir[file.exists(srcdir)])[1] source(file.path(srcdir,"load.everything.r")) #------------------------------------------------------------------------------------------# @@ -87,20 +137,16 @@ nout = length (outform) #------------------------------------------------------------------------------------------# -#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# -options(locatorBell=FALSE) -#------------------------------------------------------------------------------------------# - - -#----- Define plot window size ------------------------------------------------------------# -size = plotsize(proje=FALSE,paper=paper) +#----- Convert output var list to data table. ---------------------------------------------# +outvars = list.2.data.table(outvars) +noutvars = nrow(outvars) #------------------------------------------------------------------------------------------# #---- Create the main output directory in case there is none. -----------------------------# -if (! file.exists(outroot)) dir.create(outroot) +dummy = dir.create(outroot,recursive=TRUE,showWarnings=FALSE) #------------------------------------------------------------------------------------------# @@ -108,38 +154,131 @@ if (! file.exists(outroot)) dir.create(outroot) #------------------------------------------------------------------------------------------# # Read job order. We always use this file to build the array. # #------------------------------------------------------------------------------------------# -cat (" + Reading ",basename(joborder),"...","\n") -names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) -names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) -jobs = read.table(file=joborder,skip=3,header=FALSE,comment.char="" - ,stringsAsFactors=FALSE) -names(jobs) = names.jobs -njobs = nrow(jobs) +cat0(" + Read ",basename(joborder),".") +names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) +names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) +jobs = read.table(file = joborder + ,skip = 3 + ,header = FALSE + ,comment.char = "" + ,stringsAsFactors = FALSE + )#end read.table +names(jobs) = names.jobs +jobs = data.table(jobs) +njobs = nrow(jobs) #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# # Read the last and the current check. For the current check, we normally skip the # -# last line to avoid trouble, unless the file is complete. # -#------------------------------------------------------------------------------------------# -names.check = c("run","lon","lat","year","month","day","hhmm","runt" - ,"agb","bsa","lai","scb") -cat (" + Reading ",basename(lastcheck),"...","\n") -last = read.table(file=lastcheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -cat (" + Reading ",basename(mycheck),"...","\n") -ncurr = length(readLines(mycheck)) -if (ncurr == njobs){ - curr = read.table(file=mycheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -}else if (ncurr > 0){ - curr = read.table(file=mycheck,skip=0,nrows=ncurr-1,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) +# last line to avoid trouble, unless the file is complete. Sometimes one of the files # +# (typically last) may be missing. Account for that too. # +#------------------------------------------------------------------------------------------# +names.check = c("run","lon","lat","year","month","day","hhmm","stall","runt" + ,"agb","bsa","lai","scb","npa") +if (file.exists(lastcheck) && file.exists(mycheck)){ + #------ Both files exist, read both. ---------------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + curr = last[ 1,,drop=FALSE] + curr = curr[-1,,drop=FALSE] + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# +}else if(file.exists(lastcheck)){ + #------ Only lastcheck exists, duplicate it. -------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + #---------------------------------------------------------------------------------------# + + #---- Duplicate last. ------------------------------------------------------------------# + curr = last + #---------------------------------------------------------------------------------------# +}else if(file.exists(mycheck )){ + #------ Only mycheck exists. -----------------------------------------------------------# + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + #------ Nothing to read, stop the run. ----------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" Last check file not found and current check file is empty/almost empty!") + cat0(" Lastcheck: " ,lastcheck,".") + cat0(" Mycheck: " ,mycheck ,".") + cat0(" Line count in mycheck: ",ncurr ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #------------------------------------------------------------------------------------# + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# + + #---- Duplicate curr. ------------------------------------------------------------------# + last = curr + #---------------------------------------------------------------------------------------# }else{ - curr = data.frame(rep(NA,times=length(names.check)),names=names.check) - curr = curr[-1,] -}#end f + #------ Nothing to read, stop the run. -------------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" None of the check files was found!") + cat0(" Lastcheck: ",lastcheck,".") + cat0(" Mycheck: ",mycheck ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #---------------------------------------------------------------------------------------# +}#end if (file.exists(lastcheck) && file.exists(mycheck)) +#------------------------------------------------------------------------------------------# + + +#----- Turn data frames into data tables. -------------------------------------------------# +last = data.table(last) +curr = data.table(curr) #------------------------------------------------------------------------------------------# @@ -149,12 +288,12 @@ if (ncurr == njobs){ #------------------------------------------------------------------------------------------# # Find the dimensions. # #------------------------------------------------------------------------------------------# -lon = unique(sort(jobs$lon )) -lat = unique(sort(jobs$lat )) +lon = unique(sort(jobs$lon)) +lat = unique(sort(jobs$lat)) dlon = median(diff(lon)) dlat = median(diff(lat)) -n.lon = length(lon ) -n.lat = length(lat ) +n.lon = length(lon) +n.lat = length(lat) key.lon = sprintf("%+06.2f",lon) key.lat = sprintf("%+06.2f",lat) #------------------------------------------------------------------------------------------# @@ -165,31 +304,60 @@ key.lat = sprintf("%+06.2f",lat) #------------------------------------------------------------------------------------------# # Initialise the variables. # #------------------------------------------------------------------------------------------# -template = array( data = NA +r.template = array( data = NA_real_ , dim = c(n.lon,n.lat) , dimnames = list(key.lon,key.lat) )#end array -datum = list ( agb = template - , lai = template - , bsa = template - , scb = template - , status = template - , yearn = template +i.template = array( data = NA_integer_ + , dim = c(n.lon,n.lat) + , dimnames = list(key.lon,key.lat) + )#end array +datum = list ( agb = r.template + , lai = r.template + , bsa = r.template + , scb = r.template + , npa = i.template + , status = i.template + , yearn = i.template )#end list #------------------------------------------------------------------------------------------# +#----- Define plot window size ------------------------------------------------------------# +limlon = range(lon) +limlat = range(lat) +st.ext = st.leg / (1. - st.leg) +st.size = plotsize( proje = TRUE + , limlon = limlon + , limlat = limlat + , extendfc = "lat" + , extfactor = st.ext + , paper = paper + ) +ey.ext = ey.leg / (1. - ey.leg) +ey.size = plotsize( proje = TRUE + , limlon = limlon + , limlat = limlat + , extendfc = "lat" + , extfactor = ey.ext + , paper = paper + ) +#------------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------------# # Copy the information from last check to joborder. # #------------------------------------------------------------------------------------------# jobs$status = rep("INITIAL",times=njobs) jobs$yearn = jobs$yeara -jobs$agb = rep(NA,times=njobs) -jobs$bsa = rep(NA,times=njobs) -jobs$lai = rep(NA,times=njobs) -jobs$scb = rep(NA,times=njobs) +jobs$agb = rep(NA_real_ ,times=njobs) +jobs$bsa = rep(NA_real_ ,times=njobs) +jobs$lai = rep(NA_real_ ,times=njobs) +jobs$scb = rep(NA_real_ ,times=njobs) +jobs$npa = rep(NA_integer_,times=njobs) il = match(last$run,jobs$run); l.sel = ! is.na(il) ic = match(curr$run,jobs$run); c.sel = ! is.na(ic) @@ -198,17 +366,17 @@ jobs$agb [il[l.sel]] = last$agb [l.sel] ; jobs$agb [ic[c.sel]] = curr$agb [ jobs$lai [il[l.sel]] = last$lai [l.sel] ; jobs$lai [ic[c.sel]] = curr$lai [c.sel] jobs$bsa [il[l.sel]] = last$bsa [l.sel] ; jobs$bsa [ic[c.sel]] = curr$bsa [c.sel] jobs$scb [il[l.sel]] = last$scb [l.sel] ; jobs$scb [ic[c.sel]] = curr$scb [c.sel] +jobs$npa [il[l.sel]] = last$npa [l.sel] ; jobs$npa [ic[c.sel]] = curr$npa [c.sel] jobs$yearn [il[l.sel]] = last$year[l.sel] ; jobs$yearn [ic[c.sel]] = curr$year[c.sel] +#------------------------------------------------------------------------------------------# - -keep = names(jobs) %in% c("lon","lat","iata","yeara","yearz","yearn","status" - ,"agb","bsa","lai","scb") -jobs = jobs[,keep] -weird = is.finite(jobs$lai) & abs(jobs$lai) > 20 -jobs$lai[weird] = NA +#----- Select layers that are used for plotting. ------------------------------------------# +keep = names(jobs) %in% c("lon","lat","iata","yeara","yearz","yearn","status" + ,"agb","bsa","lai","scb","npa") +jobs = jobs[,..keep,drop=FALSE] #------------------------------------------------------------------------------------------# @@ -216,13 +384,14 @@ jobs$lai[weird] = NA #------------------------------------------------------------------------------------------# # Find the indices to map the data to the arrays. # #------------------------------------------------------------------------------------------# -i.lon = match(jobs$lon ,lon ) -i.lat = match(jobs$lat ,lat ) +i.lon = match(jobs$lon,lon) +i.lat = match(jobs$lat,lat) index = cbind(i.lon,i.lat) datum$agb [index] = jobs$agb datum$lai [index] = jobs$lai datum$bsa [index] = jobs$bsa datum$scb [index] = jobs$scb +datum$npa [index] = jobs$npa datum$status[index] = jobs$status datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# @@ -232,14 +401,16 @@ datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# # Run the matrices. # #------------------------------------------------------------------------------------------# -yr.range = range(c(jobs$yeara,jobs$yearz)) -yr.cut = pretty(yr.range,n=10) -yr.keep = yr.cut > yr.range[1] & yr.cut < yr.range[2] -yr.brks = c(-Inf,c(yr.range[1],yr.cut[yr.keep],yr.range[2])) -n.cut = length(yr.cut)-1 -yr.cut = cut(datum$yearn,yr.brks) -yr.level = levels(yr.cut) -n.level = length(yr.level) +yeara = min(jobs$yeara) +yearz = max(jobs$yearz) +yr.range = pretty.xylim(u=c(yeara,yearz)) +yr.brks = pretty(yr.range,n=10) +yr.keep = (yr.brks %wr% yr.range) & (! yr.brks %in% c(yeara,yearz)) +yr.brks = unique(c(-Inf,yr.brks[yr.keep],Inf)) +n.cut = length(yr.brks)-1 +yr.cut = cut(datum$yearn,yr.brks) +yr.level = levels(yr.cut) +n.level = length(yr.level) #------------------------------------------------------------------------------------------# @@ -248,6 +419,7 @@ n.level = length(yr.level) datum$yr.idx = match(yr.cut,yr.level) + 0 * datum$yearn initial = datum$status == "INITIAL" crashed = datum$status == "CRASHED" +hydfail = datum$status == "HYDFAIL" bad.met = datum$status == "BAD_MET" metmiss = datum$status == "METMISS" stopped = datum$status == "STOPPED" @@ -261,115 +433,124 @@ datum$yr.idx[extinct] = n.level + 3 datum$yr.idx[stopped] = n.level + 4 datum$yr.idx[metmiss] = n.level + 5 datum$yr.idx[bad.met] = n.level + 6 -datum$yr.idx[crashed] = n.level + 7 -yr.cscheme = c("grey89",iatlas(n=n.level),"royalblue4","steelblue3","purple3" - ,"mediumpurple1","deepskyblue","red3","hotpink") -ybottom = rep(0,times=n.level+8) -ytop = rep(1,times=n.level+8) -xleft = seq(from=-1,to=n.level+6) -xright = seq(from= 0,to=n.level+7) -xat = seq(from=-1,to=n.level+6)+0.5 -xbrks = seq(from=-1,to=n.level+7)+0.5 -xlabel = c("Initial",yr.brks[-1],"Finish","StState","Extinct" - ,"Stopped","MetMiss","Bad Met","Crashed") +datum$yr.idx[hydfail] = n.level + 7 +datum$yr.idx[crashed] = n.level + 8 +yr.cscheme = c("grey89",atlas(n=n.level),"royalblue4","steelblue3","purple3" + ,"mediumpurple1","deepskyblue","hotpink","red3","firebrick4") +ybottom = rep(0,times=n.level+9) +ytop = rep(1,times=n.level+9) +xleft = sequence(n.level+9) - 1 +xright = sequence(n.level+9) +xat = c(sequence(n.level+2)-1,n.level+sequence(8)+0.5) +xbrks = sequence(n.level+10)-1-0.5 +xlabel = c("Initial",yeara,yr.brks[-c(1,n.level+1)],yearz,"Finish","StState" + ,"Extinct","Stopped","MetMiss","Bad Met","HydFail","Crashed") #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Limits for longitude and latitude. # +# Limits and labels for longitude and latitude. # #------------------------------------------------------------------------------------------# -limlon = c(min(lon)-0.5*dlon,max(lon)+0.5*dlon) -limlat = c(min(lat)-0.5*dlat,max(lat)+0.5*dlat) +limlon = c(min(lon)-0.5*dlon,max(lon)+0.5*dlon) +limlat = c(min(lat)-0.5*dlat,max(lat)+0.5*dlat) +lonplot = pretty.lonlat(x=limlon,n=6,type="lon") +latplot = pretty.lonlat(x=limlat,n=6,type="lat") #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# + + +#==========================================================================================# +#==========================================================================================# # Create the status map for all sites. # #------------------------------------------------------------------------------------------# -cat(" Plot the current status...","\n") - -#------ Make plot annotation. -------------------------------------------------------------# -letitre = paste("Polygon status") -#------------------------------------------------------------------------------------------# - -for (o in 1:nout){ - #----- Open file. ----------------------------------------------------------------------# - fichier = paste(here,"/stt_region.",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if +cat0(" Plot the current status.") + + #------ Make plot annotation. ----------------------------------------------------------# + letitre = "Polygon status" #---------------------------------------------------------------------------------------# + for (o in sequence(nout)){ + #----- Open file. -------------------------------------------------------------------# + fichier = file.path(here,paste0("stt_region.",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = st.size + , ptsz = ptsz + , depth = depth + )#end open.plot + #------------------------------------------------------------------------------------# - #----- Save the margins to avoid losing the data. --------------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar - #---------------------------------------------------------------------------------------# + #----- Load settings and split window. ----------------------------------------------# + par.orig = par(par.user) + #------------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------------# - # Split the plotting window. # - #---------------------------------------------------------------------------------------# - layout( mat = rbind(2,1) - , heights = c(3,1) - )#end layout - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Split the plotting window. # + #------------------------------------------------------------------------------------# + layout(mat = rbind(2,1), heights = c(1.-st.leg,st.leg)) + #------------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------------# - # First, let's plot the legend. # - #---------------------------------------------------------------------------------------# - par(mar=c(3,2,2,2)+0.1) - plot.new() - plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=yr.cscheme) - box() - axis(side=1,at=xat,srt=45,labels=FALSE) - text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=30,adj=1,xpd=TRUE,cex=1.00) - title(main="Status",ylab="",xlab="") - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # First, let's plot the legend. # + #------------------------------------------------------------------------------------# + par(mar=c(3.1,3.1,1.1,1.1)) + plot.new() + plot.window( xlim = range(xleft,xright) + , ylim = range(ybottom,ytop) + , xaxs = "i" + , yaxs = "i" + )#end plot.window + rect( xleft = xleft + , ybottom = ybottom + , xright = xright + , ytop = ytop + , col = yr.cscheme + , border = "grey50" + )#end rect + box() + axis(side=1,at=xat,srt=45,labels=FALSE) + text(x=xat,y=par("usr")[3]-0.2,labels=xlabel,srt=45,adj=1,xpd=TRUE,cex=0.95) + title(main="Status",cex.main=1.0) + #------------------------------------------------------------------------------------# - #----- Set the window. -----------------------------------------------------------------# - par(mar = c(3.1,3.1,4.1,2.1)) - plot.new() - plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") - axis(side=1) - axis(side=2) - box() - title(main=letitre,xlab="",ylab="") - image(x=lon,y=lat,z=datum$yr.idx,col=yr.cscheme,breaks=xbrks,add=TRUE) - southammap() - #---------------------------------------------------------------------------------------# + #----- Set the window. --------------------------------------------------------------# + par(mar = c(2.1,3.1,1.1,1.1)) + plot.new() + plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") + axis(side=1,las=1,at=lonplot$at,labels=lonplot$labels) + axis(side=2,las=1,at=latplot$at,labels=latplot$labels) + box() + image( x = lon + , y = lat + , z = datum$yr.idx + , col = yr.cscheme + , breaks = xbrks + , add = TRUE + )#end image + southammap(col="grey30",lwd=1) + amazonmap (col="black" ,lwd=2) + #------------------------------------------------------------------------------------# - #----- Close the device. ---------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + + #----- Close the device. ------------------------------------------------------------# + dummy = close.plot(outform = outform[o]) + #------------------------------------------------------------------------------------# + }#end for (o in sequence(nout)) #---------------------------------------------------------------------------------------# -}#end for -#------------------------------------------------------------------------------------------# +#==========================================================================================# +#==========================================================================================# @@ -377,17 +558,21 @@ for (o in 1:nout){ #------------------------------------------------------------------------------------------# # Create parameter space maps for all other variables. # #------------------------------------------------------------------------------------------# -cat(" Plot the current properties...","\n") -key.var = c("lai","bsa","agb","scb") -desc.var = c("Leaf area index [m2/m2]","Basal area [cm2/m2]" - ,"Above-ground biomass [kgC/m2]","Soil carbon [kgC/m2]") -n.var = length(key.var) -for (v in 1:n.var){ - cat(" - ",desc.var[v],"...","\n") +cat0(" + Plot the current properties.") +for (v in sequence(noutvars)){ + #----- Handy aliases. ------------------------------------------------------------------# + v.vnam = outvars$vnam[v] + v.desc = outvars$desc[v] + v.unit = untab[[outvars$unit[v]]] + v.csch = match.fun(outvars$csch[v]) + cat0(" - ",v.desc,".") + #---------------------------------------------------------------------------------------# + + #----- Collapse realisations using the median. -----------------------------------------# - this.var = datum[[key.var[v]]] - rien = ! is.finite(this.var) - this.var[rien] = NA + v.value = datum[[v.vnam]] + del = ! is.finite(v.value) + v.value[del] = NA_real_ #---------------------------------------------------------------------------------------# @@ -395,55 +580,38 @@ for (v in 1:n.var){ #---------------------------------------------------------------------------------------# # Break the data into bins. # #---------------------------------------------------------------------------------------# - if (all(is.na(this.var))){ - var.brks = c(-1,0,1) - n.brks = length(var.brks) - var.cut = cut(as.numeric(this.var),breaks=var.brks) - }else{ - var.brks = pretty(this.var,n=ncolours) - n.brks = length(var.brks) - var.cut = cut(this.var,breaks=var.brks) - }#end if - var.lev = levels(var.cut) - var.idx = match(var.cut,var.lev) + 0 * this.var - var.cscheme = iatlas(n=n.brks-1) + v.limit = pretty.xylim(v.value) + v.brks = pretty(v.value,n=ncolours) + n.brks = length(v.brks) + v.cut = cut(as.numeric(v.value),breaks=v.brks) + v.lev = levels(v.cut) + v.idx = match(v.cut,v.lev) + 0 * v.value + v.cscheme = v.csch(n=n.brks-1) #---------------------------------------------------------------------------------------# #----- Make the edges. -----------------------------------------------------------------# - xleft = var.brks[-n.brks] - xright = var.brks[ -1] + xleft = v.brks[-n.brks] + xright = v.brks[ -1] ybottom = rep(0,times=n.brks) ytop = rep(1,times=n.brks) - xat = var.brks + xat = v.brks #---------------------------------------------------------------------------------------# - #------ Find the soil texture key and description. -------------------------------------# - letitre = paste(desc.var[v]) - #---------------------------------------------------------------------------------------# - for (o in 1:nout){ + #---------------------------------------------------------------------------------------# + # Loop through formats. # + #---------------------------------------------------------------------------------------# + for (o in sequence(nout)){ #----- Open file. -------------------------------------------------------------------# - fichier = paste(here,"/",key.var[v],"_region.",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if - #------------------------------------------------------------------------------------# - - - #----- Save the margins to avoid losing the data. -----------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar + fichier = file.path(here,paste0(v.vnam,"_region.",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = ey.size + , ptsz = ptsz + , depth = depth + )#end open.plot #------------------------------------------------------------------------------------# @@ -451,9 +619,8 @@ for (v in 1:n.var){ #------------------------------------------------------------------------------------# # Split the plotting window. # #------------------------------------------------------------------------------------# - layout( mat = rbind(2,1) - , heights = c(4,1) - )#end layout + par(par.user) + layout(mat=rbind(2,1),heights=c(1.-ey.leg,ey.leg)) #------------------------------------------------------------------------------------# @@ -461,41 +628,41 @@ for (v in 1:n.var){ #------------------------------------------------------------------------------------# # First, let's plot the legend. # #------------------------------------------------------------------------------------# - par(mar=c(3,3,2,2)+0.1) + par(mar=c(2.1,3.1,1.6,1.1)) plot.new() plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=var.cscheme) + rect( xleft = xleft + , ybottom = ybottom + , xright = xright + , ytop = ytop + , col = v.cscheme + , border = "transparent" + )#end rect box() axis(side=1,at=xat) - title(main=desc.var[v],xlab="",ylab="") + title(main=desc.unit(desc=v.desc,unit=v.unit),cex.main=1.0) #------------------------------------------------------------------------------------# #----- Set the window. --------------------------------------------------------------# - par(mar = c(3.1,3.1,4.1,2.1)) + par(mar = c(2.1,3.1,1.1,1.1)) plot.new() plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") - axis(side=1) - axis(side=2) + axis(side=1,las=1,at=lonplot$at,labels=lonplot$labels) + axis(side=2,las=1,at=latplot$at,labels=latplot$labels) box() - title(main=letitre,xlab="",ylab="") - image(x=lon,y=lat,z=this.var,col=var.cscheme,breaks=var.brks,add=TRUE) - southammap() + image(x=lon,y=lat,z=v.value,col=v.cscheme,breaks=v.brks,add=TRUE) + southammap(col="grey30",lwd=1) + amazonmap (col="black" ,lwd=2) #------------------------------------------------------------------------------------# #----- Close the device. ------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #------------------------------------------------------------------------------------# - }#end for + }#end for (o in sequence(nout)) #---------------------------------------------------------------------------------------# -}#end for +}#end for (v in sequence(noutvars)) #------------------------------------------------------------------------------------------# diff --git a/ED/Template/sit_utils/plot.status.r b/ED/Template/sit_utils/plot.status.r index e148cbc8f..9f0c9001d 100644 --- a/ED/Template/sit_utils/plot.status.r +++ b/ED/Template/sit_utils/plot.status.r @@ -16,11 +16,16 @@ graphics.off() #----- Paths. -----------------------------------------------------------------------------# -main = "/x/xxxxxxxxxxxx/xxxxxx/xxxxxxx/xxxxxxxx" # Main simulation directory. -here = file.path(main,"sit_utils") # This directory. - -srcdir = "/n/home00/mlongo/util/Rsc" # Source directory. -outroot = here # Directory for figures +main = "mypath" # Main path (one up sit_utils). +here = file.path(main,"sit_utils") # This path +srcdir = c( "/home/mlongo/Util/Rsc" # Possible paths with libraries + , "/Users/mlongo/Util/Rsc" # R will select the first + , "/prj/prjidfca/marcosl/Util/Rsc" # one that is found. + , "/prj/bramsolam/marcos.longo/Util/Rsc" # + , "/scratch/bramsolam/marcos.longo/Util/Rsc" # + , "/n/home00/mlongo/Util/Rsc" # + )#end c # +outroot = here # Directory for figures #------------------------------------------------------------------------------------------# @@ -58,6 +63,43 @@ mtext.yadj = 0.65 # Offset for the y label #------------------------------------------------------------------------------------------# +#------ List of variables to make the maps. -----------------------------------------------# +n = 0 +outvars = list() +n = n + 1 +outvars[[n]] = list( vnam = "lai" + , desc = "Leaf area index" + , unit = "m2lom2" + , csch = "pubugn" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "bsa" + , desc = "Basal area" + , unit = "cm2om2" + , csch = "bupu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "agb" + , desc = "Aboveground carbon" + , unit = "kgcom2" + , csch = "ylgnbu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "scb" + , desc = "Soil carbon" + , unit = "kgcom2" + , csch = "orrd" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "npa" + , desc = "Patch count" + , unit = "empty" + , csch = "magma" + )#end list +#------------------------------------------------------------------------------------------# + + + #==========================================================================================# #==========================================================================================# @@ -74,28 +116,32 @@ mtext.yadj = 0.65 # Offset for the y label #==========================================================================================# #----- Check that directory main has been set. --------------------------------------------# -if ( main == "/x/xxxxxxxxxxxx/xxxxxx/xxxxxxx/xxxxxxxx"){ +if (! dir.exists(main)){ cat (" Main: ",main,"\n") - stop(" Directory main has not been set!!!") + stop(" Directory main is incorrect or has not been set!!!") }#end if #------------------------------------------------------------------------------------------# + #----- Loading some packages and scripts. -------------------------------------------------# +srcdir = (srcdir[file.exists(srcdir)])[1] source(file.path(srcdir,"load.everything.r")) #------------------------------------------------------------------------------------------# -#----- Set how many formats we must output. -----------------------------------------------# -outform = tolower(outform) -nout = length (outform) +#----- Convert output var list to data table. ---------------------------------------------# +outvars = list.2.data.table(outvars) +noutvars = nrow(outvars) #------------------------------------------------------------------------------------------# -#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# -options(locatorBell=FALSE) + +#----- Set how many formats we must output. -----------------------------------------------# +outform = tolower(outform) +nout = length (outform) #------------------------------------------------------------------------------------------# @@ -107,7 +153,7 @@ size = plotsize(proje=FALSE,paper=paper) #---- Create the main output directory in case there is none. -----------------------------# -if (! file.exists(outroot)) dir.create(outroot) +dummy = dir.create(outroot,recursive=TRUE,showWarnings=FALSE) #------------------------------------------------------------------------------------------# @@ -115,7 +161,7 @@ if (! file.exists(outroot)) dir.create(outroot) #------------------------------------------------------------------------------------------# # Read job order. We always use this file to build the array. # #------------------------------------------------------------------------------------------# -cat (" + Reading ",basename(joborder),"...","\n") +cat0(" + Read ",basename(joborder),".") names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) jobs = read.table(file=joborder,skip=3,header=FALSE,comment.char="" @@ -131,25 +177,113 @@ jobs$realisation = as.numeric(substring(jobs$run,23,24)) #------------------------------------------------------------------------------------------# # Read the last and the current check. For the current check, we normally skip the # -# last line to avoid trouble, unless the file is complete. # +# last line to avoid trouble, unless the file is complete. Sometimes one of the files # +# (typically last) may be missing. Account for that too. # #------------------------------------------------------------------------------------------# -names.check = c("run","lon","lat","year","month","day","hhmm","runt" +names.check = c("run","lon","lat","year","month","day","hhmm","stall","runt" ,"agb","bsa","lai","scb","npa") -cat (" + Reading ",basename(lastcheck),"...","\n") -last = read.table(file=lastcheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -cat (" + Reading ",basename(mycheck),"...","\n") -ncurr = length(readLines(mycheck)) -if (ncurr == njobs){ - curr = read.table(file=mycheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -}else if (ncurr > 0){ - curr = read.table(file=mycheck,skip=0,nrows=ncurr-1,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) +if (file.exists(lastcheck) && file.exists(mycheck)){ + #------ Both files exist, read both. ---------------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + curr = last[ 1,,drop=FALSE] + curr = curr[-1,,drop=FALSE] + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# +}else if(file.exists(lastcheck)){ + #------ Only lastcheck exists, duplicate it. -------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + #---------------------------------------------------------------------------------------# + + #---- Duplicate last. ------------------------------------------------------------------# + curr = last + #---------------------------------------------------------------------------------------# +}else if(file.exists(mycheck )){ + #------ Only mycheck exists. -----------------------------------------------------------# + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + #------ Nothing to read, stop the run. ----------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" Last check file not found and current check file is empty/almost empty!") + cat0(" Lastcheck: " ,lastcheck,".") + cat0(" Mycheck: " ,mycheck ,".") + cat0(" Line count in mycheck: ",ncurr ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #------------------------------------------------------------------------------------# + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# + + #---- Duplicate curr. ------------------------------------------------------------------# + last = curr + #---------------------------------------------------------------------------------------# }else{ - curr = data.frame(rep(NA,times=length(names.check)),names=names.check) - curr = curr[-1,] -}#end f + #------ Nothing to read, stop the run. -------------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" None of the check files was found!") + cat0(" Lastcheck: ",lastcheck,".") + cat0(" Mycheck: ",mycheck ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #---------------------------------------------------------------------------------------# +}#end if (file.exists(lastcheck) && file.exists(mycheck)) +#------------------------------------------------------------------------------------------# + + +#----- Turn data frames into data tables. -------------------------------------------------# +last = data.table(last) +curr = data.table(curr) #------------------------------------------------------------------------------------------# @@ -172,10 +306,10 @@ n.realisation = length(realisation) n.stext = length(stext ) n.iphen = length(iphen ) key.iata = toupper(iata ) -key.drain = paste("r" ,sprintf("%+3.3i",sort(100*unique(jobs$drain ))),sep="") -key.dtemp = paste("t" ,sprintf("%+3.3i",sort(100*unique(jobs$dtemp ))),sep="") -key.realisation = paste("real" ,sprintf("%2.2i" ,sort( unique(jobs$realisation))),sep="") -key.stext = paste("stext",sprintf("%2.2i" ,sort( unique(jobs$istext ))),sep="") +key.drain = paste0("r" ,sprintf("%+3.3i",sort(100*unique(jobs$drain )))) +key.dtemp = paste0("t" ,sprintf("%+3.3i",sort(100*unique(jobs$dtemp )))) +key.realisation = paste0("real" ,sprintf("%2.2i" ,sort( unique(jobs$realisation)))) +key.stext = paste0("stext",sprintf("%2.2i" ,sort( unique(jobs$istext )))) key.iphen = c("Evergreen","Deciduous") desc.iata = poilist$longname[match(iata,poilist$iata)] desc.stext = stext.names[stext] @@ -265,14 +399,16 @@ datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# # Run the matrices. # #------------------------------------------------------------------------------------------# -yr.range = range(c(jobs$yeara,jobs$yearz)) -yr.cut = pretty(yr.range,n=10) -yr.keep = yr.cut > yr.range[1] & yr.cut < yr.range[2] -yr.brks = c(-Inf,c(yr.range[1],yr.cut[yr.keep],yr.range[2])) -n.cut = length(yr.cut)-1 -yr.cut = cut(datum$yearn,yr.brks) -yr.level = levels(yr.cut) -n.level = length(yr.level) +yeara = min(jobs$yeara) +yearz = max(jobs$yearz) +yr.range = pretty.xylim(u=c(yeara,yearz)) +yr.brks = pretty(yr.range,n=10) +yr.keep = (yr.brks %wr% yr.range) & (! yr.brks %in% c(yeara,yearz)) +yr.brks = unique(c(-Inf,yr.brks[yr.keep],Inf)) +n.cut = length(yr.brks)-1 +yr.cut = cut(datum$yearn,yr.brks) +yr.level = levels(yr.cut) +n.level = length(yr.level) #------------------------------------------------------------------------------------------# @@ -281,6 +417,7 @@ n.level = length(yr.level) datum$yr.idx = match(yr.cut,yr.level) + 0 * datum$yearn initial = datum$status == "INITIAL" crashed = datum$status == "CRASHED" +hydfail = datum$status == "HYDFAIL" bad.met = datum$status == "BAD_MET" metmiss = datum$status == "METMISS" stopped = datum$status == "STOPPED" @@ -294,17 +431,18 @@ datum$yr.idx[extinct] = n.level + 3 datum$yr.idx[stopped] = n.level + 4 datum$yr.idx[metmiss] = n.level + 5 datum$yr.idx[bad.met] = n.level + 6 -datum$yr.idx[crashed] = n.level + 7 -yr.cscheme = c("grey89",iatlas(n=n.level),"royalblue4","steelblue3","purple3" - ,"mediumpurple1","deepskyblue","red3","hotpink") -ybottom = rep(0,times=n.level+8) -ytop = rep(1,times=n.level+8) -xleft = seq(from=-1,to=n.level+6) -xright = seq(from= 0,to=n.level+7) -xat = seq(from=-1,to=n.level+6)+0.5 -xbrks = seq(from=-1,to=n.level+7)+0.5 -xlabel = c("Initial",yr.brks[-1],"Finish","StState","Extinct" - ,"Stopped","MetMiss","Bad Met","Crashed") +datum$yr.idx[hydfail] = n.level + 7 +datum$yr.idx[crashed] = n.level + 8 +yr.cscheme = c("grey89",atlas(n=n.level),"royalblue4","steelblue3","purple3" + ,"mediumpurple1","deepskyblue","hotpink","red3","firebrick4") +ybottom = rep(0,times=n.level+9) +ytop = rep(1,times=n.level+9) +xleft = sequence(n.level+9) - 1 +xright = sequence(n.level+9) +xat = c(sequence(n.level+2)-1,n.level+sequence(8)+0.5) +xbrks = sequence(n.level+10)-1-0.5 +xlabel = c("Initial",yeara,yr.brks[-c(1,n.level+1)],yearz,"Finish","StState" + ,"Extinct","Stopped","MetMiss","Bad Met","HydFail","Crashed") #------------------------------------------------------------------------------------------# @@ -326,9 +464,9 @@ use.yr.idx = apply( X = datum$yr.idx #------------------------------------------------------------------------------------------# # Create the status map for all sites. # #------------------------------------------------------------------------------------------# -cat(" Plot the current status...","\n") +cat0(" + lot the current status.") lo.box = pretty.box(n.iphen*n.iata) -for (st in 1:n.stext){ +for (st in sequence(n.stext)){ #------ Find the soil texture key and description. -------------------------------------# this.st.key = key.stext [st] letitre = paste("Polygon status -- Soil type: ",desc.stext[st] @@ -337,27 +475,20 @@ for (st in 1:n.stext){ ley = paste("Temperature change [K]") #---------------------------------------------------------------------------------------# - for (o in 1:nout){ + for (o in sequence(nout)){ #----- Open file. -------------------------------------------------------------------# - fichier = paste(here,"/stt_",this.st.key,".",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if + fichier = file.path(here,paste0("stt_",this.st.key,".",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = size + , ptsz = ptsz + , depth = depth + )#end open.plot #------------------------------------------------------------------------------------# #----- Save the margins to avoid losing the data. -----------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar + par(par.user) #------------------------------------------------------------------------------------# @@ -382,7 +513,7 @@ for (st in 1:n.stext){ rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=yr.cscheme) box() axis(side=1,at=xat,srt=45,labels=FALSE) - text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=30,adj=1,xpd=TRUE,cex=1.1) + text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=45,adj=1,xpd=TRUE,cex=0.95) title(main="Status",ylab="",xlab="") #------------------------------------------------------------------------------------# @@ -392,8 +523,8 @@ for (st in 1:n.stext){ # Now we loop over sites and pheonologies. # #------------------------------------------------------------------------------------# k = 0 - for (ph in 1:n.iphen){ - for (pl in 1:n.iata){ + for (ph in sequence(n.iphen)){ + for (pl in sequence(n.iata)){ #----- Make the sub-title. ----------------------------------------------------# lesub=paste(desc.iata[pl],desc.iphen[ph],sep=" - ") #------------------------------------------------------------------------------# @@ -443,13 +574,7 @@ for (st in 1:n.stext){ #----- Close the device. ------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #------------------------------------------------------------------------------------# }#end for #---------------------------------------------------------------------------------------# @@ -462,22 +587,26 @@ for (st in 1:n.stext){ #------------------------------------------------------------------------------------------# # Create parameter space maps for all other variables. # #------------------------------------------------------------------------------------------# -cat(" Plot the current properties...","\n") -key.var = c("lai","bsa","agb","scb","npa") -desc.var = c("Leaf area index [m2/m2]","Basal area [cm2/m2]" - ,"Above-ground biomass [kgC/m2]","Soil carbon [kgC/m2]","Patch count [---]") -n.var = length(key.var) +cat0(" Plot the current properties.") lo.box = pretty.box(n.iphen*n.iata) -for (v in 1:n.var){ - cat(" - ",desc.var[v],"...","\n") +for (v in sequence(noutvars)){ + #----- Handy aliases. ------------------------------------------------------------------# + v.vnam = outvars$vnam[v] + v.desc = outvars$desc[v] + v.unit = untab[[outvars$unit[v]]] + v.csch = match.fun(outvars$csch[v]) + cat0(" - ",v.desc,".") + #---------------------------------------------------------------------------------------# + + #----- Collapse realisations using the median. -----------------------------------------# - this.var = apply( X = datum[[key.var[v]]] - , MARGIN = c(1,2,4,5,6) - , FUN = median - , na.rm = TRUE - )#end apply - rien = ! is.finite(this.var) - this.var[rien] = NA + v.value = apply( X = datum[[v.vnam]] + , MARGIN = c(1,2,4,5,6) + , FUN = median + , na.rm = TRUE + )#end apply + rien = ! is.finite(v.value) + v.value[rien] = NA #---------------------------------------------------------------------------------------# @@ -485,18 +614,13 @@ for (v in 1:n.var){ #---------------------------------------------------------------------------------------# # Break the data into bins. # #---------------------------------------------------------------------------------------# - if (all(is.na(this.var))){ - var.brks = c(-1,0,1) - n.brks = length(var.brks) - var.cut = cut(as.numeric(this.var),breaks=var.brks) - }else{ - var.brks = pretty(this.var,n=ncolours) - n.brks = length(var.brks) - var.cut = cut(this.var,breaks=var.brks) - }#end if - var.lev = levels(var.cut) - var.idx = match(var.cut,var.lev) + 0 * this.var - var.cscheme = iatlas(n=n.brks-1) + v.limit = pretty.xylim(v.value) + v.brks = pretty(v.value,n=ncolours) + n.brks = length(v.brks) + v.cut = cut(as.numeric(v.value),breaks=v.brks) + v.lev = levels(v.cut) + v.idx = match(v.cut,v.lev) + 0 * v.value + v.cscheme = v.csch(n=n.brks-1) #---------------------------------------------------------------------------------------# @@ -505,33 +629,27 @@ for (v in 1:n.var){ xright = var.brks[ -1] ybottom = rep(0,times=n.brks) ytop = rep(1,times=n.brks) - xat = var.brks + xat = v.brks #---------------------------------------------------------------------------------------# - for (st in 1:n.stext){ + for (st in sequence(n.stext)){ #------ Find the soil texture key and description. ----------------------------------# this.st.key = key.stext [st] - letitre = paste(desc.var[v]," -- Soil type: ",desc.stext[st],sep="") - lex = paste("Rainfall change [scale parameter]") - ley = paste("Temperature change [K]") + letitre = paste0(desc.var[v]," -- Soil type: ",desc.stext[st]) + lex = paste0("Rainfall change [scale parameter]") + ley = paste0("Temperature change [K]") #------------------------------------------------------------------------------------# - for (o in 1:nout){ + for (o in sequence(nout)){ #----- Open file. ----------------------------------------------------------------# - fichier = paste(here,"/",key.var[v],"_",this.st.key,".",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if + fichier = file.path(here,paste0(key.var[v],"_",this.st.key,".",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = size + , ptsz = ptsz + , depth = depth + )#end open.plot #---------------------------------------------------------------------------------# @@ -559,10 +677,10 @@ for (v in 1:n.var){ par(mar=c(3,3,2,3)+0.1) plot.new() plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=var.cscheme) + rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=v.cscheme) box() axis(side=1,at=xat) - title(main=desc.var[v],xlab="",ylab="") + title(main=desc.unit(desc=v.desc,unit=v.unit),cex.main=1.0) #---------------------------------------------------------------------------------# @@ -571,8 +689,8 @@ for (v in 1:n.var){ # Now we loop over sites and pheonologies. # #---------------------------------------------------------------------------------# k = 0 - for (ph in 1:n.iphen){ - for (pl in 1:n.iata){ + for (ph in sequence(n.iphen)){ + for (pl in sequence(n.iata)){ #----- Make the sub-title. -------------------------------------------------# lesub=paste(desc.iata[pl],desc.iphen[ph],sep=" - ") #---------------------------------------------------------------------------# @@ -600,7 +718,7 @@ for (v in 1:n.var){ #----- Set the window. -----------------------------------------------------# par(mar = mar.now) - image(x=drain,y=dtemp,z=this.var[,,ph,pl,st],col=var.cscheme + image(x=drain,y=dtemp,z=v.value[,,ph,pl,st],col=v.cscheme ,breaks=var.brks,xaxt=xaxt,yaxt=yaxt,main=lesub,xlab="",ylab="") #---------------------------------------------------------------------------# }#end for @@ -622,17 +740,11 @@ for (v in 1:n.var){ #----- Close the device. ---------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #---------------------------------------------------------------------------------# - }#end for + }#end for (o in sequence(nout)) #------------------------------------------------------------------------------------# - }#end for + }#end for (st in sequence(n.stext)) #---------------------------------------------------------------------------------------# -}#end for +}#end for (v in sequence(noutvars)) #------------------------------------------------------------------------------------------# diff --git a/ED/build/make/include.mk.cannon b/ED/build/make/include.mk.cannon index 256b13d3f..4e28cf388 100644 --- a/ED/build/make/include.mk.cannon +++ b/ED/build/make/include.mk.cannon @@ -103,12 +103,12 @@ ifeq ($(KIND_COMP),B) F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ - -warn interfaces -warn declarations -qopenmp -diag-error=all -static + -warn interfaces -warn declarations -warn errors -qopenmp -static C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ - -warn interfaces -warn declarations -qopenmp -diag-error=all + -warn interfaces -warn declarations -warn errors -qopenmp #---------------------------------------------------------------------------------------# endif ifeq ($(KIND_COMP),C) diff --git a/ED/build/make/include.mk.docker b/ED/build/make/include.mk.docker index 1ad2869eb..a291b0bb2 100644 --- a/ED/build/make/include.mk.docker +++ b/ED/build/make/include.mk.docker @@ -9,8 +9,8 @@ BASE=$(ED_ROOT)/build/ # HDF 5 Libraries USE_HDF5=1 -HDF5_INCS=-I/usr/include/hdf5/serial -HDF5_LIBS=-L/usr/lib/x86_64-linux-gnu/hdf5/serial -lz -lhdf5_fortran -lhdf5 -lhdf5_hl +HDF5_INCS=-I/usr/include/hdf5/openmpi +HDF5_LIBS=-L/usr/lib/x86_64-linux-gnu/hdf5/openmpi -lz -lhdf5_fortran -lhdf5 -lhdf5_hl #HDF5_INCS=-I/usr/include #HDF5_LIBS=-lz -lhdf5_fortran -lhdf5 -lhdf5_hl USE_COLLECTIVE_MPIO=0 @@ -27,13 +27,17 @@ USE_MPIWTIME=1 # gfortran CMACH=PC_LINUX1 -F_COMP=mpif90 +FC_TYPE=GNU +# F_COMP=mpif90 +F_COMP=gfortran F_OPTS=-O3 -ffree-line-length-none -fno-whole-file -C_COMP=mpicc +# C_COMP=mpicc +C_COMP=gcc C_OPTS=-O3 -LOADER=mpif90 +# LOADER=mpif90 +LOADER=gfortran LOADER_OPTS=${F_OPTS} -C_LOADER=mpicc +# C_LOADER=mpicc # C_LOADER is obsolete and can be removed LIBS= MOD_EXT=mod @@ -41,7 +45,8 @@ MOD_EXT=mod MPI_PATH= PAR_INCS= PAR_LIBS= -PAR_DEFS=-DRAMS_MPI +# PAR_DEFS=-DRAMS_MPI +PAR_DEFS= # For IBM,HP,SGI,ALPHA,LINUX use these: ARCHIVE=ar rs diff --git a/ED/build/make/include.mk.docker.gnu b/ED/build/make/include.mk.docker.gnu new file mode 100644 index 000000000..02a5559dd --- /dev/null +++ b/ED/build/make/include.mk.docker.gnu @@ -0,0 +1,117 @@ +#==========================================================================================# +#==========================================================================================# +# Make file include.mk.docker.gnu # +#------------------------------------------------------------------------------------------# + +#----- Define make (gnu make works best). -------------------------------------------------# +MAKE=/usr/bin/make +#------------------------------------------------------------------------------------------# + +#----- Libraries. -------------------------------------------------------------------------# +BASE=$(ED_ROOT)/build/ +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# HDF5 libraries # +# # +# Since ED-2.1, this is no longer optional for real simulations. You must have HDF5 # +# libraries compiled with the same compiler you set for F_COMP and C_COMP. You may still # +# be able to compile without HDF5 but it will not run. # +#------------------------------------------------------------------------------------------# +HDF5_INCS=-I/usr/include/hdf5/openmpi +HDF5_LIBS= -L/usr/lib/$(shell uname -m)-linux-gnu/hdf5/openmpi -lhdf5_fortran -lhdf5_hl -lhdf5 -lz -lm + +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# If you have a version of hdf5 compiled in parallel, then you may benefit from # +# collective I/O, then use this flag = 1. Otherwise, set it to zero. # +#------------------------------------------------------------------------------------------# +USE_COLLECTIVE_MPIO=0 +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# This should be 1 unless you are running with -gen-interfaces. Interfaces usually # +# make the compilation to crash when the -gen-interfaces option are on, so this flag # +# bypass all interfaces in the code. # +#------------------------------------------------------------------------------------------# +USE_INTERF=1 +#------------------------------------------------------------------------------------------# + +#################################### COMPILER SETTINGS ##################################### +CMACH=DOCKER_GNU +FC_TYPE=GNU +#F_COMP=gfortran +F_COMP=mpif90.openmpi +#C_COMP=gcc +C_COMP=mpicc.openmpi +#LOADER=gfortran +LOADER=mpif90.openmpi +#C_LOADER=gcc +C_LOADER=mpicc.openmpi +LIBS= +MOD_EXT=mod +############################################################################################ + + + + + +##################################### COMPILER OPTIONS ##################################### +#------------------------------------------------------------------------------------------# +# A. Pickiest - Use this whenever you change arguments on functions and subroutines. # +# This will perform the same tests as B but it will also check whether all # +# arguments match between subroutine declaration and subroutine calls. # +# WARNING: In order to really check all interfaces you must compile with # +# this option twice: # +# 1. Compile (./install.sh A) # +# 2. Prepare second compilation(./2ndcomp.sh) # +# 3. Compile one more time (./install.sh B) # +# If the compilation fails either at step 3, then your code has interface # +# problems. If it successfully compiles, then the code is fine for # +# interfaces. # +# E. Fast - This is all about performance, use only when you are sure that the model has # +# no code problem, and you want results asap. This will not check for any # +# problems, which means that this is an option suitable for end users, not de- # +# velopers. # +#------------------------------------------------------------------------------------------# +ifeq ($(KIND_COMP),) + KIND_COMP=E +endif +#------------------------------------------------------------------------------------------# +ifeq ($(KIND_COMP),A) + F_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ + -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -static + C_OPTS= -O0 -DLITTLE -g -static + LOADER_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ + -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp + #---------------------------------------------------------------------------------------# +endif +ifeq ($(KIND_COMP),E) + F_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -static + C_OPTS= -O0 -DLITTLE -g -static + LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp + #---------------------------------------------------------------------------------------# +endif +#------------------------------------------------------------------------------------------# +############################################################################################ + +#------------------------------------------------------------------------------------------# +# If using mpicc and mpif90 as compilers (recommended), leave MPI_PATH, PAR_INCS, and # +# PAR_LIBS blank, otherwise provide the includes and libraries for mpi. Either way, don't # +# change PAR_DEFS. # +#------------------------------------------------------------------------------------------# +MPI_PATH= +PAR_INCS= +PAR_LIBS= +PAR_DEFS= +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# Archive options. # +#------------------------------------------------------------------------------------------# +#ARCHIVE=libtool -c -static -stack_size 0x1000000 -o +ARCHIVE=ar rs +#------------------------------------------------------------------------------------------# diff --git a/ED/build/make/include.mk.docker.intel b/ED/build/make/include.mk.docker.intel new file mode 100644 index 000000000..6defd47fe --- /dev/null +++ b/ED/build/make/include.mk.docker.intel @@ -0,0 +1,157 @@ +#==========================================================================================# +#==========================================================================================# +# Makefile include.mk.docker.intel # +#------------------------------------------------------------------------------------------# + +#----- Define make (gnu make works best). -------------------------------------------------# +MAKE=/usr/bin/make +#------------------------------------------------------------------------------------------# + +#----- Main path for compilation. ---------------------------------------------------------# +BASE=$(ED_ROOT)/build/ +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# HDF 5 libraries. # +# # +# Since ED-2.1, this is no longer optional for real simulations. You must have the # +# HDF5 libraries compiled with the same compiler you set for F_COMP and C_COMP. You may # +# still be able to compile without HDF5 but the code is not going to run. # +#------------------------------------------------------------------------------------------# +HDF5_PATH=/opt/HDF_Group/HDF5/1.10.9 +HDF5_INCS=-I$(HDF5_PATH)/include/static +HDF5_LIBS=-L$(HDF5_PATH)/lib -lhdf5_fortran -lhdf5_f90cstub -lhdf5_hl -lhdf5 \ + -lz -lszaec -laec -lm +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# If you have a version of hdf5 compiled in parallel, then you may benefit from # +# collective I/O, then use this flag = 1. Otherwise, set it to zero. # +#------------------------------------------------------------------------------------------# +USE_COLLECTIVE_MPIO=0 +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# This should be 1 unless you are running with -gen-interfaces. Interfaces usually # +# make the compilation to crash when the -gen-interfaces option are on, so this flag # +# bypass all interfaces in the code. # +#------------------------------------------------------------------------------------------# +USE_INTERF=1 +#------------------------------------------------------------------------------------------# + +#################################### COMPILER SETTINGS ##################################### +CMACH=DOCKER_INTEL +FC_TYPE=INTEL +F_COMP=ifort +C_COMP=icc +LOADER=ifort +LIBS= +MOD_EXT=mod +#------------------------------------------------------------------------------------------# + +##################################### COMPILER OPTIONS ##################################### +#------------------------------------------------------------------------------------------# +# A/B. Pickiest - Use this whenever you change arguments on functions and subroutines. # +# This will perform the same tests as B but it will also check whether all # +# arguments match between subroutine declaration and subroutine calls. # +# WARNING: In order to really check all interfaces you must compile with # +# this option twice: # +# 1. Compile (./install.sh A) # +# 2. Prepare second compilation(./2ndcomp.sh) # +# 3. Compile one more time (./install.sh B) # +# If the compilation fails either at step 3, then your code has interface # +# problems. If it successfully compiles, then the code is fine for # +# interfaces. # +# C. Pickiest with no interface - This will compile fast but the run will be slow due to # +# the -O0 option. However, by setting -O0 you will take full advantage of the intel # +# debugger. # +# Ideally, you should compile your code with this option whenever you make any changes. # +# Note, however, that if you change arguments you should first try A. # +# D. Fast check - This will check pretty much the same as C, but it will not set up # +# anything for the debugger. Use this only if you really don't want to deal with idb or # +# if you have a good idea of which problem you are dealing with. # +# E. Fast - This is all about performance, use only when you are sure that the model has # +# no code problem, and you want results asap. This will not check for any # +# problems, which means that this is an option suitable for end users, not de- # +# velopers. # +#------------------------------------------------------------------------------------------# +ifeq ($(KIND_COMP),) + KIND_COMP=E +endif +#------------------------------------------------------------------------------------------# +ifeq ($(KIND_COMP),A) + USE_INTERF=0 + F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ + -warn declarations -gen-interfaces -qopenmp -diag-error=all -static + C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static + LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ + -warn declarations -gen-interfaces -qopenmp -diag-error=all -static + #---------------------------------------------------------------------------------------# +endif +ifeq ($(KIND_COMP),B) + USE_INTERF=0 + F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ + -warn interfaces -warn declarations -qopenmp -diag-error=all -static + C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static + LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ + -warn interfaces -warn declarations -qopenmp -diag-error=all -static + #---------------------------------------------------------------------------------------# +endif +ifeq ($(KIND_COMP),C) + USE_INTERF=1 + F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -qopenmp -diag-error=all -static + C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static + LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ + -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ + -implicitnone -assume byterecl -qopenmp -diag-error=all -static + #---------------------------------------------------------------------------------------# +endif +ifeq ($(KIND_COMP),D) + USE_INTERF=1 + F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -fpe0 -no-ftz -traceback \ + -ftrapuv -fp-stack-check -implicitnone -assume byterecl -qopenmp \ + -diag-error=all -static + C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static + LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -fpe0 -no-ftz -traceback \ + -ftrapuv -fp-stack-check -implicitnone -assume byterecl -qopenmp \ + -diag-error=all -static + #---------------------------------------------------------------------------------------# +endif +ifeq ($(KIND_COMP),E) + USE_INTERF=1 + F_OPTS=-FR -O3 -recursive -traceback -assume byterecl -qopenmp -static + C_OPTS=-O3 -DLITTLE -traceback -qopenmp -static + F_LOWO_OPTS=-FR -O2 -recursive -traceback -assume byterecl -qopenmp -static + LOADER_OPTS=-FR -O3 -recursive -traceback -assume byterecl -qopenmp -static + #---------------------------------------------------------------------------------------# +endif +#------------------------------------------------------------------------------------------# +############################################################################################ + +#------------------------------------------------------------------------------------------# +# If using mpicc and mpif90 as compilers (recommended), leave MPI_PATH, PAR_INCS, and # +# PAR_LIBS blank, otherwise provide the includes and libraries for mpi. Either way, don't # +# change PAR_DEFS unless you know what you are doing. # +#------------------------------------------------------------------------------------------# +MPI_PATH= +PAR_INCS= +PAR_LIBS= +PAR_DEFS= +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# Archive options. # +#------------------------------------------------------------------------------------------# +#------ For IBM, HP, SGI, ALPHA, LINUX, and MAC_OS_X use these. ---------------------------# +ARCHIVE=ar rs +#------------------------------------------------------------------------------------------# diff --git a/ED/build/make/include.mk.macosx b/ED/build/make/include.mk.macosx index 9d0d94a2d..054f1e11b 100644 --- a/ED/build/make/include.mk.macosx +++ b/ED/build/make/include.mk.macosx @@ -5,7 +5,7 @@ #----- Define make (gnu make works best). -------------------------------------------------# -MAKE=/usr/bin/make +MAKE=/usr/local/bin/make #------------------------------------------------------------------------------------------# #----- Libraries. -------------------------------------------------------------------------# @@ -51,10 +51,9 @@ USE_INTERF=1 #################################### COMPILER SETTINGS ##################################### CMACH=MAC_OS_X FC_TYPE=GNU -F_COMP=gfortran-13 -C_COMP=gcc-13 -LOADER=gfortran-13 -C_LOADER=gcc-13 +F_COMP=/usr/local/bin/gfortran-14 +C_COMP=/usr/local/bin/gcc-14 +LOADER=/usr/local/bin/gfortran-14 LIBS= MOD_EXT=mod ############################################################################################ @@ -88,20 +87,17 @@ endif ifeq ($(KIND_COMP),A) F_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ - -fcheck=all -frecursive -fsignaling-nans -Werror -mmacosx-version-min=10.12 \ - -fopenmp -static - C_OPTS= -O0 -DLITTLE -g -static + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace -static + C_OPTS= -O0 -DLITTLE -g -fbacktrace -static LOADER_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ - -fcheck=all -frecursive -fsignaling-nans -Werror \ - -mmacosx-version-min=10.12 -fopenmp + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif ifeq ($(KIND_COMP),E) - F_OPTS= -O3 -ffree-line-length-none -frecursive -mmacosx-version-min=10.12 -fopenmp \ - -static - C_OPTS= -O0 -DLITTLE -g -static - LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -mmacosx-version-min=10.12 -fopenmp + F_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace -static + C_OPTS= -O3 -DLITTLE -g -fbacktrace -static + LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif #------------------------------------------------------------------------------------------# diff --git a/ED/build/make/include.mk.travisci b/ED/build/make/include.mk.travisci index 243995438..35ade16d0 100644 --- a/ED/build/make/include.mk.travisci +++ b/ED/build/make/include.mk.travisci @@ -39,17 +39,27 @@ USE_COLLECTIVE_MPIO=0 + +#------------------------------------------------------------------------------------------# +# This should be 1 unless you are running with -gen-interfaces. Interfaces usually # +# make the compilation to crash when the -gen-interfaces option are on, so this flag # +# bypass all interfaces in the code. # +#------------------------------------------------------------------------------------------# +USE_INTERF=1 +#------------------------------------------------------------------------------------------# + + + #################################### COMPILER SETTINGS ##################################### CMACH=TRAVISCI FC_TYPE=GNU -F_COMP=mpif90 -C_COMP=mpicc -LOADER=mpif90 +F_COMP=gfortran +C_COMP=gcc +LOADER=gfortran LIBS= MOD_EXT=mod #------------------------------------------------------------------------------------------# -USE_INTERF=1 ##################################### COMPILER OPTIONS ##################################### @@ -62,19 +72,19 @@ ifeq ($(KIND_COMP),) endif #------------------------------------------------------------------------------------------# ifeq ($(KIND_COMP),$(filter $(KIND_COMP), A B C D)) - F_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=nan \ - -ffpe-trap=invalid,zero,overflow,underflow -fbacktrace -fbounds-check \ - -frecursive - C_OPTS= -O0 -DLITTLE -g - LOADER_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=nan \ - -ffpe-trap=invalid,zero,overflow,underflow -fbacktrace -fbounds-check \ - -frecursive + F_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ + -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace -static + C_OPTS= -O0 -DLITTLE -g -fbacktrace -static + LOADER_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ + -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif ifeq ($(KIND_COMP),E) - F_OPTS= -O3 -ffree-line-length-none -frecursive -fno-whole-file -static - C_OPTS= -O0 -DLITTLE -g -static - LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -fno-whole-file + F_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace -static + C_OPTS= -O3 -DLITTLE -g -fbacktrace -static + LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif #------------------------------------------------------------------------------------------# @@ -91,7 +101,7 @@ endif MPI_PATH= PAR_INCS= PAR_LIBS= -PAR_DEFS=-DRAMS_MPI +PAR_DEFS= #------------------------------------------------------------------------------------------# diff --git a/ED/build/make/objects.mk b/ED/build/make/objects.mk index 51ce5faa7..2eaa696c6 100644 --- a/ED/build/make/objects.mk +++ b/ED/build/make/objects.mk @@ -51,6 +51,7 @@ OBJ_MODEL = \ ed_print.o \ ed_read_ed10_20_history.o \ ed_read_ed21_history.o \ + ed_read_ed22_initial.o \ ed_state_vars.o \ ed_therm_lib.o \ ed_type_init.o \ diff --git a/ED/build/make/rules.mk b/ED/build/make/rules.mk index 4a88bb0eb..c0c03b7e0 100644 --- a/ED/build/make/rules.mk +++ b/ED/build/make/rules.mk @@ -208,6 +208,11 @@ ed_read_ed21_history.o : $(ED_IO)/ed_read_ed21_history.f90 /bin/cp -f $< $( /dev/null +sed -i~ s@mpi.mod@@g dependency.mk sed -i~ s@hdf5.mod@@g dependency.mk sed -i~ s@ifport.mod@@g dependency.mk sed -i~ s@leaf.coms.mod@@g dependency.mk diff --git a/ED/run/ED2IN b/ED/run/ED2IN index 11f752ea3..bdb14cce1 100644 --- a/ED/run/ED2IN +++ b/ED/run/ED2IN @@ -412,7 +412,7 @@ $ED_NL ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -420,6 +420,10 @@ $ED_NL ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! NL%IED_INIT_MODE = 6 !---------------------------------------------------------------------------------------! @@ -728,14 +732,17 @@ $ED_NL !---------------------------------------------------------------------------------------! ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. Choose ! ! the option according to the site characteristics. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, use ! + ! flat bedrock, otherwise assume free drainage. This option is more ! + ! relevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! ! bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction is ! ! controlled by variable SLDRAIN. In the future options 0, 1, and 2 may ! ! be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! ! always at saturation. ! !---------------------------------------------------------------------------------------! NL%ISOILBC = 1 @@ -895,18 +902,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! - ! equations depend on wood density; (b) use leaf area based allometry ! - ! instead of leaf biomass based allometry, which is more compatible with ! - ! trait plasticity in SLA; (c) use height-based root allometry from ! - ! Smith-Martin et al. (2020, New Phyt.) ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 3 !---------------------------------------------------------------------------------------! @@ -976,12 +984,19 @@ $ED_NL ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! + ! ! ! 4: (Beta). ! ! grasses - drought-deciduous (hydraulics scheme); ! ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! @@ -1577,6 +1592,7 @@ $ED_NL ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! @@ -1589,7 +1605,6 @@ $ED_NL !---------------------------------------------------------------------------------------! NL%IANTH_DISTURB = 0 NL%SL_SCALE = 1 - NL%SL_SCALE = 0 NL%SL_YR_FIRST = 1992 NL%SL_NYRS = 50 NL%SL_PFT = 2,3,4 @@ -1597,6 +1612,7 @@ $ED_NL NL%SL_MINDBH_HARVEST = 50.,50.,50. NL%SL_BIOMASS_HARVEST = 0 NL%SL_SKID_REL_AREA = 1 + NL%SL_SKID_DBH_THRESH = 30. NL%SL_SKID_S_GTHARV = 1 NL%SL_SKID_S_LTHARV = 0.6 NL%SL_FELLING_S_LTHARV = 0.35 diff --git a/ED/src/driver/ed_1st.F90 b/ED/src/driver/ed_1st.F90 index e2d3acd3b..38a5219c3 100644 --- a/ED/src/driver/ed_1st.F90 +++ b/ED/src/driver/ed_1st.F90 @@ -22,13 +22,12 @@ subroutine ed_1st_master (ipara, nnodestotal,nslaves, headnode_num, max_threads, use ed_misc_coms , only : runtype ! ! intent(inout) use ed_state_vars, only : allocate_edglobals & ! subroutine , filltab_alltypes ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: ipara ! 0 if sequential run; 1 if parallel run integer , intent(in) :: nnodestotal ! total number of nodes on any run @@ -176,10 +175,12 @@ end subroutine ed_1st_master !------------------------------------------------------------------------------------------! subroutine ed_1st_node() use ed_mem_alloc, only : ed_memory_allocation ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Pre-compiled variables from MPI. ------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' !----- Local variable (MPI only). ------------------------------------------------------! integer :: ierr #endif diff --git a/ED/src/driver/ed_driver.F90 b/ED/src/driver/ed_driver.F90 index 1c7ff8724..d13c6927e 100644 --- a/ED/src/driver/ed_driver.F90 +++ b/ED/src/driver/ed_driver.F90 @@ -21,13 +21,19 @@ subroutine ed_driver() use ed_state_vars , only : allocate_edglobals & ! sub-routine , filltab_alltypes & ! sub-routine , edgrid_g ! ! intent(inout) - use ed_misc_coms , only : runtype & ! intent(in) - , iooutput ! ! intent(in) + use ed_misc_coms , only : dtlsm & ! intent(in) + , runtype & ! intent(in) + , current_time & ! intent(in) + , isoutput & ! intent(in) + , iooutput & ! intent(in) + , fmtrest & ! intent(in) + , restore_file ! ! intent(in) use soil_coms , only : alloc_soilgrid ! ! sub-routine use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : recvnum ! ! intent(in) #endif use detailed_coms , only : idetailed & ! intent(in) @@ -36,11 +42,8 @@ subroutine ed_driver() use hrzshade_utils , only : init_cci_variables ! ! subroutine use canopy_radiation_coms, only : ihrzrad ! ! intent(in) use random_utils , only : init_random_seed ! ! subroutine + use budget_utils , only : ed_init_budget ! ! subroutine implicit none - !----- Included variables. -------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' ! MPI commons -#endif !----- Local variables. ----------------------------------------------------------------! character(len=12) :: c0 character(len=12) :: c1 @@ -157,14 +160,6 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Allocate soil grid arrays. ! - !---------------------------------------------------------------------------------------! - if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Alloc_Soilgrid...' - call alloc_soilgrid() - !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! ! Set some polygon-level basic information, such as lon/lat/soil texture. ! @@ -176,16 +171,14 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Initialize inherent soil and vegetation properties. ! - !---------------------------------------------------------------------------------------! - if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Sfcdata_ED...' - call sfcdata_ed() + ! Decide whether to initialise ED2 or resume from history files. Note that the ! + ! order of operations will depend upon the run type. If we resume from HISTORY, we ! + ! must read the history first then allocate soil data (as they will be read from the ! + ! history file itself). Otherwise, we allocate and initialise soils, then read/assign ! + ! the initial conditions. ! !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - if (trim(runtype) == 'HISTORY' ) then + select case (trim(runtype)) + case ('HISTORY') !------------------------------------------------------------------------------------! ! Initialize the model state as a replicate image of a previous state. ! !------------------------------------------------------------------------------------! @@ -210,7 +203,26 @@ subroutine ed_driver() if (nnodetot /= 1 ) call MPI_Barrier(MPI_COMM_WORLD,ierr) #endif !------------------------------------------------------------------------------------! - else + + + case default + !------------------------------------------------------------------------------------! + ! Allocate soil grid arrays. ! + !------------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Alloc_Soilgrid...' + call alloc_soilgrid() + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Initialise variables that are related to soil layers. ! + !------------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Sfcdata_ED...' + call sfcdata_ed() + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Initialize state properties of polygons/sites/patches/cohorts. ! @@ -218,7 +230,9 @@ subroutine ed_driver() if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Load_Ecosystem_State...' call load_ecosystem_state() !------------------------------------------------------------------------------------! - end if + end select + !---------------------------------------------------------------------------------------! + !---------------------------------------------------------------------------------------! ! In case the runs is going to produce detailed output, we eliminate all patches ! @@ -291,27 +305,29 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Initialise some derived variables. Skip this in case the simulation is resuming ! + ! Bypass the initialisation of derived variables and phenology when initialising ED2 ! ! from HISTORY. ! !---------------------------------------------------------------------------------------! - if (trim(runtype) /= 'HISTORY' ) then + select case (trim(runtype)) + case ('HISTORY') + !---- Do nothing. -------------------------------------------------------------------! + continue + !------------------------------------------------------------------------------------! + case default + !---- Initialise some derived variables. --------------------------------------------! do ifm=1,ngrids call update_derived_props(edgrid_g(ifm)) end do - end if - !---------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Initialise drought phenology. This should be done after the soil moisture has ! - ! been set up. ! - !---------------------------------------------------------------------------------------! - if (runtype /= 'HISTORY') then + !---- Initialise drought phenology. -------------------------------------------------! do ifm=1,ngrids call first_phenology(edgrid_g(ifm)) end do - end if + !------------------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------------------! @@ -359,26 +375,86 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Get the CPU time and print the banner. ! - !---------------------------------------------------------------------------------------! - call timing(1,t1) - w2 = walltime(wtime_start) - if (mynum == nnodetot) then - write(c0,'(f12.2)') t1 - write(c1,'(f12.2)') w2-w1 - write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & - trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & - '; Time integration starts (ed_master) ===' - end if + ! STEP 14. Run the model or skip if it is a zero time run. In case this is a zero time ! + ! run, write the history file and the flag for restoring the run (this can ! + ! be useful for model initialisation with large number of patches in the input ! + ! file. In this case, one may need to request substantially more memory for ! + ! initialisation (but a single CPU as initialisation does not benefit from ! + ! shared-memory parallel processing), then runs can be re-submitted with less ! + ! memory demand but more CPUs, hence reducing impacts on fairshare scores. ! !---------------------------------------------------------------------------------------! + if (time < timmax) then + !------------------------------------------------------------------------------------! + ! Get the CPU time and print the banner. ! + !------------------------------------------------------------------------------------! + call timing(1,t1) + w2 = walltime(wtime_start) + if (mynum == nnodetot) then + write(c0,'(f12.2)') t1 + write(c1,'(f12.2)') w2-w1 + write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & + trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & + '; Time integration starts (ed_model) ===' + end if + !------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! STEP 14. Run the model or skip if it is a zero time run. ! - !---------------------------------------------------------------------------------------! - if (time < timmax) then + !----- Call the time step driver. ---------------------------------------------------! call ed_model() + !------------------------------------------------------------------------------------! + else if ((timmax < dtlsm) .and. (isoutput /= 0)) then + !----- Write the zero-time output only if the run type is 'INITIAL'. ----------------! + select case (trim(runtype)) + case ('INITIAL') + + !---------------------------------------------------------------------------------! + ! We must reset all budget fluxes and set all budget stocks before writing ! + ! the history file. This is needed because when we resume ED2 runs from history ! + ! files, all budget variables are read from history instead of being initialised. ! + !---------------------------------------------------------------------------------! + if (mynum == nnodetot) write(unit=*,fmt='(a)') ' [+] ED_Init_Budget.' + do ifm=1,ngrids + call ed_init_budget(edgrid_g(ifm),.true.) + end do + !---------------------------------------------------------------------------------! + + + !----- Write the output file. ----------------------------------------------------! + call h5_output('HIST') + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Write a file with the current history time. ! + !---------------------------------------------------------------------------------! + if (mynum == nnodetot) then + open (unit=18,file=trim(restore_file),form='formatted',status='replace' & + ,action='write') + write(unit=18,fmt=fmtrest) current_time%year,current_time%month & + ,current_time%date,current_time%hour & + ,current_time%min + close(unit=18,status='keep') + end if + !------------------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Get the CPU time and print the banner. ! + !------------------------------------------------------------------------------------! + call timing(1,t1) + w2 = walltime(wtime_start) + if (mynum == nnodetot) then + write(c0,'(f12.2)') t1 + write(c1,'(f12.2)') w2-w1 + write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & + trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & + ' ===' + end if + !------------------------------------------------------------------------------------! end if !---------------------------------------------------------------------------------------! @@ -544,6 +620,9 @@ subroutine exterminate_patches_except(keeppa) , patchtype ! ! structure use grid_coms , only : ngrids ! ! intent(in) use fuse_fiss_utils, only : terminate_patches ! ! sub-routine + + implicit none + !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: keeppa !----- Local variables -----------------------------------------------------------------! diff --git a/ED/src/driver/ed_met_driver.f90 b/ED/src/driver/ed_met_driver.f90 index e6fb7449a..a5e6d6628 100644 --- a/ED/src/driver/ed_met_driver.f90 +++ b/ED/src/driver/ed_met_driver.f90 @@ -345,6 +345,8 @@ subroutine read_met_drivers_init type(edtype) , pointer :: cgrid character(len=str_len) :: infile integer :: igr + integer :: year_cyc + integer :: year_cyc_2 integer :: year_use integer :: iformat integer :: iv @@ -526,9 +528,18 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------------! ! We now retrieve the met driver year based on the stored sequence. ! !------------------------------------------------------------------------------------! - iyear = current_time%year-iyeara+1 - year_use = metyears(iyear) - + !----- If we need to recycle over years, find the appropriate year to apply. --------! + year_cyc = current_time%year + ncyc = metcycf - metcyc1 + 1 + !----- If we are after the last year... ---------------------------------------------! + do while(year_cyc > metcycf) + year_cyc = year_cyc - ncyc + end do + !----- If we are before the first year... -------------------------------------------! + do while(year_cyc < metcyc1) + year_cyc = year_cyc + ncyc + end do + !------------------------------------------------------------------------------------! gridloop: do igr = 1,ngrids @@ -536,7 +547,7 @@ subroutine read_met_drivers_init !----- Loop over the different file formats --------------------------------------! formloop: do iformat = 1, nformats - + !------------------------------------------------------------------------------! ! SPECIAL CASE FOR CO2: ! ! Usually we do not want to cycle CO2 but only the other meteorology. ! @@ -545,8 +556,30 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------! not_cycle_co2 = (met_nv(iformat) == 1 .and. trim(met_vars(iformat,1)) == 'co2') if (not_cycle_co2) then - year_use = current_time%year - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),current_time%year & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use = current_time%year + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use = year_cyc + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use = year_cyc + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + !----- Create the file name and check whether it exists. ----------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use & ,mname(current_time%month),'.h5' @@ -555,10 +588,17 @@ subroutine read_met_drivers_init call shdf5_open_f(trim(infile),'R') else write (unit=*,fmt='(a)' ) '------------------------------' - write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 - write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf - write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear - write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - NYEARS =',nyears + write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers_init','ed_met_driver.f90') @@ -573,7 +613,7 @@ subroutine read_met_drivers_init !----- Loop over variables. and read the data. --------------------------------! do iv = 1, met_nv(iformat) offset = 0 - call read_ol_file(infile,iformat, iv, mname(current_time%month) & + call read_ol_file(infile,iformat, iv, mname(current_time%month) & ,current_time%year, offset, cgrid) end do @@ -584,27 +624,61 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------! ! For all interpolated variables, we also need the next time. ! !------------------------------------------------------------------------------! - !------ Find next month and year ----------------------------------------------! - m2 = current_time%month + 1 - + !------------------------------------------------------------------------------! - ! If this takes us into the next year, take the next year in sequence and ! - ! reset month to January. ! + ! Find next month and year. If this takes us into the next year, increment ! + ! year and reset month to January. ! !------------------------------------------------------------------------------! - if (m2 == 13) then - m2 = 1 - y2 = current_time%year + 1 - else - !----- Otherwise, use the same year. ---------------------------------------! - y2 = current_time%year - end if - iyear = y2 - iyeara + 1 - year_use_2 = metyears(iyear) - - ! Again consider the special case of not cycling co2 + m2 = current_time%month + 1 + select case (m2) + case (13) + m2 = 1 + y2 = current_time%year + 1 + year_cyc_2 = y2 + + !----- If we are now after the last year... --------------------------------! + do while(year_cyc_2 > metcycf) + year_cyc_2 = year_cyc_2 - ncyc + end do + !---------------------------------------------------------------------------! + + !----- If we are now before the first year... ------------------------------! + do while(year_cyc_2 < metcyc1) + year_cyc_2 = year_cyc_2 + ncyc + end do + !---------------------------------------------------------------------------! + case default + !---- Same year as the previous month. -------------------------------------! + y2 = current_time%year + year_cyc_2 = year_cyc + !---------------------------------------------------------------------------! + end select + + !------------------------------------------------------------------------------# + ! Again consider the special case of not cycling co2 + !------------------------------------------------------------------------------# if (not_cycle_co2) then - year_use_2 = y2 - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),y2,mname(m2),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use_2 = y2 + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use_2 = year_cyc_2 + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use_2 = year_cyc_2 + !---------------------------------------------------------------------------! + end if !----- Now, open the file once. -----------------------------------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use_2 & ,mname(m2),'.h5' @@ -612,10 +686,26 @@ subroutine read_met_drivers_init if (exans) then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - NYEARS =',nyears + write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CYC_2 =',m2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC_2 =',year_cyc_2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE_2 =',year_use_2 + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers_init','ed_met_driver.f90') end if - + !----- Loop over variables. ---------------------------------------------------! varloop: do iv = 1, met_nv(iformat) @@ -674,6 +764,8 @@ subroutine read_met_drivers type(edtype) , pointer :: cgrid character(len=str_len) :: infile integer :: igr + integer :: year_cyc + integer :: year_cyc_2 integer :: year_use integer :: ncyc integer :: iformat @@ -694,17 +786,17 @@ subroutine read_met_drivers !----- If we need to recycle over years, find the appropriate year to apply. --------! - year_use = current_time%year - ncyc = metcycf - metcyc1 + 1 + year_cyc = current_time%year + ncyc = metcycf - metcyc1 + 1 !----- If we are after the last year... ---------------------------------------------! - do while(year_use > metcycf) - year_use = year_use - ncyc + do while(year_cyc > metcycf) + year_cyc = year_cyc - ncyc end do !----- If we are before the first year... -------------------------------------------! - do while(year_use < metcyc1) - year_use = year_use + ncyc + do while(year_cyc < metcyc1) + year_cyc = year_cyc + ncyc end do gridloop: do igr=1,ngrids @@ -713,7 +805,7 @@ subroutine read_met_drivers !----- Loop over the different file formats --------------------------------------! formloop: do iformat = 1, nformats - + !------------------------------------------------------------------------------! ! SPECIAL CASE FOR CO2: ! ! Usually we do not want to cycle CO2 but only the other meteorology. ! @@ -722,8 +814,32 @@ subroutine read_met_drivers !------------------------------------------------------------------------------! not_cycle_co2 = (met_nv(iformat) == 1 .and. trim(met_vars(iformat,1)) == 'co2') if (not_cycle_co2) then - year_use = current_time%year - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),current_time%year & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use = current_time%year + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use = year_cyc + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use = year_cyc + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Create the file name and check whether it exists. ----------------------! write(infile,'(a,i4.4,a,a)')trim(met_names(iformat)), year_use, & mname(current_time%month),'.h5' @@ -732,6 +848,17 @@ subroutine read_met_drivers if(exans)then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers','ed_met_driver.f90') end if @@ -766,37 +893,63 @@ subroutine read_met_drivers !------------------------------------------------------------------------------! ! For all interpolated variables, we also need the next time. ! !------------------------------------------------------------------------------! - !------ Find next month and year ----------------------------------------------! - m2 = current_time%month + 1 - y2 = current_time%year - year_use_2 = year_use - - + !------------------------------------------------------------------------------! - ! If this takes us into the next year, increment year and reset month to ! - ! January. ! + ! Find next month and year. If this takes us into the next year, increment ! + ! year and reset month to January. ! !------------------------------------------------------------------------------! - if(m2 == 13)then + m2 = current_time%month + 1 + select case (m2) + case (13) m2 = 1 y2 = current_time%year + 1 - year_use_2 = y2 + year_cyc_2 = y2 !----- If we are now after the last year... --------------------------------! - do while(year_use_2 > metcycf) - year_use_2 = year_use_2 - ncyc + do while(year_cyc_2 > metcycf) + year_cyc_2 = year_cyc_2 - ncyc end do - + !---------------------------------------------------------------------------! + !----- If we are now before the first year... ------------------------------! - do while(year_use_2 < metcyc1) - year_use_2 = year_use_2 + ncyc + do while(year_cyc_2 < metcyc1) + year_cyc_2 = year_cyc_2 + ncyc end do - end if + !---------------------------------------------------------------------------! + case default + !---- Same year as the previous month. -------------------------------------! + y2 = current_time%year + year_cyc_2 = year_cyc + !---------------------------------------------------------------------------! + end select - ! Again, consider the special case for not_cycle_co2 + !---- Again, consider the special case for not_cycle_co2. ---------------------! if (not_cycle_co2) then - year_use_2 = y2 - endif - + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),y2 & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use_2 = y2 + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use_2 = year_cyc_2 + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use_2 = year_cyc_2 + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + !----- Now, open the file once. -----------------------------------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use_2 & ,mname(m2),'.h5' @@ -804,6 +957,20 @@ subroutine read_met_drivers if (exans) then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CYC_2 =',m2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC_2 =',year_cyc_2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE_2 =',year_use_2 + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error ('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers','ed_met_driver.f90') end if diff --git a/ED/src/driver/ed_model.F90 b/ED/src/driver/ed_model.F90 index 77cc8f9d0..b82e35782 100644 --- a/ED/src/driver/ed_model.F90 +++ b/ED/src/driver/ed_model.F90 @@ -11,6 +11,7 @@ !------------------------------------------------------------------------------------------! subroutine ed_model() use ed_misc_coms , only : simtime & ! structure + , fmtrest & ! intent(in) , ivegt_dynamics & ! intent(in) , integration_scheme & ! intent(in) , current_time & ! intent(in) @@ -90,15 +91,14 @@ subroutine ed_model() , initialize_misc_stepvars ! ! sub-routine use stable_cohorts , only : flag_stable_cohorts ! ! sub-routine use update_derived_utils, only : update_model_time_dm ! ! sub-routine - use budget_utils , only : ed_init_budget ! ! intent(in) + use budget_utils , only : ed_init_budget ! ! sub-routine use vegetation_dynamics , only : veg_dynamics_driver ! ! sub-routine use ed_type_init , only : ed_init_viable ! ! sub-routine use soil_respiration , only : zero_litter_inputs ! ! sub-routine - implicit none - !----- Common blocks. ------------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! type(simtime) :: daybefore character(len=28) :: fmthead @@ -108,6 +108,7 @@ subroutine ed_model() integer :: ndays integer :: dbndays integer :: obstime_idx + logical :: last_step logical :: analysis_time logical :: observation_time logical :: new_day @@ -141,8 +142,6 @@ subroutine ed_model() ! during synchronization, so you ! can find out which node is the ! slow one - !----- String for output format. -------------------------------------------------------! - character(len=26), parameter :: fmtrest = '(i4.4,2(1x,i2.2),1x,2i2.2)' !----- External functions. -------------------------------------------------------------! real , external :: walltime ! Wall time integer , external :: num_days ! Number of days in the current month @@ -374,6 +373,7 @@ subroutine ed_model() dcyc_analy_time = new_month .and. writing_dcyc reset_time = mod(time,dble(frqsum)) < dble(dtlsm) annual_time = new_year .and. writing_year + last_step = time >= timmax !------------------------------------------------------------------------------------! @@ -434,6 +434,14 @@ subroutine ed_model() !------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! + ! If this is the last step, write the history even if it is not the a typical ! + ! time step to write history. ! + !------------------------------------------------------------------------------------! + history_time = history_time .or. last_step + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Update nrec_fast and nrec_state if it is a new month and outfast/outstate are ! diff --git a/ED/src/driver/edmain.F90 b/ED/src/driver/edmain.F90 index 53995bf4a..7be848c37 100644 --- a/ED/src/driver/edmain.F90 +++ b/ED/src/driver/edmain.F90 @@ -14,6 +14,9 @@ !------------------------------------------------------------------------------------------! program main !$ use omp_lib +#if defined(RAMS_MPI) + use mpi +#endif implicit none !---------------------------------------------------------------------------------------! @@ -49,10 +52,6 @@ program main integer, dimension(64) :: thread_use integer, dimension(64) :: cpu_use integer, external :: findmycpu - !------ MPI interface. -----------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/disturbance.f90 b/ED/src/dynamics/disturbance.f90 index f1dc10627..44ef4da90 100644 --- a/ED/src/dynamics/disturbance.f90 +++ b/ED/src/dynamics/disturbance.f90 @@ -51,8 +51,7 @@ subroutine apply_disturbances(cgrid) , plantation_year & ! intent(in) , treefall_hite_threshold & ! intent(in) , does_hite_limit_tfpatch & ! intent(in) - , min_oldgrowth & ! intent(in) - , sl_skid_rel_area ! ! intent(in) + , min_oldgrowth ! ! intent(in) use ed_max_dims , only : n_dist_types & ! intent(in) , n_pft & ! intent(in) , n_dbh ! ! intent(in) @@ -117,8 +116,14 @@ subroutine apply_disturbances(cgrid) logical :: same_pft logical :: is_primary real , dimension(n_pft) :: mindbh_harvest + real , dimension(n_pft) :: felling_s_gtharv + real , dimension(n_pft) :: felling_s_ltharv + real , dimension(n_pft) :: skid_dbh_thresh + real , dimension(n_pft) :: skid_s_gtharv + real , dimension(n_pft) :: skid_s_ltharv real :: pot_area_remain real :: area_loss_tot + real :: lambda_harv_og_max real :: lambda_sum real :: area_fac real :: orig_area @@ -212,8 +217,22 @@ subroutine apply_disturbances(cgrid) cpoly%combusted_fuel (isi) = 0.0 !------------------------------------------------------------------------------! - !----- Copy mindbh for harvesting to a local variable. ------------------------! + + !------------------------------------------------------------------------------! + ! Retrieve maximum logging disturbance rate for logging old-growth forests. ! + !------------------------------------------------------------------------------! + lambda_harv_og_max = cpoly%disturbance_rates(6,3,isi) + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! Copy harvest and skid trail instructions to local variables. ! + !------------------------------------------------------------------------------! mindbh_harvest (:) = cpoly%mindbh_harvest (:,isi) + felling_s_gtharv(:) = cpoly%felling_s_gtharv(:,isi) + felling_s_ltharv(:) = cpoly%felling_s_ltharv(:,isi) + skid_dbh_thresh (:) = cpoly%skid_dbh_thresh (:,isi) + skid_s_gtharv (:) = cpoly%skid_s_gtharv (:,isi) + skid_s_ltharv (:) = cpoly%skid_s_ltharv (:,isi) !------------------------------------------------------------------------------! @@ -257,7 +276,7 @@ subroutine apply_disturbances(cgrid) ! Find the area to be harvested when biomass targets have been ! ! established. ! !------------------------------------------------------------------------------! - call find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) + call find_lambda_harvest(cpoly,isi,onsp,lambda_harv_og_max,lambda_harvest) !------------------------------------------------------------------------------! @@ -445,17 +464,17 @@ subroutine apply_disturbances(cgrid) ! the tree felling disturbance, and can be thought as a way to quantify ! ! the logging impact. ! !---------------------------------------------------------------------------! - if (sl_skid_rel_area == 1.0) then + if (cpoly%skid_rel_area(isi) == 1.0) then !----- Special case: we simply copy the felling disturbance. ------------! lambda_now(7) = lambda_now(6) !------------------------------------------------------------------------! - else if (lambda_now(6) > 0.0 .and. sl_skid_rel_area > 0.0) then + else if (lambda_now(6) > 0.0 .and. cpoly%skid_rel_area(isi) > 0.0) then !------------------------------------------------------------------------! ! The collateral damage is given in terms of area, so we must ! ! convert the ratio to disturbance rate. We use the definition of ! ! disturbed area. ! !------------------------------------------------------------------------! - lfactor = sl_skid_rel_area * (1.0 - exp( - lambda_now(6))) + lfactor = cpoly%skid_rel_area(isi) * (1.0 - exp( - lambda_now(6))) if ( lfactor <= 1.0 * (1.0 - epsilon(1.0)) ) then lambda_now(7) = log( 1.0 / (1.0 - lfactor) ) else @@ -711,9 +730,14 @@ subroutine apply_disturbances(cgrid) ,cb_mass_np,cb_molar_np,cb_water_np & ,cb_co2_np) call insert_survivors(csite,onsp+new_lu,ipa,new_lu,area_fac & - ,mindbh_harvest) + ,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh & + ,skid_s_gtharv,skid_s_ltharv) call accum_dist_harv_litt(cpoly,isi,1,onsp+new_lu,ipa,new_lu & - ,area_fac,mindbh_harvest) + ,area_fac,mindbh_harvest & + ,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv & + ,skid_s_ltharv) !---------------------------------------------------------------! case (1) !---------------------------------------------------------------! @@ -742,9 +766,14 @@ subroutine apply_disturbances(cgrid) ,cb_mass_np,cb_molar_np,cb_water_np & ,cb_co2_np) call insert_survivors(csite,npa,ipa,new_lu,area_fac & - ,mindbh_harvest) + ,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh & + ,skid_s_gtharv,skid_s_ltharv) call accum_dist_harv_litt(cpoly,isi,1,npa,ipa,new_lu & - ,area_fac,mindbh_harvest) + ,area_fac,mindbh_harvest & + ,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv & + ,skid_s_ltharv) !------------------------------------------------------------! case default !------------------------------------------------------------! @@ -796,9 +825,15 @@ subroutine apply_disturbances(cgrid) ,cb_mass_np,cb_molar_np & ,cb_water_np,cb_co2_np) call insert_survivors(csite,npa,ipa,new_lu,area_fac & - ,mindbh_harvest) + ,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh & + ,skid_s_gtharv,skid_s_ltharv) call accum_dist_harv_litt(cpoly,isi,1,npa,ipa,new_lu & - ,area_fac,mindbh_harvest) + ,area_fac,mindbh_harvest & + ,felling_s_gtharv & + ,felling_s_ltharv & + ,skid_dbh_thresh & + ,skid_s_gtharv,skid_s_ltharv) end if !---------------------------------------------------------! end do @@ -830,9 +865,9 @@ subroutine apply_disturbances(cgrid) ! canopy air temperature. ! !------------------------------------------------------------------------! call update_patch_thermo_props(csite,onsp+new_lu,onsp+new_lu,nzg,nzs & - ,cpoly%ntext_soil(:,isi)) + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi)) call update_patch_thermo_fmean(csite,onsp+new_lu,onsp+new_lu,nzg & - ,cpoly%ntext_soil(:,isi)) + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi)) !------------------------------------------------------------------------! @@ -988,7 +1023,9 @@ subroutine apply_disturbances(cgrid) !------------------------------------------------------------------------------! old_lu_l4th: do ipa=1,onsp pat_area_loss = act_area_loss(ipa,:) - call disturbance_mortality(csite,ipa,pat_area_loss,mindbh_harvest) + call disturbance_mortality(csite,ipa,pat_area_loss,mindbh_harvest & + ,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv,skid_s_ltharv) csite%area(ipa) = csite%area(ipa) - sum(pat_area_loss) end do old_lu_l4th !------------------------------------------------------------------------------! @@ -1334,6 +1371,8 @@ subroutine site_disturbance_rates(year, cgrid) real :: bharvest real :: pot_harvest_target real :: fire_disturbance_rate + real :: lambda_harv_og_max + real :: f_harv_prim_max logical :: is_plantation logical :: is_rotation logical :: is_mature @@ -1547,6 +1586,26 @@ subroutine site_disturbance_rates(year, cgrid) + !------------------------------------------------------------------------------! + ! Logging disturbance. Here we define the maximum logging disturbance ! + ! possible for old-growth forests. The actual disturbance rate may be lower ! + ! (but never higher) than the rates obtained from the instruction file. ! + ! We save this information in cpoly%disturbance_rates(6,3,isi) only but this ! + ! is accounted for any old-growth patch (which includes types 4, 5, 6, and 7 ! + ! if their age is old). ! + !------------------------------------------------------------------------------! + lambda_harv_og_max = max(0.,min(lnexp_max,clutime%landuse(11))) + if (lambda_harv_og_max == lnexp_max) then + f_harv_prim_max = 1. + else + f_harv_prim_max = 1. - exp( - lambda_harv_og_max) + end if + !----- Save disturbance rate to the site level structure. ---------------------! + cpoly%disturbance_rates(6,3,isi) = lambda_harv_og_max + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! ! Harvesting (either plantation -> plantation or logging) when a biomass ! ! target does not exist (e.g. SimAmazonia)). Convert the harvest probability ! @@ -1563,7 +1622,7 @@ subroutine site_disturbance_rates(year, cgrid) !---------------------------------------------------------------------------! case default !------ Read anthropogenic disturbance from external data set. -------------! - if (clutime%landuse(12) < 0 .or. clutime%landuse(14) < 0) then + if (clutime%landuse(12) < 0. .or. clutime%landuse(14) < 0.) then find_target = .true. cpoly%primary_harvest_target (isi) = 0. cpoly%secondary_harvest_target(isi) = 0. @@ -1651,8 +1710,9 @@ subroutine site_disturbance_rates(year, cgrid) ! Accumulate site-level harvest target. ! !------------------------------------------------------------------------! if (harv_primary) then - cpoly%primary_harvest_target(isi) = & - cpoly%primary_harvest_target(isi) + bharvest * csite%area(ipa) + cpoly%primary_harvest_target(isi) = cpoly%primary_harvest_target(isi) & + + f_harv_prim_max * bharvest & + * csite%area(ipa) else if (harv_secondary) then cpoly%secondary_harvest_target(isi) = & cpoly%secondary_harvest_target(isi) + bharvest * csite%area(ipa) @@ -2265,6 +2325,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%fmean_sfcw_mass (np) = csite%fmean_sfcw_mass (np) & + csite%fmean_sfcw_mass (cp) & * area_fac + csite%fmean_snowfac (np) = csite%fmean_snowfac (np) & + + csite%fmean_snowfac (cp) & + * area_fac csite%fmean_rshort_gnd (np) = csite%fmean_rshort_gnd (np) & + csite%fmean_rshort_gnd (cp) & * area_fac @@ -2487,6 +2550,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%dmean_sfcw_fliq ( np) = csite%dmean_sfcw_fliq ( np) & + csite%dmean_sfcw_fliq ( cp) & * area_fac + csite%dmean_snowfac ( np) = csite%dmean_snowfac ( np) & + + csite%dmean_snowfac ( cp) & + * area_fac csite%dmean_rshort_gnd ( np) = csite%dmean_rshort_gnd ( np) & + csite%dmean_rshort_gnd ( cp) & * area_fac @@ -2770,6 +2836,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%mmean_sfcw_fliq ( np) = csite%mmean_sfcw_fliq ( np) & + csite%mmean_sfcw_fliq ( cp) & * area_fac + csite%mmean_snowfac ( np) = csite%mmean_snowfac ( np) & + + csite%mmean_snowfac ( cp) & + * area_fac csite%mmean_rshort_gnd ( np) = csite%mmean_rshort_gnd ( np) & + csite%mmean_rshort_gnd ( cp) & * area_fac @@ -3065,6 +3134,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%qmean_sfcw_fliq ( :,np) = csite%qmean_sfcw_fliq ( :,np) & + csite%qmean_sfcw_fliq ( :,cp) & * area_fac + csite%qmean_snowfac ( :,np) = csite%qmean_snowfac ( :,np) & + + csite%qmean_snowfac ( :,cp) & + * area_fac csite%qmean_soil_energy (:,:,np) = csite%qmean_soil_energy (:,:,np) & + csite%qmean_soil_energy (:,:,cp) & * area_fac @@ -3331,7 +3403,9 @@ end subroutine norm_canopy_air_props ! This subroutine will populate the disturbed patch with the cohorts that were ! ! disturbed but did not go extinct. ! !---------------------------------------------------------------------------------------! - subroutine insert_survivors(csite,np,cp,new_lu,area_fac,mindbh_harvest) + subroutine insert_survivors(csite,np,cp,new_lu,area_fac,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh,skid_s_gtharv & + ,skid_s_ltharv) use ed_state_vars , only : sitetype & ! structure , patchtype ! ! structure use ed_max_dims , only : n_pft ! ! intent(in) @@ -3345,6 +3419,11 @@ subroutine insert_survivors(csite,np,cp,new_lu,area_fac,mindbh_harvest) integer , intent(in) :: np integer , intent(in) :: cp real , dimension(n_pft), intent(in) :: mindbh_harvest + real , dimension(n_pft), intent(in) :: felling_s_gtharv + real , dimension(n_pft), intent(in) :: felling_s_ltharv + real , dimension(n_pft), intent(in) :: skid_dbh_thresh + real , dimension(n_pft), intent(in) :: skid_s_gtharv + real , dimension(n_pft), intent(in) :: skid_s_ltharv real , intent(in) :: area_fac !----- Local variables. -------------------------------------------------------------! type(patchtype) , pointer :: cpatch @@ -3379,7 +3458,10 @@ subroutine insert_survivors(csite,np,cp,new_lu,area_fac,mindbh_harvest) survivalloop: do ico = 1,cpatch%ncohorts ipft = cpatch%pft(ico) survival_fac(ico) = survivorship(new_lu,csite%dist_type(cp),mindbh_harvest & - ,cpatch,ico) * area_fac + ,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv,skid_s_ltharv & + ,cpatch,ico ) & + * area_fac n_survivors = cpatch%nplant(ico) * survival_fac(ico) !----- If something survived, make a new cohort. ------------------------------! @@ -3463,7 +3545,8 @@ end subroutine insert_survivors ! place. ! !---------------------------------------------------------------------------------------! subroutine accum_dist_harv_litt(cpoly,isi,census_flag,np,cp,new_lu,area_fac & - ,mindbh_harvest) + ,mindbh_harvest,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv,skid_s_ltharv) use ed_state_vars, only : sitetype & ! structure , patchtype & ! structure , polygontype ! ! structure @@ -3492,6 +3575,11 @@ subroutine accum_dist_harv_litt(cpoly,isi,census_flag,np,cp,new_lu,area_fac integer , intent(in) :: np integer , intent(in) :: cp real , dimension(n_pft), intent(in) :: mindbh_harvest + real , dimension(n_pft), intent(in) :: felling_s_gtharv + real , dimension(n_pft), intent(in) :: felling_s_ltharv + real , dimension(n_pft), intent(in) :: skid_dbh_thresh + real , dimension(n_pft), intent(in) :: skid_s_gtharv + real , dimension(n_pft), intent(in) :: skid_s_ltharv integer , intent(in) :: new_lu real , intent(in) :: area_fac !----- Local variables. -------------------------------------------------------------! @@ -3701,7 +3789,9 @@ subroutine accum_dist_harv_litt(cpoly,isi,census_flag,np,cp,new_lu,area_fac !----- Find survivorship. --------------------------------------------------------! - survival_fac = survivorship(new_lu,csite%dist_type(cp),mindbh_harvest,cpatch,ico) + survival_fac = survivorship(new_lu,csite%dist_type(cp),mindbh_harvest & + ,felling_s_gtharv,felling_s_ltharv,skid_dbh_thresh & + ,skid_s_gtharv,skid_s_ltharv,cpatch,ico) !---------------------------------------------------------------------------------! @@ -4098,7 +4188,8 @@ subroutine prune_lianas(csite, np, lsl) , h2dbh & ! function , size2bl & ! function , size2bd & ! function - , size2krdepth ! ! function + , size2krdepth & ! function + , distrib_root ! ! subroutine use pft_coms, only : qsw & ! intent(in) , qbark & ! intent(in) , agf_bs & ! intent(in) @@ -4222,6 +4313,13 @@ subroutine prune_lianas(csite, np, lsl) !----- Update rooting depth ---------------------------------------------------! cpatch%krdepth(ico) = size2krdepth(cpatch%hite(ico),cpatch%dbh(ico),ipft,lsl) !if new root depth is smaller keep the old one + !------------------------------------------------------------------------------! + + + !----- Update the vertical distribution of roots. -----------------------------! + call distrib_root(cpatch%krdepth(ico),ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------! + !------------------------------------------------------------------------------! ! It is likely that biomass has changed, therefore, update ! diff --git a/ED/src/dynamics/euler_driver.f90 b/ED/src/dynamics/euler_driver.f90 index 416104399..ebfb5719d 100644 --- a/ED/src/dynamics/euler_driver.f90 +++ b/ED/src/dynamics/euler_driver.f90 @@ -19,6 +19,7 @@ subroutine euler_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use ed_max_dims , only : n_dbh ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function @@ -76,6 +77,7 @@ subroutine euler_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !------------------------------------------------------------------------------------! @@ -84,6 +86,31 @@ subroutine euler_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -97,22 +124,22 @@ subroutine euler_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar & - ,cmet%atm_theiv,cmet%atm_vpdef,cmet%atm_theta & - ,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2,cmet%geoht & - ,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & - ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & - ,cgrid%lat(ipy),cgrid%cosz(ipy)) + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & + ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -220,7 +247,8 @@ subroutine euler_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! @@ -432,8 +460,8 @@ subroutine integrate_patch_euler(csite,initp,dinitp,ytemp,yscal,dydx,ipa,isi,ibu !------------------------------------------------------------------------------------! ! Move the state variables from the integrated patch to the model patch. ! !------------------------------------------------------------------------------------! - call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm,ecurr_netrad & - ,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & + call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm & + ,ecurr_netrad,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & ,ecurr_loss2drainage,wcurr_loss2runoff,ecurr_loss2runoff & ,co2curr_denseffect,ecurr_denseffect,wcurr_denseffect) !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/events.f90 b/ED/src/dynamics/events.f90 index df3437763..80a454c83 100644 --- a/ED/src/dynamics/events.f90 +++ b/ED/src/dynamics/events.f90 @@ -509,6 +509,7 @@ end subroutine event_harvest subroutine event_planting(pft,density8) use rk4_integ_utils, only : initialize_rk4patches use update_derived_utils, only : update_patch_thermo_props & + , update_patch_thermo_fmean & , update_patch_derived_props & , update_site_derived_props use grid_coms, only : ngrids,nzg,nzs @@ -553,8 +554,11 @@ subroutine event_planting(pft,density8) csite => cpoly%site(isi) do ipa=1,csite%npatches - call update_patch_thermo_props(csite,ipa,ipa,nzg,nzs,cpoly%ntext_soil(:,isi)) - call plant_patch(csite,ipa,nzg,pft,density,cpoly%ntext_soil(:,isi) & + call update_patch_thermo_props(csite,ipa,ipa,nzg,nzs,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi)) + call update_patch_thermo_fmean(csite,ipa,ipa,nzg,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi)) + call plant_patch(csite,ipa,nzg,pft,density,cpoly%ntext_soil(:,isi) & ,planting_ht,cpoly%lsl(isi)) call update_patch_derived_props(csite,ipa,.true.) call new_patch_sfc_props(csite, ipa,nzg,nzs,cpoly%ntext_soil(:,isi)) diff --git a/ED/src/dynamics/farq_katul.f90 b/ED/src/dynamics/farq_katul.f90 index 877910f0e..90e769971 100644 --- a/ED/src/dynamics/farq_katul.f90 +++ b/ED/src/dynamics/farq_katul.f90 @@ -254,9 +254,6 @@ subroutine katul_lphys(ib,can_prss,can_rhos,can_shv,can_co2,ipft,leaf_par,leaf_t !update photosynthetic parameters with water stress select case (h2o_plant_lim) - case (0,1,2,3) - ! use fsw to account for water stress in photosyn_driv - water_stress_factor = 1. case (4) ! leaf water potential will influence stomata optimization ! at two different scales @@ -275,6 +272,9 @@ subroutine katul_lphys(ib,can_prss,can_rhos,can_shv,can_co2,ipft,leaf_par,leaf_t 1. / (1. + & 0.1 * (leaf_psi / leaf_psi_tlp(ipft)) ** 6.0))) lambda8 = lambda8 * dble(exp(stoma_beta(ipft) * dmax_leaf_psi)) + case default + ! use fsw to account for water stress in photosyn_driv + water_stress_factor = 1. end select !thispft(ib)%vm0 = thispft(ib)%vm0 * dble(water_stress_factor) @@ -857,7 +857,8 @@ subroutine photosynthesis_stomata_solver8(ib,gsc,limit_case, real(kind=8) :: rad !! sqrt(b2-4ac) real(kind=8) :: ciroot1 !! First root of ci real(kind=8) :: ciroot2 !! Second root of ci - real(kind=8) :: dbdg,dcdg !! derivatives of b,c wrt. gsc + real(kind=8) :: dbdg !! derivatives of b wrt. gsc + real(kind=8) :: dcdg !! derivatives of c wrt. gsc !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/fire.f90 b/ED/src/dynamics/fire.f90 index 0df3bcbf3..b93c9703e 100644 --- a/ED/src/dynamics/fire.f90 +++ b/ED/src/dynamics/fire.f90 @@ -62,7 +62,7 @@ subroutine fire_frequency(cgrid) real :: fuel real :: ignition_rate real :: mean_fire_intensity - real :: sum_pcpg + real :: sum_accp logical :: people_around !------------------------------------------------------------------------------------! @@ -97,8 +97,8 @@ subroutine fire_frequency(cgrid) ! Find the total rainfall of the past year and reset the counter for this ! ! month. ! !------------------------------------------------------------------------------! - sum_pcpg = sum(cpoly%avg_monthly_pcpg(:,isi)) - cpoly%avg_monthly_pcpg(imon,isi) = 0. + sum_accp = sum(cpoly%avg_monthly_accp(:,isi)) + cpoly%avg_monthly_accp(imon,isi) = 0. !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/forestry.f90 b/ED/src/dynamics/forestry.f90 index 320513cbf..7b8593ff1 100644 --- a/ED/src/dynamics/forestry.f90 +++ b/ED/src/dynamics/forestry.f90 @@ -24,7 +24,7 @@ module forestry ! This subroutine finds the disturbance rates associated with logging, when biomass ! ! demands are provided instead of actual disturbance rates. ! !---------------------------------------------------------------------------------------! - subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) + subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harv_og_max,lambda_harvest) use ed_state_vars , only : polygontype & ! structure , sitetype & ! structure , patchtype & ! structure @@ -32,7 +32,6 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) , deallocate_sitetype & ! subroutine , copy_sitetype ! ! subroutine use disturb_coms , only : ianth_disturb & ! intent(in) - , lutime & ! intent(in) , min_patch_area & ! intent(in) , plantation_rotation & ! intent(in) , min_harvest_biomass & ! intent(in) @@ -47,6 +46,7 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) type(polygontype) , target :: cpoly integer , intent(in) :: isi integer , intent(in) :: onsp + real , intent(inout) :: lambda_harv_og_max real, dimension(onsp) , intent(inout) :: lambda_harvest !----- Local variables --------------------------------------------------------------! type(sitetype) , pointer :: csite @@ -142,6 +142,10 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) ! croplands and pastures. ! !---------------------------------------------------------------------------------! select case(ilu) + case (1,8) + !---- Pasture or cropland. Do nothing. ----------------------------------------! + continue + !------------------------------------------------------------------------------! case (2:7) hcoh_loop: do ico=1,cpatch%ncohorts ipft = cpatch%pft(ico) @@ -241,7 +245,8 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) ,hvmax_mature_secondary,hvpot_mature_secondary & ,hvmax_mature_plantation,hvpot_mature_plantation & ,primary_harvest_target,secondary_harvest_target & - ,pat_hvmax_btimber,lambda_harvest,harvest_deficit) + ,pat_hvmax_btimber,lambda_harv_og_max,lambda_harvest & + ,harvest_deficit) !------------------------------------------------------------------------------------! @@ -251,7 +256,7 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) ! biomass demands. ! !------------------------------------------------------------------------------------! call young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimber & - ,lambda_harvest,harvest_deficit) + ,lambda_harv_og_max,lambda_harvest,harvest_deficit) !------------------------------------------------------------------------------------! @@ -287,14 +292,18 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) , hvpot_mature_secondary write (unit=*,fmt='(a,1x,es12.5)') ' HVPOT BIOMASS (PLANTATION) = ' & , hvpot_mature_plantation - write (unit=*,fmt='(a,1x,es12.5)') ' HV AREA (PRIMARY) = ' & + write (unit=*,fmt='(a,1x,es12.5)') ' HARVEST AREA (PRIMARY) = ' & , area_mature_primary - write (unit=*,fmt='(a,1x,es12.5)') ' HV AREA (SECONDARY) = ' & + write (unit=*,fmt='(a,1x,es12.5)') ' HARVEST AREA (SECONDARY) = ' & , area_mature_secondary - write (unit=*,fmt='(a,1x,es12.5)') ' HV AREA (PLANTATION) = ' & + write (unit=*,fmt='(a,1x,es12.5)') ' HARVEST AREA (PLANTATION) = ' & , area_mature_plantation write (unit=*,fmt='(a)' ) ' ' - write (unit=*,fmt='(a,1x,es12.5)') ' HARVEST DEFICIT = ', harvest_deficit + write (unit=*,fmt='(a,1x,es12.5)') ' HARVEST DEFICIT = ' & + , harvest_deficit + write (unit=*,fmt='(a)' ) ' ' + write (unit=*,fmt='(a,1x,es12.5)') ' MAXIMUM LAMBDA (OLD-GROWTH) = ' & + , lambda_harv_og_max write (unit=*,fmt='(a)' ) ' ' write (unit=*,fmt='(a)' ) '---------------------------------------------' write (unit=*,fmt='(9(a,1x))' ) ' IPA',' LU',' AGE',' AREA' & @@ -501,7 +510,8 @@ subroutine mature_forest_harvest(cpoly,isi,onsp ,hvmax_mature_secondary,hvpot_mature_secondary & ,hvmax_mature_plantation,hvpot_mature_plantation & ,primary_harvest_target,secondary_harvest_target & - ,pat_hvmax_btimber,lambda_harvest,harvest_deficit) + ,pat_hvmax_btimber,lambda_harv_og_max,lambda_harvest & + ,harvest_deficit) use ed_state_vars , only : polygontype & ! structure , sitetype ! ! structure use disturb_coms , only : plantation_rotation & ! intent(in) @@ -509,7 +519,8 @@ subroutine mature_forest_harvest(cpoly,isi,onsp , min_harvest_biomass & ! intent(in) , min_oldgrowth ! ! intent(in) use consts_coms , only : lnexp_max & ! intent(in) - , almost_one ! ! intent(in) + , almost_one & ! intent(in) + , tiny_num ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! type(polygontype) , target :: cpoly @@ -524,6 +535,7 @@ subroutine mature_forest_harvest(cpoly,isi,onsp real , intent(in) :: primary_harvest_target real , intent(inout) :: secondary_harvest_target real, dimension(onsp), intent(in) :: pat_hvmax_btimber + real , intent(in) :: lambda_harv_og_max real, dimension(onsp), intent(inout) :: lambda_harvest real , intent(out) :: harvest_deficit !----- Local variables --------------------------------------------------------------! @@ -534,74 +546,158 @@ subroutine mature_forest_harvest(cpoly,isi,onsp logical :: is_mature logical :: is_rotation real :: f_harvest + real :: f_harv_prim_max + real :: harvest_actual real :: lambda_mature_primary real :: lambda_mature_plantation real :: lambda_mature_secondary !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Make sure the disturbance rate for primary forests doesn't exceed the maximum ! + ! disturbance taken from the land use instructions for this year. ! !------------------------------------------------------------------------------------! - ! Find harvesting rate in mature primary vegetation. In case there is not enough ! - ! biomass harvest, harvest all primary vegetation then add the unmet biomass to the ! - ! target for secondary vegetation. ! + f_harv_prim_max = 1. - exp (-lambda_harv_og_max) !------------------------------------------------------------------------------------! - if (almost_one * hvmax_mature_primary > primary_harvest_target) then - f_harvest = primary_harvest_target / hvpot_mature_primary - lambda_mature_primary = log(1./(1.-f_harvest)) - elseif (almost_one * hvpot_mature_primary > hvmax_mature_primary) then - f_harvest = hvmax_mature_primary / hvpot_mature_primary - lambda_mature_primary = log(1./(1.-f_harvest)) - harvest_deficit = primary_harvest_target - hvmax_mature_primary - secondary_harvest_target = secondary_harvest_target + harvest_deficit + + + !---- Find harvesting rate in mature primary vegetation. ----------------------------! + if ( hvpot_mature_primary > tiny_num ) then + !---------------------------------------------------------------------------------! + ! Find the total biomass to be harvested from mature primary vegetation. The ! + ! actual harvest cannot exceed the target, cannot exceed the actual biomass, and ! + ! must be bounded by the disturbance rate target. ! + !---------------------------------------------------------------------------------! + harvest_actual = min( f_harv_prim_max * hvpot_mature_primary & + , hvmax_mature_primary, primary_harvest_target ) + f_harvest = harvest_actual / hvpot_mature_primary + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Check fraction to be harvest, to avoid floating point exceptions. ! + !---------------------------------------------------------------------------------! + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------------! + f_harvest = 1.0 + harvest_actual = hvpot_mature_primary + lambda_mature_primary = lnexp_max + harvest_deficit = primary_harvest_target - harvest_actual + secondary_harvest_target = secondary_harvest_target + harvest_deficit + !------------------------------------------------------------------------------! + else + !---- Find the disturbance rate from the fraction of biomass to be harvested. -! + lambda_mature_primary = log(1./(1.-f_harvest)) + harvest_deficit = primary_harvest_target - harvest_actual + secondary_harvest_target = secondary_harvest_target + harvest_deficit + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! else - lambda_mature_primary = lnexp_max - harvest_deficit = primary_harvest_target - hvmax_mature_primary - secondary_harvest_target = secondary_harvest_target + harvest_deficit + !---------------------------------------------------------------------------------! + ! No mature primary forest to harvest. Do not log from any primary forest and ! + ! try to harvest secondary forest instead. ! + !---------------------------------------------------------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + lambda_mature_primary = 0.0 + secondary_harvest_target = secondary_harvest_target + primary_harvest_target + !---------------------------------------------------------------------------------! end if !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! - ! Find harvesting rate for mature plantations and mature secondary forests. ! - ! First try to remove all biomass from plantations. In case there isn't sufficient ! - ! biomass, harvest all plantations then remove the unmet biomass from mature ! - ! secondary vegetation. In case there isn't enough biomass, leave the remaining ! - ! target in harvest_deficit, which will be used to determine harvesting from young ! - ! forests. ! + ! Find harvest disturbance rates for mature forest plantations. We always give ! + ! preference for logging plantations over second-growth forests. ! !------------------------------------------------------------------------------------! - if (almost_one * hvmax_mature_plantation > secondary_harvest_target) then - f_harvest = secondary_harvest_target / hvpot_mature_plantation - lambda_mature_plantation = log(1./(1.-f_harvest)) - harvest_deficit = 0.0 - elseif (almost_one * hvpot_mature_plantation > hvmax_mature_plantation) then - f_harvest = hvmax_mature_plantation / hvpot_mature_plantation - lambda_mature_plantation = log(1./(1.-f_harvest)) - harvest_deficit = secondary_harvest_target - hvmax_mature_plantation + if ( hvpot_mature_plantation > tiny_num ) then + !---------------------------------------------------------------------------------! + ! Find the total biomass to be harvested from mature forest plantation. The ! + ! actual harvest cannot exceed the target or the actual biomass. ! + !---------------------------------------------------------------------------------! + harvest_actual = min( secondary_harvest_target, hvmax_mature_plantation & + , hvpot_mature_plantation ) + f_harvest = harvest_actual / hvpot_mature_plantation + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Check fraction to be harvest, to avoid floating point exceptions. ! + !---------------------------------------------------------------------------------! + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------------! + f_harvest = 1.0 + harvest_actual = hvpot_mature_plantation + lambda_mature_plantation = lnexp_max + harvest_deficit = max(0.,secondary_harvest_target - harvest_actual) + !------------------------------------------------------------------------------! + else + !---- Find the disturbance rate from the fraction of biomass to be harvested. -! + lambda_mature_plantation = log(1./(1.-f_harvest)) + harvest_deficit = max(0.,secondary_harvest_target - harvest_actual) + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! else - lambda_mature_plantation = lnexp_max - harvest_deficit = secondary_harvest_target - hvmax_mature_plantation + !---------------------------------------------------------------------------------! + ! No forest plantation to harvest. Do not log from any plantation and try to ! + ! harvest secondary forest instead. ! + !---------------------------------------------------------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + lambda_mature_plantation = 0.0 + harvest_deficit = secondary_harvest_target + !---------------------------------------------------------------------------------! end if !------------------------------------------------------------------------------------! - - !------------------------------------------------------------------------------------! ! Find disturbance rates for secondary forests other than forest plantation. ! !------------------------------------------------------------------------------------! - if (almost_one * hvmax_mature_secondary > harvest_deficit) then - f_harvest = harvest_deficit / hvpot_mature_secondary - lambda_mature_plantation = log(1./(1.-f_harvest)) - harvest_deficit = 0.0 - elseif (almost_one * hvpot_mature_secondary > hvmax_mature_secondary) then - f_harvest = hvmax_mature_secondary / hvpot_mature_secondary - lambda_mature_secondary = log(1./(1.-f_harvest)) - harvest_deficit = harvest_deficit - hvmax_mature_secondary + if ( hvpot_mature_secondary > tiny_num ) then + !---------------------------------------------------------------------------------! + ! Find the total biomass to be harvested from mature second-growth forest. ! + ! The actual harvest cannot exceed the target or the actual biomass. ! + !---------------------------------------------------------------------------------! + harvest_actual = min( harvest_deficit, hvmax_mature_secondary & + , hvpot_mature_secondary ) + f_harvest = harvest_actual / hvpot_mature_secondary + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Check fraction to be harvest, to avoid floating point exceptions. ! + !---------------------------------------------------------------------------------! + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------------! + f_harvest = 1.0 + harvest_actual = hvpot_mature_secondary + lambda_mature_secondary = lnexp_max + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------------! + else + !---- Find the disturbance rate from the fraction of biomass to be harvested. -! + lambda_mature_secondary = log(1./(1.-f_harvest)) + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! else - lambda_mature_secondary = lnexp_max - harvest_deficit = harvest_deficit - hvmax_mature_secondary + !---------------------------------------------------------------------------------! + ! No mature second-growth forest to harvest. Do not log from any plantation ! + ! and try to harvest secondary forest instead. ! + !---------------------------------------------------------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + lambda_mature_secondary = 0.0 + ! harvest_deficit = harvest_deficit + !---------------------------------------------------------------------------------! end if !------------------------------------------------------------------------------------! @@ -660,6 +756,9 @@ subroutine mature_forest_harvest(cpoly,isi,onsp !------------------------------------------------------------------------------! end select !---------------------------------------------------------------------------------! + + + end do patch_loop !------------------------------------------------------------------------------------! @@ -679,7 +778,7 @@ end subroutine mature_forest_harvest ! the demand for biomass. ! !---------------------------------------------------------------------------------------! subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimber & - ,lambda_harvest,harvest_deficit) + ,lambda_harv_og_max,lambda_harvest,harvest_deficit) use ed_state_vars , only : polygontype & ! structure , sitetype & ! structure , patchtype ! ! structure @@ -688,7 +787,8 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb , min_harvest_biomass & ! intent(in) , min_oldgrowth ! ! intent(in) use consts_coms , only : lnexp_max & ! intent(in) - , almost_one ! ! intent(in) + , almost_one & ! intent(in) + , tiny_num ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -698,6 +798,7 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb real, dimension(onsp) , intent(in) :: pat_hvmax_btimber real, dimension(onsp) , intent(in) :: pat_hvpot_btimber real, dimension(onsp) , intent(inout) :: lambda_harvest + real , intent(in) :: lambda_harv_og_max real , intent(inout) :: harvest_deficit !----- Local variables --------------------------------------------------------------! type(sitetype) , pointer :: csite @@ -709,6 +810,8 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb logical :: is_primary logical :: is_young real :: f_harvest + real :: f_harv_prim_max + real :: harvest_actual real :: site_hvmax_btimber real :: site_hvpot_btimber !------------------------------------------------------------------------------------! @@ -720,10 +823,19 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Make sure the disturbance rate for primary forests doesn't exceed the maximum ! + ! disturbance taken from the land use instructions for this year. ! + !------------------------------------------------------------------------------------! + f_harv_prim_max = 1. - exp (-lambda_harv_og_max) + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! First loop, try to obtain the biomass from young forest plantations. ! !------------------------------------------------------------------------------------! - patch_loop_fopl: do ipa=1,onsp + patch_loop_fypl: do ipa=1,onsp !----- Check whether we can harvest this patch. ----------------------------------! is_harvestable = pat_hvmax_btimber(ipa) >= min_harvest_biomass is_plantation = csite%dist_type(ipa) == 2 @@ -740,39 +852,52 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb !------------------------------------------------------------------------------! - !----- Immature patch is harvestable. Check how much to harvest. -------------! - if (almost_one * site_hvmax_btimber > harvest_deficit) then - !---------------------------------------------------------------------------! - ! Biomass target has been met, harvest the patch, then quit the sub- ! - ! -routine. ! + + !------------------------------------------------------------------------------! + ! Check if there is enough biomass to harvest in this patch. ! + !------------------------------------------------------------------------------! + if ( site_hvpot_btimber > tiny_num ) then !---------------------------------------------------------------------------! - f_harvest = harvest_deficit / site_hvpot_btimber - lambda_harvest(ipa) = log(1./ (1. - f_harvest)) - harvest_deficit = 0.0 - return + ! Check how much biomass can be extracted from this patch, up to the ! + ! target biomass. ! !---------------------------------------------------------------------------! - else if (almost_one * site_hvpot_btimber > site_hvmax_btimber) then + harvest_actual = min(harvest_deficit,site_hvmax_btimber,site_hvpot_btimber) + f_harvest = harvest_actual / site_hvpot_btimber !---------------------------------------------------------------------------! - ! Biomass target has not been met, harvest the entire patch, and keep ! - ! searching for biomass. ! + + !---------------------------------------------------------------------------! - f_harvest = site_hvmax_btimber / site_hvpot_btimber - lambda_harvest(ipa) = log(1./ (1. - f_harvest)) - harvest_deficit = harvest_deficit - site_hvmax_btimber + ! Check fraction to be harvest, to avoid floating point exceptions. ! !---------------------------------------------------------------------------! - else + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------! + f_harvest = 1.0 + harvest_actual = site_hvpot_btimber + lambda_harvest(ipa) = lnexp_max + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + else + !---- Find the disturbance rate. ----------------------------------------! + lambda_harvest(ipa) = log(1./(1.-f_harvest)) + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + end if !---------------------------------------------------------------------------! - ! Biomass target has not been met, harvest the entire patch, and keep ! - ! searching for biomass. ! + + !---- If we successfully met harvest demands, quit routine. ----------------! + if ( harvest_deficit == 0. ) return !---------------------------------------------------------------------------! - lambda_harvest(ipa) = lnexp_max - harvest_deficit = harvest_deficit - site_hvmax_btimber + else + !----- Patch does not have enough biomass. ---------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + ! harvest_deficit = harvest_deficit !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! end if !---------------------------------------------------------------------------------! - end do patch_loop_fopl + end do patch_loop_fypl !------------------------------------------------------------------------------------! @@ -806,33 +931,46 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb !------------------------------------------------------------------------------! - !----- Immature patch is harvestable. Check how much to harvest. -------------! - if (almost_one * site_hvmax_btimber > harvest_deficit) then - !---------------------------------------------------------------------------! - ! Biomass target has been met, harvest the patch, then quit the sub- ! - ! -routine. ! + + !------------------------------------------------------------------------------! + ! Check if there is enough biomass to harvest in this patch. ! + !------------------------------------------------------------------------------! + if ( site_hvpot_btimber > tiny_num ) then !---------------------------------------------------------------------------! - f_harvest = harvest_deficit / site_hvpot_btimber - lambda_harvest(ipa) = log(1./ (1. - f_harvest)) - harvest_deficit = 0.0 - return + ! Check how much biomass can be extracted from this patch, up to the ! + ! target biomass. ! !---------------------------------------------------------------------------! - else if (almost_one * site_hvpot_btimber > site_hvmax_btimber) then + harvest_actual = min(harvest_deficit,site_hvmax_btimber,site_hvpot_btimber) + f_harvest = harvest_actual / site_hvpot_btimber !---------------------------------------------------------------------------! - ! Biomass target has not been met, harvest the entire patch, and keep ! - ! searching for biomass. ! + + !---------------------------------------------------------------------------! - f_harvest = site_hvmax_btimber / site_hvpot_btimber - lambda_harvest(ipa) = log(1./ (1. - f_harvest)) - harvest_deficit = harvest_deficit - site_hvmax_btimber + ! Check fraction to be harvest, to avoid floating point exceptions. ! !---------------------------------------------------------------------------! - else + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------! + f_harvest = 1.0 + harvest_actual = site_hvpot_btimber + lambda_harvest(ipa) = lnexp_max + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + else + !---- Find the disturbance rate. ----------------------------------------! + lambda_harvest(ipa) = log(1./(1.-f_harvest)) + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + end if !---------------------------------------------------------------------------! - ! Biomass target has not been met, harvest the entire patch, and keep ! - ! searching for biomass. ! + + !---- If we successfully met harvest demands, quit routine. ----------------! + if ( harvest_deficit == 0. ) return !---------------------------------------------------------------------------! - lambda_harvest(ipa) = lnexp_max - harvest_deficit = harvest_deficit - site_hvmax_btimber + else + !----- Patch does not have enough biomass. ---------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + ! harvest_deficit = harvest_deficit !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! @@ -872,6 +1010,56 @@ subroutine young_forest_harvest(cpoly,isi,onsp,pat_hvmax_btimber,pat_hvpot_btimb !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Check if there is enough biomass to harvest in this patch. ! + !------------------------------------------------------------------------------! + if ( site_hvpot_btimber > tiny_num ) then + !---------------------------------------------------------------------------! + ! Check how much biomass can be extracted from this patch, up to the ! + ! target biomass. ! + !---------------------------------------------------------------------------! + harvest_actual = min( harvest_deficit, site_hvmax_btimber & + , f_harv_prim_max * site_hvpot_btimber ) + f_harvest = harvest_actual / site_hvpot_btimber + !---------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------! + ! Check fraction to be harvest, to avoid floating point exceptions. ! + !---------------------------------------------------------------------------! + if (f_harvest > almost_one) then + !---- Apply sweeping logging disturbance across primary forests. --------! + f_harvest = 1.0 + harvest_actual = site_hvpot_btimber + lambda_harvest(ipa) = lnexp_max + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + else + !---- Find the disturbance rate. ----------------------------------------! + lambda_harvest(ipa) = log(1./(1.-f_harvest)) + harvest_deficit = max(0.,harvest_deficit - harvest_actual) + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + + !---- If we successfully met harvest demands, quit routine. ----------------! + if ( harvest_deficit == 0. ) return + !---------------------------------------------------------------------------! + else + !----- Patch does not have enough biomass. ---------------------------------! + f_harvest = 0.0 + harvest_actual = 0.0 + ! harvest_deficit = harvest_deficit + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + + !----- Immature patch is harvestable. Check how much to harvest. -------------! if (almost_one * site_hvmax_btimber > harvest_deficit) then !---------------------------------------------------------------------------! diff --git a/ED/src/dynamics/growth_balive.f90 b/ED/src/dynamics/growth_balive.f90 index e9c66af96..b4309bb59 100644 --- a/ED/src/dynamics/growth_balive.f90 +++ b/ED/src/dynamics/growth_balive.f90 @@ -1379,46 +1379,49 @@ subroutine get_c_xfers(csite,ipa,ico,npp_actual,green_leaf_factor,gr_tfact0 ! net growth (i.e. increment from the value of btissue before ! ! maintenance was applied) is the same every day. ! !------------------------------------------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. (.not. (is_grass(ipft) .and. igrass == 1)) ) then - if (delta_bleaf >= tiny_num) then - gtf_bleaf = ( cpatch%leaf_maintenance(ico) & - + gr_tfact0 * (delta_bleaf - cpatch%leaf_maintenance(ico)) ) & - / delta_bleaf - else - gtf_bleaf = gr_tfact0 - end if - if (delta_broot >= tiny_num) then - gtf_broot = ( cpatch%root_maintenance(ico) & - + gr_tfact0 * (delta_broot - cpatch%root_maintenance(ico)) ) & - / delta_broot - else - gtf_broot = gr_tfact0 - end if - if (delta_bbarka >= tiny_num) then - gtf_bbarka = ( cpatch%barka_maintenance(ico) & - + gr_tfact0 & - * (delta_bbarka - cpatch%barka_maintenance(ico)) ) & - / delta_bbarka - else - gtf_bbarka = gr_tfact0 - end if - if (delta_bbarkb >= tiny_num) then - gtf_bbarkb = ( cpatch%barkb_maintenance(ico) & - + gr_tfact0 & - * (delta_bbarkb - cpatch%barkb_maintenance(ico)) ) & - / delta_bbarkb - else - gtf_bbarkb = gr_tfact0 + select case (iallom) + case (3,4,5) + if (.not. (is_grass(ipft) .and. igrass == 1) ) then + if (delta_bleaf >= tiny_num) then + gtf_bleaf = ( cpatch%leaf_maintenance(ico) & + + gr_tfact0 * (delta_bleaf-cpatch%leaf_maintenance(ico))) & + / delta_bleaf + else + gtf_bleaf = gr_tfact0 + end if + if (delta_broot >= tiny_num) then + gtf_broot = ( cpatch%root_maintenance(ico) & + + gr_tfact0 * (delta_broot-cpatch%root_maintenance(ico))) & + / delta_broot + else + gtf_broot = gr_tfact0 + end if + if (delta_bbarka >= tiny_num) then + gtf_bbarka = ( cpatch%barka_maintenance(ico) & + + gr_tfact0 & + * (delta_bbarka - cpatch%barka_maintenance(ico)) ) & + / delta_bbarka + else + gtf_bbarka = gr_tfact0 + end if + if (delta_bbarkb >= tiny_num) then + gtf_bbarkb = ( cpatch%barkb_maintenance(ico) & + + gr_tfact0 & + * (delta_bbarkb - cpatch%barkb_maintenance(ico)) ) & + / delta_bbarkb + else + gtf_bbarkb = gr_tfact0 + end if + !----- Correct deltas based on the time of the month and turnover. ------! + delta_bleaf = delta_bleaf * gtf_bleaf + delta_broot = delta_broot * gtf_broot + delta_bsapwooda = delta_bsapwooda * gr_tfact0 ! sapwood turnover is zero. + delta_bsapwoodb = delta_bsapwoodb * gr_tfact0 ! sapwood turnover is zero. + delta_bbarka = delta_bbarka * gtf_bbarka + delta_bbarkb = delta_bbarkb * gtf_bbarkb end if - !----- Correct deltas based on the time of the month and turnover. ---------! - delta_bleaf = delta_bleaf * gtf_bleaf - delta_broot = delta_broot * gtf_broot - delta_bsapwooda = delta_bsapwooda * gr_tfact0 ! sapwood turnover is zero. - delta_bsapwoodb = delta_bsapwoodb * gr_tfact0 ! sapwood turnover is zero. - delta_bbarka = delta_bbarka * gtf_bbarka - delta_bbarkb = delta_bbarkb * gtf_bbarkb - end if + !---------------------------------------------------------------------------! + end select !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/heun_driver.f90 b/ED/src/dynamics/heun_driver.f90 index c3c9631b6..19f727337 100644 --- a/ED/src/dynamics/heun_driver.f90 +++ b/ED/src/dynamics/heun_driver.f90 @@ -22,6 +22,7 @@ subroutine heun_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use ed_max_dims , only : n_dbh ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function @@ -78,6 +79,7 @@ subroutine heun_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !------------------------------------------------------------------------------------! @@ -85,6 +87,31 @@ subroutine heun_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -98,19 +125,20 @@ subroutine heun_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2 & - ,cmet%geoht,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -218,7 +246,8 @@ subroutine heun_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! diff --git a/ED/src/dynamics/hybrid_driver.f90 b/ED/src/dynamics/hybrid_driver.f90 index 7aaf1d59f..f1cdb6880 100644 --- a/ED/src/dynamics/hybrid_driver.f90 +++ b/ED/src/dynamics/hybrid_driver.f90 @@ -26,6 +26,7 @@ subroutine hybrid_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function use soil_respiration , only : soil_respiration_driver ! ! function @@ -84,6 +85,7 @@ subroutine hybrid_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -----------------------------------------------! logical , parameter :: test_energy_sanity = .false. !----- External functions. --------------------------------------------! @@ -93,6 +95,31 @@ subroutine hybrid_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + wtime0=walltime(0.) siteloop: do isi = 1,cpoly%nsites @@ -107,22 +134,19 @@ subroutine hybrid_timestep(cgrid) ! Update the monthly rainfall. ! !---------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !---------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv & - ,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv & - ,cmet%atm_co2,cmet%geoht,cmet%exner & - ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss & - ,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam & - ,cmet%nir_diffuse,cmet%geoht & - ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & - ,cpoly%green_leaf_factor(:,isi) & - ,cgrid%lon(ipy),cgrid%lat(ipy) & - ,cgrid%cosz(ipy)) + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & + ,cgrid%lat(ipy),cgrid%cosz(ipy)) @@ -230,7 +254,8 @@ subroutine hybrid_timestep(cgrid) ! placed before canopy_photosynthesis because plant_hydro_driver ! ! needs fs_open from previous timestep. ! !------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi),site_isoilbc) !------------------------------------------------------------------! diff --git a/ED/src/dynamics/mortality.f90 b/ED/src/dynamics/mortality.f90 index 3b5eb33df..40240a91d 100644 --- a/ED/src/dynamics/mortality.f90 +++ b/ED/src/dynamics/mortality.f90 @@ -143,7 +143,9 @@ end subroutine mortality_rates ! This subroutine determines the mortality rates associated with the current ! ! disturbance. ! !---------------------------------------------------------------------------------------! - subroutine disturbance_mortality(csite,ipa,area_loss,mindbh_harvest) + subroutine disturbance_mortality(csite,ipa,area_loss,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh,skid_s_gtharv & + ,skid_s_ltharv) use ed_state_vars, only : sitetype & ! structure , patchtype ! ! structure use ed_max_dims , only : n_pft & ! intent(in) @@ -157,6 +159,11 @@ subroutine disturbance_mortality(csite,ipa,area_loss,mindbh_harvest) integer , intent(in) :: ipa real , dimension(n_dist_types), intent(in) :: area_loss real , dimension(n_pft) , intent(in) :: mindbh_harvest + real , dimension(n_pft) , intent(in) :: felling_s_gtharv + real , dimension(n_pft) , intent(in) :: felling_s_ltharv + real , dimension(n_pft) , intent(in) :: skid_dbh_thresh + real , dimension(n_pft) , intent(in) :: skid_s_gtharv + real , dimension(n_pft) , intent(in) :: skid_s_ltharv !----- Local variables. -------------------------------------------------------------! type(patchtype) , pointer :: cpatch integer :: ico @@ -186,6 +193,8 @@ subroutine disturbance_mortality(csite,ipa,area_loss,mindbh_harvest) if (area_loss(new_lu) > tiny_num) then do ico=1,cpatch%ncohorts f_survival = survivorship(new_lu,csite%dist_type(ipa),mindbh_harvest & + ,felling_s_gtharv,felling_s_ltharv & + ,skid_dbh_thresh,skid_s_gtharv,skid_s_ltharv & ,cpatch,ico) a_factor(ico) = a_factor(ico) & + ( 1.0 - f_survival ) * area_loss(new_lu) / csite%area(ipa) @@ -236,7 +245,9 @@ end subroutine disturbance_mortality ! -- cpatch: current patch. ! ! -- ico: index for current cohort. ! !---------------------------------------------------------------------------------------! - real function survivorship(new_lu,old_lu,mindbh_harvest,cpatch,ico) + real function survivorship(new_lu,old_lu,mindbh_harvest,felling_s_gtharv & + ,felling_s_ltharv,skid_dbh_thresh,skid_s_gtharv,skid_s_ltharv & + ,cpatch,ico) use ed_state_vars, only : patchtype ! ! structure use disturb_coms , only : treefall_hite_threshold ! ! intent(in) use pft_coms , only : treefall_s_ltht & ! intent(in) @@ -244,11 +255,7 @@ real function survivorship(new_lu,old_lu,mindbh_harvest,cpatch,ico) , fire_s_min & ! intent(in) , fire_s_max & ! intent(in) , fire_s_inter & ! intent(in) - , fire_s_slope & ! intent(in) - , felling_s_gtharv & ! intent(in) - , felling_s_ltharv & ! intent(in) - , skid_s_ltharv & ! intent(in) - , skid_s_gtharv ! ! intent(in) + , fire_s_slope ! ! intent(in) use ed_max_dims , only : n_pft ! ! intent(in) use consts_coms , only : lnexp_min & ! intent(in) , lnexp_max ! ! intent(in) @@ -256,6 +263,11 @@ real function survivorship(new_lu,old_lu,mindbh_harvest,cpatch,ico) !----- Arguments. -------------------------------------------------------------------! type(patchtype) , target :: cpatch real , dimension(n_pft), intent(in) :: mindbh_harvest + real , dimension(n_pft), intent(in) :: felling_s_gtharv + real , dimension(n_pft), intent(in) :: felling_s_ltharv + real , dimension(n_pft), intent(in) :: skid_dbh_thresh + real , dimension(n_pft), intent(in) :: skid_s_gtharv + real , dimension(n_pft), intent(in) :: skid_s_ltharv integer , intent(in) :: ico integer , intent(in) :: new_lu integer , intent(in) :: old_lu @@ -347,11 +359,13 @@ real function survivorship(new_lu,old_lu,mindbh_harvest,cpatch,ico) !---------------------------------------------------------------------------------! case (7) !---------------------------------------------------------------------------------! - ! Collateral damage from logging (skid trails, roads). The damage currently ! - ! takes into account the minimum harvest size, because presumably loggers avoid ! - ! damaging trees that may be potentially harvested. ! + ! Collateral damage from logging (skid trails, roads). We assign different ! + ! survivorships for small and large trees because loggers avoid large trees when ! + ! building trails and roads: it is easier to build skid trails around large trees ! + ! than felling them just for the trail, and loggers may want to keep the large ! + ! trees alive because they may be their harvest in the next logging cycle. ! !---------------------------------------------------------------------------------! - if (cpatch%dbh(ico) >= mindbh_harvest(ipft)) then + if (cpatch%dbh(ico) >= skid_dbh_thresh(ipft)) then survivorship = skid_s_gtharv(ipft) else survivorship = skid_s_ltharv(ipft) diff --git a/ED/src/dynamics/phenology_aux.f90 b/ED/src/dynamics/phenology_aux.f90 index a8abed4f4..f91e30ae5 100644 --- a/ED/src/dynamics/phenology_aux.f90 +++ b/ED/src/dynamics/phenology_aux.f90 @@ -288,7 +288,7 @@ subroutine update_turnover(cpoly, isi) !------------------------------------------------------------------------------------! sitepft_loop: do ipft=1,n_pft select case (phenology(ipft)) - case (3) + case (3,6) !------ The actual turnover amplitude is based on a running average. ----------! cpoly%turnover_amp(isi) = (1.0 - turnamp_wgt) * cpoly%turnover_amp(isi) & + turnamp_wgt * turnamp_now @@ -414,7 +414,7 @@ subroutine update_turnover(cpoly, isi) ! -modulated. ! !------------------------------------------------------------------------------! select case (phenology(ipft)) - case (3) + case (3,6) !----- Update the data set. ------------------------------------------------! cpatch%llspan(ico) = cpatch%llspan (ico) & * cpoly%llspan_toc(ipft,isi) / llspan_toc_in(ipft) diff --git a/ED/src/dynamics/phenology_driv.f90 b/ED/src/dynamics/phenology_driv.f90 index c4c6322c2..a5bfbf3f1 100644 --- a/ED/src/dynamics/phenology_driv.f90 +++ b/ED/src/dynamics/phenology_driv.f90 @@ -46,31 +46,51 @@ subroutine phenology_driver(cgrid, doy, month, tfact,veget_dyn_on) do ipa = 1,csite%npatches csite%avg_daily_temp(ipa) = csite%avg_daily_temp(ipa) * tfact end do - + select case (iphen_scheme) - case (-1,0,2) + case (1) !---------------------------------------------------------------------------! - ! Default predictive scheme (Botta et al.) or the modified drought ! - ! deciduous phenology for broadleaf PFTs. ! + ! Use prescribed phenology (M09). ! + ! ! + ! Medvigy DM, Wofsy SC, Munger JW, Hollinger DY , Moorcroft PR. 2009. ! + ! Mechanistic scaling of ecosystem function and dynamics in space and ! + ! time: Ecosystem demography model version 2. J. Geophys. ! + ! Res.-Biogeosci., 114: G01002. doi:10.1029/2008JG000812 (M09). ! !---------------------------------------------------------------------------! - call update_thermal_sums(month, cpoly, isi, cgrid%lat(ipy)) - call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) - - case (1) - !----- Use prescribed phenology. -------------------------------------------! call prescribed_leaf_state(cgrid%lat(ipy), current_time%month & ,current_time%year, doy & ,cpoly%green_leaf_factor(:,isi) & ,cpoly%leaf_aging_factor(:,isi) & ,cpoly%phen_pars(isi) ) call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) + !---------------------------------------------------------------------------! - - case (3,4) - !----- Light-controlled predictive phenology scheme. -----------------------! + case default + !---------------------------------------------------------------------------! + ! Default predictive scheme (B00), the modified drought deciduous ! + ! phenology for broadleaf PFTs (L19), or the light-controlled predictive ! + ! phenology scheme (K12). ! + ! ! + ! Botta A, Viovy N, Ciais P, Friedlingstein P , Monfray P. 2000. A global ! + ! prognostic scheme of leaf onset using satellite data. Glob. Change ! + ! Biol., 6: 709-725. doi:10.1046/j.1365-2486.2000.00362.x (2000). ! + ! ! + ! Kim Y, Knox RG, Longo M, Medvigy D, Hutyra LR, Pyle EH, Wofsy SC, ! + ! Bras RL, Moorcroft PR. 2012. Seasonal carbon dynamics and water fluxes ! + ! in an Amazon rainforest. Glob. Change Biol., 18: 1322-1334. ! + ! doi:10.1111/j.1365-2486.2011.02629.x (K12). ! + ! ! + ! Longo M, Knox RG, Medvigy DM, Levine NM, Dietze MC, Kim Y, Swann ALS, ! + ! Zhang K, Rollinson CR, Bras RL et al. 2019. The biophysics, ecology, ! + ! and biogeochemistry of functionally diverse, vertically and ! + ! horizontally heterogeneous ecosystems: the Ecosystem Demography model, ! + ! version 2.2 -- part 1: Model description. Geosci. Model Dev., 12: ! + ! 4309-4346. doi:10.5194/gmd-12-4309-2019 (L19). + !---------------------------------------------------------------------------! call update_thermal_sums(month, cpoly, isi, cgrid%lat(ipy)) call update_turnover(cpoly,isi) call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) + !---------------------------------------------------------------------------! end select end do end do @@ -95,6 +115,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) use pft_coms , only : phenology & ! intent(in) , c2n_leaf & ! intent(in) , q & ! intent(in) + , leaf_psi_min & ! intent(in) , leaf_psi_tlp & ! intent(in) , high_psi_threshold & ! intent(in) , low_psi_threshold & ! intent(in) @@ -108,7 +129,8 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) , root_phen_factor & ! intent(in) , iphen_scheme & ! intent(in) , elongf_min & ! intent(in) - , elongf_flush ! ! intent(in) + , elongf_flush & ! intent(in) + , f_psi_xdry ! ! intent(in) use consts_coms , only : t3ple & ! intent(in) , cice & ! intent(in) , cliq & ! intent(in) @@ -271,7 +293,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !------------------------------------------------------------------------------! ! Here we decide what to do depending on the phenology habit. There are ! - ! five different types: ! + ! different types: ! ! 0. Evergreen - neither cold nor drought makes these plants to drop ! ! their leaves; ! ! 1. Drought deciduous - these plants will drop all leaves when drought ! @@ -285,6 +307,13 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) ! 4. Drought deciduous - similar to one, but the threshold is compared against ! ! a 10-day running average rather than the instant- ! ! aneous value. ! + ! 5. Hydro-deciduous - similar to four, but the thresholds are based on ! + ! leaf water potential instead (and thus it requires ! + ! plant hydrodynamics). ! + ! 6. Light phenology ! + ! + Hydro-deciduous - similar to three, but the thresholds are based on ! + ! leaf water potential instead (and thus it requires ! + ! plant hydrodynamics). ! !------------------------------------------------------------------------------! select case (phenology(ipft)) case (0) @@ -628,7 +657,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !------------------------------------------------------------------------! end if !---------------------------------------------------------------------------! - case (5) + case (5,6) !---------------------------------------------------------------------------! ! Drought deciduous driven by plant hydrodynamics. We track the number ! ! of consecutive wet days and dry days. We then modify the phenology ! @@ -664,7 +693,15 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !----- Modify elongf and phenology_status whenever necessary. --------------! - if (cpatch%low_leaf_psi_days(ico) >= low_psi_threshold(ipft)) then + if ( cpatch%leaf_psi(ico) < ( f_psi_xdry * leaf_psi_min(ipft) ) & + .and. cpatch%wood_psi(ico) < leaf_psi_tlp(ipft) ) then + !------------------------------------------------------------------------! + ! Extremely dry conditions: leaf_psi is too low and even wood_psi is ! + ! below leaf_tlp. Shed all leaves. ! + !------------------------------------------------------------------------! + elongf_try = 0.0 + !------------------------------------------------------------------------! + else if (cpatch%low_leaf_psi_days(ico) >= low_psi_threshold(ipft)) then !----- Too many dry days, decrease elongation factor. -------------------! elongf_try = max(0., cpatch%elongf(ico) - leaf_shed_rate(ipft)) !------------------------------------------------------------------------! @@ -921,15 +958,19 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !---------------------------------------------------------------------------! - ! Adjust root biomass in case phenology is 5 (drought-deciduous driven ! - ! by hydrodynamics). ! + ! Adjust root biomass in case phenology is 5 or 6 (drought-deciduous ! + ! driven by hydrodynamics). ! !---------------------------------------------------------------------------! - if (phenology(ipft) == 5 .and. root_phen_factor > 0.) then - cpatch%broot(ico) = q(ipft) * (elongf_try + root_phen_factor - 1.) & - * size2bl(cpatch%dbh(ico),cpatch%hite(ico) & - ,cpatch%sla(ico),ipft) & - / root_phen_factor - end if + select case (phenology(ipft)) + case (5,6) + if (root_phen_factor > 0.) then + cpatch%broot(ico) = q(ipft) * (elongf_try + root_phen_factor - 1.) & + * size2bl(cpatch%dbh(ico),cpatch%hite(ico) & + ,cpatch%sla(ico),ipft) & + / root_phen_factor + end if + !------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/plant_hydro.f90 b/ED/src/dynamics/plant_hydro.f90 index 76d6e7e04..587043c02 100644 --- a/ED/src/dynamics/plant_hydro.f90 +++ b/ED/src/dynamics/plant_hydro.f90 @@ -42,13 +42,20 @@ module plant_hydro !> !> \author Xiangtao Xu, 30 Jan. 2018 !---------------------------------------------------------------------------------------! - subroutine plant_hydro_driver(csite,ipa,ntext_soil) + subroutine plant_hydro_driver(csite,ipa,lsl,ntext_soil,site_isoilbc) use ed_state_vars , only : sitetype & ! structure , patchtype ! ! structure use ed_misc_coms , only : dtlsm & ! intent(in) , dtlsm_o_frqsum & ! intent(in) , current_time ! ! intent(in) use soil_coms , only : soil & ! intent(in) + , slzt & ! intent(in) + , dslz & ! intent(in) + , dslzt & ! intent(in) + , dslzti & ! intent(in) + , dslzi & ! intent(in) + , sin_sldrain & ! intent(in) + , slcons1 & ! intent(in) , matric_potential & ! function , hydr_conduct ! ! function use grid_coms , only : nzg ! ! intent(in) @@ -59,23 +66,30 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) use pft_coms , only : C2B & ! intent(in) , leaf_water_cap & ! intent(in) , leaf_psi_min & ! intent(in) + , wood_psi_min & ! intent(in) , small_psi_min ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! type(sitetype) , target :: csite integer , intent(in) :: ipa + integer , intent(in) :: lsl integer,dimension(nzg), intent(in) :: ntext_soil + integer , intent(in) :: site_isoilbc !----- Local Vars ------------------------------------------------------------------! type(patchtype) , pointer :: cpatch !< patch strcture real :: swater_min !< Min. soil moisture for condct. - real :: swater_max !< Max. soil moisture for condct. + real :: swater_try !< Projected soil water. real :: swater_use !< soil moisture + real :: avg_cond0 !< Interpolated conductance integer :: nsoil !< soil type for soil integer :: k !< iterator for soil lyr integer :: ico !< iterator for cohort integer :: ipft !< PFT index real ,dimension(nzg) :: soil_psi !< soil water potential [ m] + real ,dimension(0:nzg+1) :: soil_psipz0 !< soil water potential [ m] + real ,dimension(0:nzg+1) :: soil_cond0 !< soil water conductance [kg/m2/s] + real ,dimension(0:nzg+1) :: wflux0 !< potential water flux [kg/m2/s] real ,dimension(nzg) :: soil_cond !< soil water conductance [kg/m2/s] real :: sap_frac !< sapwood fraction [ ---] real :: sap_area !< sapwood area [ m2] @@ -85,7 +99,7 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) logical :: track_hydraulics !< whether track hydraulics !----- Variables for debugging purposes ---------------------------------------------! integer, parameter :: dco = 0 ! the cohort to debug - logical, dimension(3) :: error_flag + logical, dimension(6) :: error_flag logical, parameter :: debug_flag = .false. character(len=13) , parameter :: efmt = '(a,1x,es12.5)' character(len=9) , parameter :: ifmt = '(a,1x,i5)' @@ -128,43 +142,107 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) !---------------------------------------------------------------------------------! ! Calculate water potential and conductance in each soil layer in preparation - ! for later calculations. + ! for later calculations. Soil conductance is only allowed for layers above the + ! lowest resolvable soil depth. We calculate the conductance twice: the first + ! time we compute the target conductance, and in the second time we impose bounds + ! to avoid soil water to be over-extracted by plants. !---------------------------------------------------------------------------------! - do k = 1,nzg + soil_cond0 (:) = 0.0 + soil_psipz0(:) = 0.0 + wflux0 (:) = 0.0 + !----- First guess. --------------------------------------------------------------! + guess_1st_loop: do k = lsl,nzg nsoil = ntext_soil(k) - + soil_cond0 (k) = wdns * hydr_conduct(k,nsoil,csite%soil_water (k,ipa) & + ,csite%soil_fracliq(k,ipa) ) + soil_psipz0(k) = csite%soil_mstpot(k,ipa) + slzt(k) + end do guess_1st_loop + !----- Bottom boundary condition. ------------------------------------------------! + select case (site_isoilbc) + case (0) + !----- Bedrock. ---------------------------------------------------------------! + soil_psipz0(lsl-1) = soil_psipz0(lsl) + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - ! Get bounded soil moisture. ! - ! MLO. The lower bound used to be air-dry soil moisture. This causes issues ! - ! in the RK4 integrator if the soil moisture is just slightly above air-dry ! - ! and dtlsm is long. For the time being, I am assuming that soil ! - ! conductivity is halted just below the permanent wilting point. Similarly, ! - ! I am assuming that matric potential cannot exceed a value slightly less ! - ! than the bubbling point. ! + case (1) + !----- Free drainage. ---------------------------------------------------------! + soil_psipz0(lsl-1) = csite%soil_mstpot(lsl,ipa) + slzt(lsl-1) + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - swater_min = mg_safe * soil(nsoil)%soilcp + om_safe * soil(nsoil)%soilwp - swater_max = mg_safe * soil(nsoil)%sfldcap + om_safe * soil(nsoil)%slmsts - swater_use = max( swater_min & - , min(swater_max & - ,csite%soil_water(k,ipa) * csite%soil_fracliq(k,ipa) ) ) + case (2) + !----- Partial drainage. ------------------------------------------------------! + soil_psipz0(lsl-1) = csite%soil_mstpot(lsl,ipa) & + + slzt(lsl) - dslzt(lsl) * sin_sldrain + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - - - !----- Clapp & Hornberger curves. ---------------------------------------------! - soil_psi(k) = matric_potential(nsoil,swater_use) + case (3) + !----- Aquifer. ---------------------------------------------------------------! + nsoil = ntext_soil(lsl) + soil_psipz0(lsl-1) = soil(nsoil)%slpots + soil_cond0 (lsl-1) = slcons1(lsl-1,nsoil) !------------------------------------------------------------------------------! + end select + !----- Top boundary condition. ---------------------------------------------------! + soil_psipz0(nzg+1) = soil_psipz0(nzg) + !----- First guess for water flux. -----------------------------------------------! + do k = lsl,nzg + nsoil = ntext_soil(k) + select case (soil(nsoil)%method) + case ('BDRK') + !----- Bedrock, soil conductance should be zero. ---------------------------! + wflux0(k) = 0. + !---------------------------------------------------------------------------! + case default + !----- Log-linear interpolation of conductivity to layer interface. --------! + avg_cond0 = soil_cond0(k-1) * ( soil_cond0(k) / soil_cond0(k-1) ) & + ** ( dslz(k-1) / (dslz(k-1) + dslz(k)) ) + !---------------------------------------------------------------------------! + !------ Estimate flux at interface. ----------------------------------------! + wflux0(k) = - avg_cond0 * ( soil_psipz0(k) - soil_psipz0(k-1) ) * dslzti(k) + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + end do + !----- Find bounded fluxes. ------------------------------------------------------! + soil_cond(:) = 0. + do k = lsl,nzg + !------------------------------------------------------------------------------! + ! Quick estimate of soil water for the next step. ! + !------------------------------------------------------------------------------! + nsoil = ntext_soil(k) + swater_use = csite%soil_water(k,ipa) * csite%soil_fracliq(k,ipa) + swater_min = mg_safe * soil(nsoil)%soilcp + om_safe * soil(nsoil)%soilwp + swater_try = csite%soil_water(k,ipa) & + + dtlsm * dslzi(k) * ( wflux0(k) - wflux0(k+1)) + !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! - ! In the model, soil can't get drier than residual soil moisture. Ensure ! - ! that hydraulic conductivity is effectively zero in case soil moisture ! - ! reaches this level or drier. ! + ! Check whether or not the conductance could drive soil water too low. ! !------------------------------------------------------------------------------! - if (csite%soil_water(k,ipa) < swater_min) then + if ( swater_use < swater_min) then + !------ Soil is already very dry (or frozen). Halt water transport. -------! + swater_use = swater_min soil_cond(k) = 0. + soil_psi (k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! + else if ( (swater_try < swater_use) .and. (swater_try < swater_min)) then + !---------------------------------------------------------------------------! + ! Conductance could desiccate soil layer, down-regulate soil ! + ! conductance and adjust soil matric potential accordingly. We also change ! + ! the units for conductance to kg/m2/s. ! + !---------------------------------------------------------------------------! + soil_cond(k) = wdns * soil_cond0(k) * ( swater_use - swater_min) & + / ( swater_use - swater_try) + soil_psi(k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! else - soil_cond(k) = wdns * hydr_conduct(k,nsoil,csite%soil_water(k,ipa) & - ,csite%soil_fracliq(k,ipa)) + !---------------------------------------------------------------------------! + ! Use the actual conductance (just convert it to kg/m2/s). ! + !---------------------------------------------------------------------------! + soil_cond(k) = wdns * soil_cond0(k) + soil_psi (k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! end do @@ -226,14 +304,54 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) + transp * dtlsm & ! kgH2O / c_leaf ! ! kgH2O/m !------------------------------------------------------------------------! + + + !------------------------------------------------------------------------! + ! Run sanity check. The code will crash if any of these happens. ! + ! ! + ! 1. If leaf_psi is invalid (run the debugger, the problem may be else- ! + ! where) ! + ! 2. If leaf_psi is positive (non-sensical) ! + ! 3. If leaf_psi is too negative (also non-sensical) ! + !------------------------------------------------------------------------! + error_flag(1) = isnan_real(cpatch%leaf_psi(ico)) ! NaN values + error_flag(2) = cpatch%leaf_psi(ico) > 0. ! Positive potential + error_flag(3) = merge( cpatch%leaf_psi(ico) < small_psi_min(ipft) & + , cpatch%leaf_psi(ico) < leaf_psi_min (ipft) & + , cpatch%is_small(ico) ) + !------------------------------------------------------------------------! else !----- No leaves, set leaf_psi the same as wood_psi - hite. -------------! cpatch%leaf_psi(ico) = cpatch%wood_psi(ico) - cpatch%hite(ico) !------------------------------------------------------------------------! + + + !----- Skip checking leaf psi. ------------------------------------------! + error_flag(1) = .false. + error_flag(2) = .false. + error_flag(3) = .false. + !------------------------------------------------------------------------! end if !---------------------------------------------------------------------------! + !---------------------------------------------------------------------------! + ! Run sanity check for wood. The code will crash if any of these ! + ! happens. ! + ! ! + ! 1. If wood_psi is invalid (run the debugger, the problem may be else- ! + ! where) ! + ! 2. If wood_psi is positive (non-sensical) ! + ! 3. If wood_psi is too negative (also non-sensical) ! + !---------------------------------------------------------------------------! + error_flag(4) = isnan_real(cpatch%wood_psi(ico)) ! NaN values + error_flag(5) = cpatch%wood_psi(ico) > 0. ! Positive potential + error_flag(6) = merge( cpatch%wood_psi(ico) < small_psi_min(ipft) & + , cpatch%wood_psi(ico) < wood_psi_min (ipft) & + , cpatch%is_small(ico) ) + !---------------------------------------------------------------------------! + + !---------------------------------------------------------------------------! ! Run sanity check. The code will crash if any of these happen. ! ! ! @@ -242,17 +360,12 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) ! 2. If leaf_psi is positive (non-sensical) ! ! 3. If leaf_psi is too negative (also non-sensical) ! !---------------------------------------------------------------------------! - error_flag(1) = isnan_real(cpatch%leaf_psi(ico)) ! NaN values - error_flag(2) = cpatch%leaf_psi(ico) > 0. ! Positive potential - error_flag(3) = merge( cpatch%leaf_psi(ico) < small_psi_min(ipft) & - , cpatch%leaf_psi(ico) < leaf_psi_min (ipft) & - , cpatch%is_small(ico) ) if ((debug_flag .and. (dco == 0 .or. ico == dco)) .or. any(error_flag)) then write (unit=*,fmt='(a)') ' ' write (unit=*,fmt='(92a)') ('=',k=1,92) write (unit=*,fmt='(92a)') ('=',k=1,92) write (unit=*,fmt='(a)' ) & - ' Invalid leaf_psi detected.' + ' Invalid leaf_psi or wood_psi detected.' write (unit=*,fmt='(92a)') ('-',k=1,92) write (unit=*,fmt='(a,i4.4,2(1x,i2.2),1x,f6.0)') ' TIME : ' & ,current_time%year,current_time%month & @@ -266,12 +379,17 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) write (unit=*,fmt=lfmt ) ' + SMALL =',cpatch%is_small(ico) write (unit=*,fmt='(a)' ) ' ' - write (unit=*,fmt=lfmt ) ' + FINITE =',.not. error_flag(1) - write (unit=*,fmt=lfmt ) ' + NEGATIVE =',.not. error_flag(2) - write (unit=*,fmt=lfmt ) ' + BOUNDED =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + FINITE (Leaf) =',.not. error_flag(1) + write (unit=*,fmt=lfmt ) ' + NEGATIVE (Leaf) =',.not. error_flag(2) + write (unit=*,fmt=lfmt ) ' + BOUNDED (Leaf) =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + FINITE (Wood) =',.not. error_flag(4) + write (unit=*,fmt=lfmt ) ' + NEGATIVE (Wood) =',.not. error_flag(5) + write (unit=*,fmt=lfmt ) ' + BOUNDED (Wood) =',.not. error_flag(6) write (unit=*,fmt='(a)' ) ' ' write (unit=*,fmt=efmt ) ' + LEAF_PSI_MIN =',leaf_psi_min (ipft) + write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) + write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) write (unit=*,fmt=efmt ) ' + SMALL_PSI_MIN =',small_psi_min(ipft) write (unit=*,fmt='(a)' ) ' ' @@ -340,15 +458,15 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) ! and psi_closed. ! !---------------------------------------------------------------------------! call calc_plant_water_flux( & - dtlsm &!input - ,sap_area,cpatch%nplant(ico),ipft &!input - ,cpatch%is_small(ico),cpatch%krdepth(ico) &!input - ,cpatch%bleaf(ico),bsap,cpatch%broot(ico) &!input - ,cpatch%hite(ico),transp &!input - ,cpatch%leaf_psi(ico),cpatch%wood_psi(ico) &!input - ,soil_psi,soil_cond,ipa,ico &!input - ,cpatch%wflux_wl(ico),cpatch%wflux_gw(ico) &!output - ,cpatch%wflux_gw_layer(:,ico)) !!output + dtlsm & ! input + ,sap_area,cpatch%nplant(ico),ipft & ! input + ,cpatch%is_small(ico),cpatch%krdepth(ico) & ! input + ,cpatch%bleaf(ico),bsap,cpatch%broot(ico) & ! input + ,cpatch%hite(ico),cpatch%root_frac(:,ico) & ! input + ,transp,cpatch%leaf_psi(ico),cpatch%wood_psi(ico) & ! input + ,soil_psi,soil_cond,lsl,ipa,ico & ! input + ,cpatch%wflux_wl(ico),cpatch%wflux_gw(ico) & ! output + ,cpatch%wflux_gw_layer(:,ico)) ! ! output !---------------------------------------------------------------------------! else !----- Neither leaves nor wood are resolvable. Assume zero flow. ----------! @@ -450,13 +568,12 @@ end subroutine plant_hydro_driver !---------------------------------------------------------------------------------------! subroutine calc_plant_water_flux(dt & !timestep ,sap_area,nplant,ipft,is_small,krdepth & !plant input - ,bleaf,bsap,broot,hite & !plant input + ,bleaf,bsap,broot,hite ,root_frac & !plant input ,transp,leaf_psi,wood_psi & !plant input - ,soil_psi,soil_cond & !soil input + ,soil_psi,soil_cond,lsl & !soil input ,ipa,ico & !debug input ,wflux_wl,wflux_gw,wflux_gw_layer) ! !flux output - use soil_coms , only : slz8 & ! intent(in) - , dslz8 ! ! intent(in) + use soil_coms , only : dslz8 ! ! intent(in) use grid_coms , only : nzg ! ! intent(in) use consts_coms , only : pi18 & ! intent(in) , lnexp_min8 ! ! intent(in) @@ -470,7 +587,6 @@ subroutine calc_plant_water_flux(dt & !timestep , wood_Kmax & ! intent(in) , wood_Kexp & ! intent(in) , vessel_curl_factor & ! intent(in) - , root_beta & ! intent(in) , SRA & ! intent(in) , C2B ! ! intent(in) use ed_misc_coms , only : current_time ! ! intent(in) @@ -486,11 +602,13 @@ subroutine calc_plant_water_flux(dt & !timestep real , intent(in) :: bsap !sapwood biomass [ kgC/pl] real , intent(in) :: broot !fine root biomass [ kgC/pl] real , intent(in) :: hite !plant height [ m] + real , dimension(nzg), intent(in) :: root_frac !Root fraction [ m] real , intent(in) :: transp !transpiration [ kg/s] real , intent(in) :: leaf_psi !leaf water pot. [ m] real , intent(in) :: wood_psi !wood water pot. [ m] real , dimension(nzg), intent(in) :: soil_psi !soil water pot. [ m] real , dimension(nzg), intent(in) :: soil_cond !soil water cond. [kg/m2/s] + integer, intent(in) :: lsl !lowest active lyr [ ---] integer, intent(in) :: ipa !Patch index [ ---] integer, intent(in) :: ico !Cohort index [ ---] real , intent(out) :: wflux_wl !wood-leaf flux [ kg/s] @@ -517,12 +635,12 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: wood_psi_min_d real(kind=8) :: leaf_psi_lwr_d real(kind=8) :: wood_psi_lwr_d - real(kind=8) :: root_beta_d real(kind=8) :: SRA_d real(kind=8) :: wood_psi50_d real(kind=8) :: wood_Kexp_d real(kind=8) :: wood_Kmax_d real(kind=8) :: vessel_curl_factor_d + real(kind=8) :: root_frac_d !fraction of roots !----- Auxiliary variables. ---------------------------------------------------------! real(kind=8) :: exp_term !exponent term real(kind=8) :: ap ![s-1] @@ -532,7 +650,6 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: c_leaf !leaf water capacitance real(kind=8) :: c_stem !stem water capacitance real(kind=8) :: RAI !root area index - real(kind=8) :: root_frac !fraction of roots real(kind=8) :: proj_leaf_psi !projected leaf water pot. real(kind=8) :: proj_wood_psi !projected wood water pot. real(kind=8) :: gw_cond !g->w water conductivity @@ -540,8 +657,6 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: org_leaf_psi !used for small tree real(kind=8) :: weighted_soil_psi real(kind=8) :: weighted_gw_cond - real(kind=8) :: above_layer_depth - real(kind=8) :: current_layer_depth real(kind=8) :: total_water_supply real(kind=8) , dimension(nzg) :: layer_water_supply !----- Counters. --------------------------------------------------------------------! @@ -558,6 +673,7 @@ subroutine calc_plant_water_flux(dt & !timestep logical , parameter :: debug_flag = .false. !----- External function ------------------------------------------------------------! real(kind=4) , external :: sngloff ! Safe dble 2 single precision + logical , external :: isnan_dble ! Check for NaN !------------------------------------------------------------------------------------! @@ -570,14 +686,13 @@ subroutine calc_plant_water_flux(dt & !timestep bleaf_d = dble(bleaf ) bsap_d = dble(bsap ) broot_d = dble(broot ) - nplant_d = dble(nplant ) + nplant_d = dble(nplant ) hite_d = dble(hite ) transp_d = dble(transp ) leaf_psi_d = dble(leaf_psi ) wood_psi_d = dble(wood_psi ) soil_psi_d = dble(soil_psi ) soil_cond_d = dble(soil_cond ) - root_beta_d = dble(root_beta (ipft)) SRA_d = dble(SRA (ipft)) !----- Minimum threshold depends on whether the plant is small or large. ------------! if (is_small) then @@ -718,7 +833,7 @@ subroutine calc_plant_water_flux(dt & !timestep wflux_wl_d = 0.d0 !------ Proj_leaf_psi is only dependent upon transpiration. -------------------! - if (c_leaf > 0.) then + if (c_leaf > 0.d0) then proj_leaf_psi = leaf_psi_d - transp_d * dt_d / c_leaf else proj_leaf_psi = leaf_psi_d @@ -753,7 +868,7 @@ subroutine calc_plant_water_flux(dt & !timestep !------------------------------------------------------------------------------! ! Find sapflow. !------------------------------------------------------------------------------! - if (stem_cond == 0.) then + if (stem_cond == 0.d0) then !---- 1.2.2. Zero flux because stem conductivity is also zero. -------------! wflux_wl_d = 0.d0 !---------------------------------------------------------------------------! @@ -795,26 +910,16 @@ subroutine calc_plant_water_flux(dt & !timestep !----- Loop over all soil layers to get the aggregated water conductance. -----------! do k = krdepth,nzg - !---------------------------------------------------------------------------------! - ! Define layer edges - ! - !---------------------------------------------------------------------------------! - current_layer_depth = -slz8(k) - above_layer_depth = -slz8(k+1) - !---------------------------------------------------------------------------------! - - - !----- Calculate the root fraction of this layer. --------------------------------! - root_frac = ( root_beta_d ** (above_layer_depth / (-slz8(krdepth))) & - - root_beta_d ** (current_layer_depth / (-slz8(krdepth))) ) + !----- Retrieve the root fraction of this layer. ---------------------------------! + root_frac_d = dble(root_frac(k)) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! ! Calculate RAI in each layer. ! !---------------------------------------------------------------------------------! - RAI = broot_d * SRA_d * root_frac * nplant_d ! m2/m2 + RAI = broot_d * SRA_d * root_frac_d * nplant_d ! m2/m2 !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! @@ -863,7 +968,7 @@ subroutine calc_plant_water_flux(dt & !timestep ! No need to calculate water flow: wood psi is only dependent upon sapflow. !---------------------------------------------------------------------------------! wflux_gw_d = 0.d0 - if (c_stem > 0.) then + if (c_stem > 0.d0) then !----- Make sure that projected wood psi will be bounded. ---------------------! wflux_wl_d = min(wflux_wl_d, (wood_psi_d - wood_psi_lwr_d) * c_stem / dt_d ) proj_wood_psi = wood_psi_d - wflux_wl_d * dt_d / c_stem @@ -937,11 +1042,26 @@ subroutine calc_plant_water_flux(dt & !timestep ! d. Projected leaf/wood potential is less than minimum acceptable ! e. Current leaf/wood potential is less than minimum acceptable !------------------------------------------------------------------------------------! - error_flag(1) = isnan(wflux_wl_d) .or. isnan(wflux_gw_d) - error_flag(2) = proj_leaf_psi > 0. .or. proj_wood_psi > 0. - error_flag(3) = leaf_psi_d > 0. .or. wood_psi_d > 0. - error_flag(4) = proj_leaf_psi < leaf_psi_min_d .or. proj_wood_psi < wood_psi_min_d - error_flag(5) = leaf_psi_d < leaf_psi_min_d .or. wood_psi_d < wood_psi_min_d + if (c_leaf > 0.d0) then + !------ Check for errors in both wood and leaf. ----------------------------------! + error_flag(1) = isnan_dble(wflux_wl_d) .or. isnan_dble(wflux_gw_d) + error_flag(2) = proj_leaf_psi > 0.d0 .or. proj_wood_psi > 0.d0 + error_flag(3) = leaf_psi_d > 0.d0 .or. wood_psi_d > 0.d0 + error_flag(4) = proj_leaf_psi < leaf_psi_min_d .or. proj_wood_psi < wood_psi_min_d + error_flag(5) = leaf_psi_d < leaf_psi_min_d .or. wood_psi_d < wood_psi_min_d + !---------------------------------------------------------------------------------! + else + !---------------------------------------------------------------------------------! + ! Check for errors in wood only, as plant has no leaves. The only exception ! + ! is the flux from wood to leaf, which should never be NaN, so we still check it. ! + !---------------------------------------------------------------------------------! + error_flag(1) = isnan_dble(wflux_wl_d) .or. isnan_dble(wflux_gw_d) + error_flag(2) = proj_wood_psi > 0.d0 + error_flag(3) = wood_psi_d > 0.d0 + error_flag(4) = proj_wood_psi < wood_psi_min_d + error_flag(5) = wood_psi_d < wood_psi_min_d + !---------------------------------------------------------------------------------! + end if if ( (debug_flag .and. (dco == 0 .or. ico == dco)) .or. any(error_flag)) then write (unit=*,fmt='(a)') ' ' @@ -971,15 +1091,15 @@ subroutine calc_plant_water_flux(dt & !timestep write (unit=*,fmt=efmt ) ' + SAPWOOD_AREA =',sap_area write (unit=*,fmt='(a)' ) ' ' - write (unit=*,fmt=lfmt ) ' + Finite fluxes =',.not. error_flag(1) - write (unit=*,fmt=lfmt ) ' + Negative Proj Psi =',.not. error_flag(2) - write (unit=*,fmt=lfmt ) ' + Negative Curr Psi =',.not. error_flag(3) - write (unit=*,fmt=lfmt ) ' + Bounded Proj Psi =',.not. error_flag(4) - write (unit=*,fmt=lfmt ) ' + Bounded Curr Psi =',.not. error_flag(5) + write (unit=*,fmt=lfmt ) ' + Leaves were checked =',c_leaf > 0.d0 + write (unit=*,fmt=lfmt ) ' + Finite fluxes =',.not. error_flag(1) + write (unit=*,fmt=lfmt ) ' + Negative Proj Psi =',.not. error_flag(2) + write (unit=*,fmt=lfmt ) ' + Negative Curr Psi =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + Bounded Proj Psi =',.not. error_flag(4) + write (unit=*,fmt=lfmt ) ' + Bounded Curr Psi =',.not. error_flag(5) write (unit=*,fmt='(a)' ) ' ' write (unit=*,fmt=efmt ) ' + LEAF_PSI_MIN =',leaf_psi_min (ipft) - write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) write (unit=*,fmt=efmt ) ' + SMALL_PSI_MIN =',small_psi_min(ipft) write (unit=*,fmt='(a)' ) ' ' @@ -1017,7 +1137,8 @@ subroutine calc_plant_water_flux(dt & !timestep ! Copy all the results to output variables. !------------------------------------------------------------------------------------! wflux_wl = sngloff(wflux_wl_d,tiny_offset) - do k = 1, nzg + wflux_gw_layer(:) = 0.0 + do k = lsl, nzg wflux_gw_layer(k) = sngloff(wflux_gw_layer_d(k),tiny_offset) end do wflux_gw = sum(wflux_gw_layer) diff --git a/ED/src/dynamics/reproduction.f90 b/ED/src/dynamics/reproduction.f90 index 170fec5a8..52ab6a4d6 100644 --- a/ED/src/dynamics/reproduction.f90 +++ b/ED/src/dynamics/reproduction.f90 @@ -179,6 +179,7 @@ subroutine reproduction_driver(cgrid,month,veget_dyn_on) !----- The big loops start here. -------------------------------------------------! polyloop: do ipy = 1,cgrid%npolygons + cpoly => cgrid%polygon(ipy) !------------------------------------------------------------------------------! ! Check whether this is late spring/early summer. This is needed for ! @@ -187,8 +188,8 @@ subroutine reproduction_driver(cgrid,month,veget_dyn_on) !------------------------------------------------------------------------------! late_spring = (cgrid%lat(ipy) >= 0.0 .and. month == 6) .or. & (cgrid%lat(ipy) < 0.0 .and. month == 12) + !------------------------------------------------------------------------------! - cpoly => cgrid%polygon(ipy) siteloop_sort: do isi = 1,cpoly%nsites csite => cpoly%site(isi) @@ -1286,8 +1287,8 @@ subroutine seed_dispersal(cpoly,late_spring) ! of them will land again in this patch, and we correct for this further ! ! down. ! !------------------------------------------------------------------------! - csite%cbudget_seedrain(donpa) = csite%cbudget_seedrain(donpa) & - - bseed_maygo * frqsumi + donsite%cbudget_seedrain(donpa) = donsite%cbudget_seedrain(donpa) & + - bseed_maygo * frqsumi !------------------------------------------------------------------------! @@ -1314,7 +1315,7 @@ subroutine seed_dispersal(cpoly,late_spring) ! (4) RPY = DPA * AD * AR (1->3) ! ! (5) RPA = DPA * AD (4->2, regardless of the patch) ! !------------------------------------------------------------------------! - bseed_xpatch = bseed_maygo * csite%area(donpa) * cpoly%area(donsi) + bseed_xpatch = bseed_maygo * donsite%area(donpa) * cpoly%area(donsi) !------------------------------------------------------------------------! @@ -1343,8 +1344,8 @@ subroutine seed_dispersal(cpoly,late_spring) ! subtracted all the non-local dispersal outside the receptor site ! ! loop. ! !------------------------------------------------------------------! - csite%cbudget_seedrain(recpa) = csite%cbudget_seedrain(recpa) & - + bseed_xpatch * frqsumi + recsite%cbudget_seedrain(recpa) = recsite%cbudget_seedrain(recpa) & + + bseed_xpatch * frqsumi !------------------------------------------------------------------! diff --git a/ED/src/dynamics/rk4_copy_patch.f90 b/ED/src/dynamics/rk4_copy_patch.f90 index 9fbeff87e..f8d6edffe 100644 --- a/ED/src/dynamics/rk4_copy_patch.f90 +++ b/ED/src/dynamics/rk4_copy_patch.f90 @@ -931,10 +931,11 @@ end subroutine copy_rk4_patch ! This subroutine will copy the variables from the integration buffer to the state ! ! patch and cohorts. ! !---------------------------------------------------------------------------------------! - subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm,ebudget_netrad & - ,ebudget_loss2atm,co2budget_loss2atm,wbudget_loss2drainage & - ,ebudget_loss2drainage,wbudget_loss2runoff,ebudget_loss2runoff & - ,co2budget_denseffect,ebudget_denseffect,wbudget_denseffect) + subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm & + ,ebudget_netrad,ebudget_loss2atm,co2budget_loss2atm & + ,wbudget_loss2drainage,ebudget_loss2drainage,wbudget_loss2runoff & + ,ebudget_loss2runoff,co2budget_denseffect,ebudget_denseffect & + ,wbudget_denseffect) use rk4_coms , only : rk4patchtype & ! structure , rk4site & ! intent(in) , rk4min_veg_temp & ! intent(in) @@ -2092,6 +2093,8 @@ subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm,ebudget_ + csite%ground_shv (ipa) * dtlsm_o_frqsum csite%fmean_can_ggnd (ipa) = csite%fmean_can_ggnd (ipa) & + csite%ggnet (ipa) * dtlsm_o_frqsum + csite%fmean_snowfac (ipa) = csite%fmean_snowfac (ipa) & + + csite%snowfac (ipa) * dtlsm_o_frqsum !------------------------------------------------------------------------------------! ! Snow/pounding layers. We keep track of the total, not individual layers. ! ! Energy will be integrated as an extensive variable, we will convert it by the ! diff --git a/ED/src/dynamics/rk4_derivs.f90 b/ED/src/dynamics/rk4_derivs.f90 index d413a383f..869f22b5a 100644 --- a/ED/src/dynamics/rk4_derivs.f90 +++ b/ED/src/dynamics/rk4_derivs.f90 @@ -25,7 +25,11 @@ module rk4_derivs !---------------------------------------------------------------------------------------! subroutine leaf_derivs(initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) - use rk4_coms , only : rk4patchtype ! ! structure + use rk4_coms , only : rk4patchtype & ! structure + , rk4aux & ! intent(out) + , zero_rk4_aux & ! sub-routine + , zero_rk4_patch & ! sub-routine + , zero_rk4_cohort ! ! sub-routine use ed_state_vars , only : sitetype & ! structure , polygontype ! ! structure use grid_coms , only : nzg & ! intent(in) @@ -43,10 +47,15 @@ subroutine leaf_derivs(initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) ! solver solution. !------------------------------------------------------------------------------------! - !----- Ensure that theta_Eiv and water storage derivatives are both zero. -----------! - dinitp%ebudget_storage = 0.d0 - dinitp%wbudget_storage = 0.d0 - dinitp%co2budget_storage = 0.d0 + + !---- Flush all derivatives to zero. ------------------------------------------------! + call zero_rk4_patch (dinitp) + call zero_rk4_cohort(dinitp) + !------------------------------------------------------------------------------------! + + + !---- Flush auxiliary variables to zero. --------------------------------------------! + call zero_rk4_aux(rk4aux(ibuff)) !------------------------------------------------------------------------------------! @@ -84,15 +93,13 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) , slzt8 & ! intent(in) , dslzt8 & ! intent(in) , ss & ! intent(in) - , isoilbc & ! intent(in) , sin_sldrain8 & ! intent(in) , hydr_conduct8 ! ! function use rk4_coms , only : checkbudget & ! intent(in) , print_detailed & ! intent(in) , rk4site & ! intent(in) , rk4patchtype & ! structure - , rk4aux & ! intent(out) - , zero_rk4_aux ! ! intent(in) + , rk4aux ! ! intent(out) use ed_state_vars , only : sitetype & ! structure , patchtype & ! structure , polygontype ! ! structure @@ -174,27 +181,6 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------------------! - !---- Flush auxiliary variables to zero. --------------------------------------------! - call zero_rk4_aux(rk4aux(ibuff)) - !------------------------------------------------------------------------------------! - - - - !----- Make sure derivatives are flushed to zero. -----------------------------------! - dinitp%soil_energy(:) = 0.0d0 - dinitp%soil_water(:) = 0.0d0 - dinitp%sfcwater_depth(:) = 0.0d0 - dinitp%sfcwater_energy(:) = 0.0d0 - dinitp%sfcwater_mass(:) = 0.0d0 - dinitp%virtual_energy = 0.0d0 - dinitp%virtual_water = 0.0d0 - dinitp%virtual_depth = 0.0d0 - if (fast_diagnostics .or. print_detailed) then - dinitp%avg_transloss(:) = 0.0d0 - end if - !------------------------------------------------------------------------------------! - - !------------------------------------------------------------------------------------! @@ -355,7 +341,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) ! Find the boundary condition for total potential beneath the bottom layer. ! !------------------------------------------------------------------------------------! nsoil = rk4site%ntext_soil(klsl) - select case (isoilbc) + select case (rk4site%isoilbc) case (0) !---------------------------------------------------------------------------------! ! Bedrock. Make the potential exactly the same as the bottom layer, and the ! @@ -420,6 +406,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) rk4aux(ibuff)%psiplusz (kben) = slzt8(kben) + initp%soil_mstpot(kben) rk4aux(ibuff)%drysoil (kben) = .false. rk4aux(ibuff)%satsoil (kben) = .false. + !---------------------------------------------------------------------------------! end select !------------------------------------------------------------------------------------! @@ -598,7 +585,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) if (initp%virtual_water /= 0.d0) then !!process "virtural water" pool nsoil = rk4site%ntext_soil(mzg) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + continue + case default infilt = - dslzi8(mzg) * 5.d-1 & * hydr_conduct8(mzg,nsoil,initp%soil_water(mzg) & ,initp%soil_fracliq(mzg)) & @@ -610,12 +600,15 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) rk4aux(ibuff)%qw_flux_g(mzg+1) = rk4aux(ibuff)%qw_flux_g(mzg+1) + qinfilt dinitp%virtual_water = dinitp%virtual_water - infilt*wdns8 dinitp%virtual_energy = dinitp%virtual_energy - qinfilt - end if + end select end if !! end virtual water pool if (initp%nlev_sfcwater >= 1) then !----- Process "snow" water pool --------------! surface_water = initp%sfcwater_mass(1)*initp%sfcwater_fracliq(1)*wdnsi8 !(m/m2) nsoil = rk4site%ntext_soil(mzg) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + continue + case default !----- Calculate infiltration rate (m/s) -----------------------------------! infilt = - dslzi8(mzg) * 5.d-1 & * hydr_conduct8(mzg,nsoil,initp%soil_water(mzg) & @@ -629,7 +622,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) dinitp%sfcwater_mass(1) = dinitp%sfcwater_mass(1) - infilt*wdns8 dinitp%sfcwater_energy(1) = dinitp%sfcwater_energy(1) - qinfilt dinitp%sfcwater_depth(1) = dinitp%sfcwater_depth(1) - infilt - end if + end select end if ! End snow water pool end if !! End alternate infiltration !------------------------------------------------------------------------------------! @@ -648,7 +641,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------------------! do k = klsl, mzg nsoil = rk4site%ntext_soil(k) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + rk4aux(ibuff)%w_flux_g(k) = 0.d0 + case default !----- Log-linear interpolation of hydraulic conductivity to layer interface. -! avg_hydcond = rk4aux(ibuff)%hydcond(k-1) & @@ -677,10 +673,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) end if !------------------------------------------------------------------------------! - - else - rk4aux(ibuff)%w_flux_g(k) = 0.d0 - end if + end select !---------------------------------------------------------------------------------! @@ -780,8 +773,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------! ! Skip calculation if no water is available in this layer. ! !------------------------------------------------------------------------! - if ( rk4site%ntext_soil(k2) == 13 .or. & - rk4aux(ibuff)%avail_h2o_lyr(k2) < tiny_num8 ) cycle k2_transp_loop + if ( trim(soil8(rk4site%ntext_soil(k2))%method) == 'BDRK' .or. & + rk4aux(ibuff)%avail_h2o_lyr(k2) < tiny_num8 ) then + cycle k2_transp_loop + end if !------------------------------------------------------------------------! @@ -862,6 +857,19 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) qloss_tot = 0.d0 uint_water_k1 = tl2uint8(initp%soil_tempk(k1),1.d0) + + !------------------------------------------------------------------------------! + ! MLO -> XX. I added this if to bypass contributions from this layer to ! + ! transpiration when the soil is completely desiccated. Do you ! + ! foresee any problems? ! + !------------------------------------------------------------------------------! + if (rk4aux(ibuff)%drysoil(k1)) then + cycle k1_transh_loop + end if + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! ! Integrate the total to be removed from this layer. Add water and ! ! internal energy to each cohort, so water and energy are conserved. The ! diff --git a/ED/src/dynamics/rk4_driver.F90 b/ED/src/dynamics/rk4_driver.F90 index ae758614c..8e428ad62 100644 --- a/ED/src/dynamics/rk4_driver.F90 +++ b/ED/src/dynamics/rk4_driver.F90 @@ -25,6 +25,7 @@ subroutine rk4_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function use soil_respiration , only : soil_respiration_driver ! ! sub-routine @@ -87,6 +88,7 @@ subroutine rk4_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !----- Functions --------------------------------------------------------------------! @@ -98,6 +100,31 @@ subroutine rk4_timestep(cgrid) polygonloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -112,7 +139,7 @@ subroutine rk4_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! @@ -121,12 +148,13 @@ subroutine rk4_timestep(cgrid) !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2 & - ,cmet%geoht,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -251,7 +279,8 @@ subroutine rk4_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! @@ -434,8 +463,8 @@ subroutine integrate_patch_rk4(csite,initp,ipa,isi,ibuff,nighttime,wcurr_loss2at !------------------------------------------------------------------------------------! ! Move the state variables from the integrated patch to the model patch. ! !------------------------------------------------------------------------------------! - call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm,ecurr_netrad & - ,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & + call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm & + ,ecurr_netrad,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & ,ecurr_loss2drainage,wcurr_loss2runoff,ecurr_loss2runoff & ,co2curr_denseffect,ecurr_denseffect,wcurr_denseffect) !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/rk4_integ_utils.f90 b/ED/src/dynamics/rk4_integ_utils.f90 index 46db5c36a..de2ee62d9 100644 --- a/ED/src/dynamics/rk4_integ_utils.f90 +++ b/ED/src/dynamics/rk4_integ_utils.f90 @@ -252,10 +252,10 @@ end subroutine odeint ! This is to ensure all variables are in double precision, so consistent with the ! ! buffer variables. ! !---------------------------------------------------------------------------------------! - subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tmp & - ,atm_shv,atm_co2,zoff,exner,pcpg,qpcpg,dpcpg,prss,rshort & - ,rlong,par_beam,par_diffuse,nir_beam,nir_diffuse,geoht & - ,lsl,ntext_soil,green_leaf_factor,lon,lat,cosz) + subroutine copy_met_2_rk4site(mzg,site_isoilbc,atm_ustar,atm_theiv,atm_vpdef,atm_theta & + ,atm_tmp,atm_shv,atm_co2,zoff,exner,pcpg,qpcpg,dpcpg,prss & + ,rshort,rlong,par_beam,par_diffuse,nir_beam,nir_diffuse & + ,geoht,lsl,ntext_soil,green_leaf_factor,lon,lat,cosz) use ed_max_dims , only : n_pft ! ! intent(in) use rk4_coms , only : rk4site ! ! structure use canopy_air_coms, only : ustmin8 ! ! intent(in) @@ -268,9 +268,9 @@ subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tm implicit none !----- Arguments --------------------------------------------------------------------! integer , intent(in) :: mzg + integer , intent(in) :: site_isoilbc integer , intent(in) :: lsl real , intent(in) :: atm_ustar - ! real , intent(in) :: vels real , intent(in) :: atm_theiv real , intent(in) :: atm_vpdef real , intent(in) :: atm_theta @@ -300,8 +300,11 @@ subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tm !----- Copy the integer variables. --------------------------------------------------! rk4site%lsl = lsl + rk4site%isoilbc = site_isoilbc rk4site%ntext_soil(:) = 0 rk4site%ntext_soil(1:mzg) = ntext_soil(1:mzg) + !------------------------------------------------------------------------------------! + !----- Convert to double precision. -------------------------------------------------! rk4site%atm_theiv = dble(atm_theiv ) @@ -597,8 +600,7 @@ subroutine get_yscal(y,dy,htry,yscal,cpatch) use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) use consts_coms , only : wdnsi8 ! ! intent(in) - use soil_coms , only : isoilbc & ! intent(in) - , dslzi8 ! ! intent(in) + use soil_coms , only : dslzi8 ! ! intent(in) use physiology_coms , only : plant_hydro_scheme ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -993,15 +995,15 @@ subroutine get_yscal(y,dy,htry,yscal,cpatch) ! Drainage terms will be checked only if the boundary condition is free ! ! drainage. ! !---------------------------------------------------------------------------------! - if (isoilbc == 0 .or. (abs(y%ebudget_loss2drainage) < tiny_offset .and. & - abs(dy%ebudget_loss2drainage) < tiny_offset) ) then + if (rk4site%isoilbc == 0 .or. (abs(y%ebudget_loss2drainage) < tiny_offset & + .and. abs(dy%ebudget_loss2drainage) < tiny_offset)) then yscal%ebudget_loss2drainage = huge_offset else yscal%ebudget_loss2drainage = abs(y%ebudget_loss2drainage) & + abs(dy%ebudget_loss2drainage*htry) end if - if (isoilbc == 0 .or. (abs(y%wbudget_loss2drainage) < tiny_offset .and. & - abs(dy%wbudget_loss2drainage) < tiny_offset) ) then + if (rk4site%isoilbc == 0 .or. (abs(y%wbudget_loss2drainage) < tiny_offset & + .and. abs(dy%wbudget_loss2drainage) < tiny_offset)) then yscal%wbudget_loss2drainage = huge_offset else yscal%wbudget_loss2drainage = abs(y%wbudget_loss2drainage) & @@ -1847,7 +1849,8 @@ subroutine rkqs(x,htry,hgoal,hdid,hnext,csite,ipa,isi,ibuff) , patchtype ! ! structure use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) - use ed_misc_coms , only : dtlsm ! ! intent(in) + use ed_misc_coms , only : dtlsm & ! intent(in) + , current_time ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -1945,8 +1948,18 @@ subroutine rkqs(x,htry,hgoal,hdid,hnext,csite,ipa,isi,ibuff) write (unit=*,fmt='(80a)') ('=',k=1,80) write (unit=*,fmt='(a)') ' STEPSIZE UNDERFLOW IN RKQS' write (unit=*,fmt='(80a)') ('-',k=1,80) + write (unit=*,fmt='(a,1x,2(i2.2,a),i4.4,1x,3(i2.2,a))') & + ' + TIME: ' & + ,current_time%month,'/',current_time%date,'/',current_time%year & + ,current_time%hour,':',current_time%min,':',current_time%sec,' UTC' write (unit=*,fmt='(a,1x,f9.4)') ' + LONGITUDE: ',rk4site%lon write (unit=*,fmt='(a,1x,f9.4)') ' + LATITUDE: ',rk4site%lat + write (unit=*,fmt='(a)') ' + SITE INFO: ' + write (unit=*,fmt='(a,1x,i6)') ' - NUMBER: ',isi + write (unit=*,fmt='(a,1x,i6)') ' - NTEXT(NZG) ' & + ,rk4site%ntext_soil(nzg) + write (unit=*,fmt='(a,1x,i6)') ' - LSL: ',rk4site%lsl + write (unit=*,fmt='(a,1x,i6)') ' - ISOILBC: ',rk4site%isoilbc write (unit=*,fmt='(a)') ' + PATCH INFO: ' write (unit=*,fmt='(a,1x,i6)') ' - NUMBER: ',ipa write (unit=*,fmt='(a,1x,es12.4)') ' - AGE: ',csite%age(ipa) diff --git a/ED/src/dynamics/rk4_misc.f90 b/ED/src/dynamics/rk4_misc.f90 index f847831ca..2a083d869 100644 --- a/ED/src/dynamics/rk4_misc.f90 +++ b/ED/src/dynamics/rk4_misc.f90 @@ -3707,8 +3707,8 @@ subroutine print_csiteipa(csite, ipa) write(unit=*,fmt='(80a)') ('-',k=1,80) - write (unit=*,fmt='(a,1x,2(i2.2,a),i4.4,1x,3(i2.2,a))') & - 'Time:',current_time%month,'/',current_time%date,'/',current_time%year & + write (unit=*,fmt='(a,1x,i4.4,2(a,i2.2),1x,3(i2.2,a))') & + 'Time:',current_time%year,'-',current_time%month,'-',current_time%date & ,current_time%hour,':',current_time%min,':',current_time%sec,' UTC' write(unit=*,fmt='(a,1x,es12.4)') 'Attempted step size:',csite%htry(ipa) write (unit=*,fmt='(a,1x,i6)') 'Ncohorts: ',cpatch%ncohorts diff --git a/ED/src/dynamics/vegetation_dynamics.f90 b/ED/src/dynamics/vegetation_dynamics.f90 index 645ae24c9..c30e6dcd7 100644 --- a/ED/src/dynamics/vegetation_dynamics.f90 +++ b/ED/src/dynamics/vegetation_dynamics.f90 @@ -34,7 +34,7 @@ subroutine veg_dynamics_driver(new_month,new_year,gr_tfact0,veget_dyn_on) , yr_day ! ! intent(in) use mem_polygons , only : maxpatch ! ! intent(in) use average_utils , only : normalize_ed_today_vars & ! sub-routine - , normalize_ed_todaynpp_vars & ! sub-routine + , copy_today_to_dmean_vars & ! sub-routine , zero_ed_today_vars ! ! sub-routine use canopy_radiation_coms, only : ihrzrad ! ! intent(in) use hrzshade_utils , only : split_hrzshade & ! sub-routine @@ -129,7 +129,7 @@ subroutine veg_dynamics_driver(new_month,new_year,gr_tfact0,veget_dyn_on) !------ update dmean and mmean values for NPP allocation terms ------------------! - call normalize_ed_todayNPP_vars(cgrid) + call copy_today_to_dmean_vars(cgrid) !---------------------------------------------------------------------------------! diff --git a/ED/src/init/ed_init.F90 b/ED/src/init/ed_init.F90 index b4913d66c..178165208 100644 --- a/ED/src/init/ed_init.F90 +++ b/ED/src/init/ed_init.F90 @@ -34,6 +34,12 @@ subroutine set_polygon_coordinates() cgrid%lat (ipy) = work_v(ifm)%glat (ipy) cgrid%xatm(ipy) = work_v(ifm)%xid (ipy) cgrid%yatm(ipy) = work_v(ifm)%yid (ipy) + + + + !----- Initialise load adjacency with dummy value. ----------------------------! + cgrid%load_adjacency(ipy) = 0 + !------------------------------------------------------------------------------! end do polyloop !---------------------------------------------------------------------------------! end do gridloop @@ -94,9 +100,6 @@ subroutine set_site_defprops() cgrid => edgrid_g(ifm) polyloop: do ipy=1,cgrid%npolygons - - !----- Initialise load adjacency with dummy value. ----------------------------! - cgrid%load_adjacency(ipy) = 0 !----- Alias to current polygon. ----------------------------------------------! cpoly => cgrid%polygon(ipy) @@ -311,6 +314,7 @@ subroutine load_ecosystem_state() , near_bare_ground_big_leaf_init ! ! sub-routine use ed_bigleaf_init , only : sas_to_bigleaf ! ! sub-routine #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum & ! intent(in) @@ -320,9 +324,6 @@ subroutine load_ecosystem_state() #endif implicit none -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Local variables --------------------------------------------------------------! integer :: igr integer :: ping @@ -353,7 +354,7 @@ subroutine load_ecosystem_state() do igr = 1,ngrids call read_site_file(edgrid_g(igr),igr) end do - case (4,7) + case (4,7,8) continue case default call set_site_defprops() @@ -447,6 +448,30 @@ subroutine load_ecosystem_state() end do end select + + + case (8) + !---------------------------------------------------------------------------------! + ! Initialise model with ED-2 initial conditions file. This is somewhat ! + ! similar to option 6, but it allows multiple sites, and these files do not ! + ! require any transformation of PFTs and disturbance type flags. ! + !---------------------------------------------------------------------------------! + write(unit=*,fmt='(a,i3.3)') & + ' + Initialise from ED2 initial conditions file. Node: ',mynum + call read_ed22_initial_file() + !---------------------------------------------------------------------------------! + + + + !----- In case this is a big-leaf simulation, convert initial conditions. --------! + select case (ibigleaf) + case (1) + do igr=1,ngrids + call sas_to_bigleaf(edgrid_g(igr)) + end do + end select + !---------------------------------------------------------------------------------! + end select @@ -529,7 +554,8 @@ subroutine sfcdata_ed() use rk4_coms , only : ipercol ! ! intent(in) use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) + use ed_max_dims , only : ed_nstyp ! ! intent(in) + use soil_coms , only : soil_hydro_scheme & ! intent(in) , slz & ! intent(in) , dslz & ! intent(out) , dslzo2 & ! intent(out) @@ -552,7 +578,8 @@ subroutine sfcdata_ed() , slcons18 & ! intent(out) , soil & ! intent(in) , thicknet & ! intent(out) - , thick ! ! intent(out) + , thick & ! intent(out) + , ed_gen_soil_table ! ! subroutine use consts_coms , only : wdns & ! intent(in) , wdnsi8 ! ! intent(in) use rk4_coms , only : rk4min_sfcw_moist & ! intent(in) @@ -560,11 +587,14 @@ subroutine sfcdata_ed() , rk4min_sfcw_mass & ! intent(out) , rk4min_virt_water ! ! intent(out) use ed_misc_coms, only : dtlsm ! ! intent(in) + use decomp_coms , only : rh_active_depth & ! intent(in) + , k_rh_active ! ! intent(out) implicit none !----- Local variables --------------------------------------------------------------! integer :: k integer :: nnn integer :: kzs + logical :: is_hydr_decay real :: thik real :: stretch real :: slz0 @@ -625,15 +655,19 @@ subroutine sfcdata_ed() end do + + !------------------------------------------------------------------------------------! + ! Generate the look-up table for soil properties. ! + !------------------------------------------------------------------------------------! + call ed_gen_soil_table() + !------------------------------------------------------------------------------------! + + !----- Find layer-dependent hydraulic conductivity. ---------------------------------! + is_hydr_decay = (ipercol == 2) .or. (soil_hydro_scheme == 2) do nnn = 1,ed_nstyp do k = 0,nzg - select case (ipercol) - case (0,1) - !----- Original form, constant with depth. --------------------------------! - slcons1(k,nnn) = soil(nnn)%slcons - !---------------------------------------------------------------------------! - case (2) + if (is_hydr_decay) then !---------------------------------------------------------------------------! ! Define conductivity using the SIMTOP approach (N05). ! ! ! @@ -645,7 +679,12 @@ subroutine sfcdata_ed() !---------------------------------------------------------------------------! slcons1(k,nnn) = soil(nnn)%slcons * exp ( soil(nnn)%fhydraul * slzt(k)) !---------------------------------------------------------------------------! - end select + else + !----- Original form, constant with depth. --------------------------------! + slcons1(k,nnn) = soil(nnn)%slcons + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! !------ Find the double precision. --------------------------------------------! slcons18(k,nnn) = dble(slcons1(k,nnn)) @@ -676,6 +715,20 @@ subroutine sfcdata_ed() !----- Assigning some soil grid-dependent RK4 variables -----------------------------! rk4min_sfcw_mass = rk4min_sfcw_moist * wdns * dslz(nzg) rk4min_virt_water = rk4min_virt_moist * wdns * dslz(nzg) + !------------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------------! + ! Determine the bottommost layer to consider for environmental regulation of ! + ! heterotrophic respiration. ! + !------------------------------------------------------------------------------------! + k_rh_loop: do k_rh_active=nzg-1,1,-1 + if (slz(k_rh_active) < rh_active_depth) exit k_rh_loop + end do k_rh_loop + k_rh_active = k_rh_active + 1 + !------------------------------------------------------------------------------------! return end subroutine sfcdata_ed diff --git a/ED/src/init/ed_init_atm.F90 b/ED/src/init/ed_init_atm.F90 index 65cf07ee4..041ab13d0 100644 --- a/ED/src/init/ed_init_atm.F90 +++ b/ED/src/init/ed_init_atm.F90 @@ -33,6 +33,7 @@ subroutine ed_init_atm() , terminate_cohorts & ! subroutine , split_cohorts ! ! subroutine #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : nnodetot & ! intent(in) , mynum & ! intent(in) , sendnum & ! intent(in) @@ -95,10 +96,6 @@ subroutine ed_init_atm() !----- Local variables (MPI only). -----------------------------------------------------! #if defined(RAMS_MPI) integer :: ierr -#endif - !----- Add the MPI common block. -------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/init/ed_params.f90 b/ED/src/init/ed_params.f90 index 3edbea93f..eddc7588e 100644 --- a/ED/src/init/ed_params.f90 +++ b/ED/src/init/ed_params.f90 @@ -525,7 +525,7 @@ subroutine init_decomp_params() rh0 = 0.700 ! 0.701 ! 0.425 rh_q10 = 1.500 ! 1.500 ! 1.893 rh_p_smoist = 1.600 ! 0.836 ! 0.606 - rh_p_oxygen = 0.600 ! 0.404 ! 0.164 + rh_p_oxygen = 0.450 ! 0.404 ! 0.164 !---------------------------------------------------------------------------------------! @@ -1525,12 +1525,15 @@ end subroutine init_hydro_coms !==========================================================================================! !==========================================================================================! ! Subroutine that initialises most of the soil parameters. ! +! ! +! MLO: This sub-routine formerly initiliased the soil and soil8 tables, but this creates ! +! a problem for some HISTORY runs (especially those with multiple sites that modify ! +! the default parameters). The soil table is now initialised in a separate sub- ! +! routine (ed_gen_soil_table), after loading HISTORY variables, or right before or ! +! right after reading the initial conditions. ! !------------------------------------------------------------------------------------------! subroutine init_soil_coms - use detailed_coms , only : idetailed ! ! intent(in) - use ed_max_dims , only : str_len ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) - , isoilflg & ! intent(in) + use soil_coms , only : isoilflg & ! intent(in) , nslcon & ! intent(in) , soil_hydro_scheme & ! intent(in) , slxclay & ! intent(in) @@ -1539,11 +1542,17 @@ subroutine init_soil_coms , slph & ! intent(in) , slcec & ! intent(in) , sldbd & ! intent(in) - , soil & ! intent(in) - , soil_class & ! type + , slxkey_ref & ! intent(out) + , slhydro_ref & ! intent(out) + , slxclay_ref & ! intent(out) + , slxsilt_ref & ! intent(out) + , slxsand_ref & ! intent(out) + , slsoc_ref & ! intent(out) + , slph_ref & ! intent(out) + , slcec_ref & ! intent(out) + , sldbd_ref & ! intent(out) , soilcol & ! intent(in) , soilcol_class & ! type - , soil8 & ! intent(out) , water_stab_thresh & ! intent(out) , snowmin & ! intent(out) , dewmax & ! intent(out) @@ -1564,68 +1573,18 @@ subroutine init_soil_coms , sin_sldrain & ! intent(out) , sin_sldrain8 & ! intent(out) , hydcond_min & ! intent(out) - , hydcond_min8 & ! intent(out) - , ed_init_soil & ! subroutine - , matric_potential & ! function - , soil_moisture ! ! function - use phenology_coms , only : thetacrit ! ! intent(in) - use disturb_coms , only : sm_fire ! ! intent(in) + , hydcond_min8 ! ! intent(out) use grid_coms , only : ngrids ! ! intent(in) - use consts_coms , only : grav & ! intent(in) - , wdns & ! intent(in) - , hr_sec & ! intent(in) + use consts_coms , only : wdns & ! intent(in) , day_sec & ! intent(in) , pio180 & ! intent(in) , pio1808 ! ! intent(in) implicit none !----- Local variables. ----------------------------------------------------------------! - integer :: s ! Soil texture flag logical :: update_slx ! Update texture fractions? [ T|F] - logical :: print_soil_table ! Print parameter table? [ T|F] - real(kind=4) :: soilep ! Effective porosity (O19) [ m3/m3] - real(kind=4) :: slpot33 ! Potential for EP (O19) [ m] - real(kind=4) :: slcons_mmhr ! Sat. hydraulic conduct. [ mm/hr] - real(kind=4) :: slcpd_mjm3k ! Soil heat capacity [MJ/m3/K] - real(kind=4) :: ksand ! k-factor for sand (de Vries model) - real(kind=4) :: ksilt ! k-factor for silt (de Vries model) - real(kind=4) :: kclay ! k-factor for clay (de Vries model) - real(kind=4) :: kair ! k-factor for air (de Vries model) - !----- Initial sand and clay volumetric fractions. -------------------------------------! - real(kind=4) , dimension(ed_nstyp) :: xsand_def ! Default sand fraction [ 0-1] - real(kind=4) , dimension(ed_nstyp) :: xclay_def ! Default clay fraction [ 0-1] - !---- Soil texture acronym. ------------------------------------------------------------! - character(len=4), dimension(ed_nstyp) :: xkey_def ! Acronym !----- Local constants. ----------------------------------------------------------------! - real(kind=4), parameter :: fieldcp_K = 0.1 ! hydr. cond. at field cap. [mm/day] - real(kind=4), parameter :: residual_K = 1.e-5 ! minimum hydr. cond. (RS02) [mm/day] - real(kind=4), parameter :: slpots_MPa = -0.0005 ! Saturation for vG80 [ MPa] - real(kind=4), parameter :: slpot33_MPa = -0.033 ! Potential for soilep (O19) [ MPa] - real(kind=4), parameter :: slpotfc_MPa = -0.010 ! Field capacity (TH98) [ MPa] - real(kind=4), parameter :: slpotcp_MPa = -3.1 ! Matric pot. - air dry soil [ MPa] - real(kind=4), parameter :: slpotwp_MPa = -1.5 ! Matric pot. - wilting point [ MPa] - real(kind=4), parameter :: sand_hcapv = 2.128e6 ! Sand vol. heat capacity [J/m3/K] - real(kind=4), parameter :: clay_hcapv = 2.385e6 ! Clay vol. heat capacity [J/m3/K] - real(kind=4), parameter :: silt_hcapv = 2.256e6 ! Silt vol. heat capacity (*) [J/m3/K] - real(kind=4), parameter :: air_hcapv = 1.212e3 ! Air vol. heat capacity [J/m3/K] - real(kind=4), parameter :: sand_thcond = 8.80 ! Sand thermal conduct. [ W/m/K] - real(kind=4), parameter :: clay_thcond = 2.92 ! Clay thermal conduct. [ W/m/K] - real(kind=4), parameter :: silt_thcond = 5.87 ! Silt thermal conduct. (*) [ W/m/K] - real(kind=4), parameter :: air_thcond = 0.025 ! Air thermal conduct. [ W/m/K] - real(kind=4), parameter :: h2o_thcond = 0.57 ! Water thermal conduct. [ W/m/K] - !------ Name for the parameter table. --------------------------------------------------! - character(len=str_len), parameter :: soil_table_fn = 'soil_properties.txt' - !---------------------------------------------------------------------------------------! - ! (*) If anyone has the heat capacity and thermal conductivity for silt, please feel ! - ! free to add it in here, I didn't find any. Apparently no one knows, and I've ! - ! seen in other models that people just assume either the same as sand or the ! - ! average. Here I'm just using halfway. I think the most important thing is to ! - ! take into account the soil and the air, which are the most different. ! - ! ! - ! Sand (quartz), clay, air, and water heat capacities and thermal conductivities values ! - ! are from: ! - ! Monteith and Unsworth, 2008: Environmental Physics. ! - ! Academic Press, Third Edition. Table 15.1, p. 292 ! + real(kind=4), parameter :: residual_K = 1.e-5 ! min. hydr. cond. (RS02) [mm/day] !---------------------------------------------------------------------------------------! @@ -1659,24 +1618,24 @@ subroutine init_soil_coms !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! - ! Initialise the soil and soil8 structures. ! - !---------------------------------------------------------------------------------------! - call ed_init_soil() - !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! ! Removed the hardcoded initialisation of the entire structure. Instead, we set the ! ! texture for every class, then use the equations to populate the structure. ! !---------------------------------------------------------------------------------------! - xsand_def = (/ 0.920, 0.825, 0.660, 0.200, 0.410, 0.590, 0.100, 0.320 & - , 0.520, 0.060, 0.200, 0.200, 0.333, 0.075, 0.100, 0.375, 0.125 /) - xclay_def = (/ 0.030, 0.060, 0.110, 0.160, 0.170, 0.270, 0.340, 0.340 & - , 0.420, 0.470, 0.600, 0.200, 0.333, 0.050, 0.800, 0.525, 0.525 /) - xkey_def = (/' Sa',' LSa',' SaL',' SiL',' L','SaCL','SiCL',' CL' & - ,' SaC',' SiC',' C','Peat','BdRk',' Si',' CC',' CSa',' CSi' /) + slxkey_ref ( :) = (/' Sa',' LSa',' SaL',' SiL',' L','SaCL','SiCL',' CL' & + ,' SaC',' SiC',' C','Peat','BdRk',' Si',' CC',' CSa',' CSi' /) + slxsand_ref( :) = (/ 0.920, 0.825, 0.660, 0.200, 0.410, 0.590, 0.100, 0.320 & + , 0.520, 0.060, 0.200, 0.200, 0.333, 0.075, 0.100, 0.375, 0.125 /) + slxclay_ref( :) = (/ 0.030, 0.060, 0.110, 0.160, 0.170, 0.270, 0.340, 0.340 & + , 0.420, 0.470, 0.600, 0.200, 0.333, 0.050, 0.800, 0.525, 0.525 /) + slxsilt_ref( :) = 1. - slxsand_ref(:) - slxclay_ref(:) + slhydro_ref( :) = soil_hydro_scheme + slhydro_ref(12) = 12 + slhydro_ref(13) = 13 + slsoc_ref ( :) = slsoc + slph_ref ( :) = slph + slcec_ref ( :) = slcec + sldbd_ref ( :) = sldbd !---------------------------------------------------------------------------------------! @@ -1686,620 +1645,15 @@ subroutine init_soil_coms update_slx = any(isoilflg(1:ngrids) == 2) .and. slxclay > 0. .and. slxsand > 0. .and. & (slxclay + slxsand) <= 1. if (update_slx) then - xsand_def(nslcon) = slxsand - xclay_def(nslcon) = slxclay - xkey_def (nslcon) = 'User' + slxsand_ref(nslcon) = slxsand + slxclay_ref(nslcon) = slxclay + slxsilt_ref(nslcon) = 1. - slxsand - slxclay + slxkey_ref (nslcon) = 'User' end if !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Assign texture and silt fraction (method-independent). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - soil(s)%key = xkey_def(s) - soil(s)%xsand = xsand_def(s) - soil(s)%xclay = xclay_def(s) - soil(s)%xsilt = 1. - xsand_def(s) - xclay_def(s) - end do - !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - ! Other soil properties (relevant only when SOIL_HYDRO_SCHEME = 2). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - soil(s)%slsoc = slsoc - soil(s)%slph = slph - soil(s)%slcec = slcec - soil(s)%sldbd = sldbd - end do - !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - ! Calculate method- and texture-dependent properties. For a general overview, ! - ! check (M14). Additional references correspond to specific parametrisations. ! - ! ! - ! References: ! - ! ! - ! Brooks RH , Corey AT. 1964. Hydraulic properties of porous media. Hydrology Papers 3, ! - ! Colorado State University, Fort Collins, U.S.A (BC64). ! - ! Marthews TR, Quesada CA, Galbraith DR, Malhi Y, Mullins CE, Hodnett MG , Dharssi I. ! - ! 2014. High-resolution hydraulic parameter maps for surface soils in tropical South ! - ! America. Geosci. Model Dev. 7: 711-723. doi:10.5194/gmd-7-711-2014 (M14). ! - ! Campbell GS. 1974. A simple method for determining unsaturated conductivity from ! - ! moisture retention data. Soil Science 117: 311-314. ! - ! doi:10.1097/00010694-197406000-00001 (C74). ! - ! Cosby BJ, Hornberger GM, Clapp RB , Ginn TR. 1984. A statistical exploration of the ! - ! relationships of soil moisture characteristics to the physical properties of ! - ! soils. Water Resour. Res. 20: 682-690. doi:10.1029/WR020i006p00682 (C84). ! - ! van Genuchten MT. 1980. A closed-form equation for predicting the hydraulic ! - ! conductivity of unsaturated soils1. Soil Sci. Soc. Am. J. 44: 892-898. ! - ! doi:10.2136/sssaj1980.03615995004400050002x (vG80). ! - ! Hodnett M , Tomasella J. 2002. Marked differences between van Genuchten soil ! - ! water-retention parameters for temperate and tropical soils: a new ! - ! water-retention pedo-transfer functions developed for tropical soils. Geoderma ! - ! 108: 155-180. doi:10.1016/S0016-7061(02)00105-2 (HT02). ! - ! Montzka C, Herbst M, Weihermuller L, Verhoef A , Vereecken H. 2017. A global data set ! - ! of soil hydraulic properties and sub-grid variability of soil water retention and ! - ! hydraulic conductivity curves. Earth Syst. Sci. Data, 9: 529-543. ! - ! doi:10.5194/essd-9-529-2017 (M17). ! - ! Mualem Y. 1976. A new model for predicting the hydraulic conductivity of unsaturated ! - ! porous media. Water Resour. Res., 12: 513-522. doi:10.1029/WR012i003p00513 (M76). ! - ! Ottoni MV, Ottoni Filho TB, Lopes-Assad MLR , Rotunno Filho OC. 2019. Pedotransfer ! - ! functions for saturated hydraulic conductivity using a database with temperate and ! - ! tropical climate soils. J. Hydrol., 575: 1345-1358. ! - ! doi:10.1016/j.jhydrol.2019.05.050 (O19). ! - ! Romano N , Santini A. 2002. Field. In: Methods of soil analysis: Part 4 physical ! - ! methods (eds. Dane JH. & Topp GC.). Soil Science Society of America, Madison, WI, ! - ! SSSA Book Series 5.4, chap. 3.3.3, pp. 721--738 (RS02). ! - ! Schaap MG , Leij FJ. 2000. Improved prediction of unsaturated hydraulic conductivity ! - ! with the Mualem- van Genuchten model. Soil Sci. Soc. Am. J., 64: 843-851. ! - ! doi:10.2136/sssaj2000.643843x (SL00). ! - ! Tomasella J , Hodnett MG. 1998. Estimating soil water retention characteristics from ! - ! limited data in Brazilian Amazonia. Soil Sci. 163: 190-202. ! - ! doi:10.1097/00010694-199803000-00003 (TH98). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - - !----- Check soil texture. Peat and bedrock must be handled separately. ------------! - select case (s) - case (12) - !---------------------------------------------------------------------------------! - ! Peat. We always use BC64-M76 approach. This modify hydraulic properties ! - ! to account for high soil organic content. This class becomes obsolete for ! - ! SOIL_HYDRO_SCHEME=2 because we can account for SOC directly. ! - ! ! - ! MLO - I noticed that most parameters do not correspond to what is implemented ! - ! in LEAF3 (as of RAMS-6.0). I left the LEAF3 values as comments next to ! - ! the default values but someone running ED2 for peats should check. I ! - ! think the LEAF3 values intuitively make more sense for peat. ! - !---------------------------------------------------------------------------------! - soil(s)%method = 'BC64' - - !----- Peat, use the default value from LEAF3. -----------------------------------! - soil(s)%slcons = 8.0e-6 ! ED-2.2 2.357930e-6 - !---------------------------------------------------------------------------------! - - !---- Pore tortuosity factor. Assumed 1 to be consistent with BC64. --------------! - soil(s)%sltt = 1.0 - !---------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, aka ! - ! BC64's "b" factor). ! - !---------------------------------------------------------------------------------! - soil(s)%slbs = 7.75 ! ED-2.2 6.180000 - soil(s)%slnm = 1. / soil(s)%slbs - !---------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !---------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !---------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. -------------------------------------------------! - soil(s)%slpots = -0.356 ! ED-2.2 -0.534564359 - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp ! Inverse of bubbling point (not used) - !---------------------------------------------------------------------------------! - - - - !----- Soil moisture at saturation [m3/m3]. --------------------------------------! - soil(s)%slmsts = 0.863 ! ED-2.2 0.469200 - soil(s)%soilbp = soil(s)%slmsts ! Assume the same as saturation - soil(s)%soilpo = soil(s)%slmsts ! Assume the same as saturation - !---------------------------------------------------------------------------------! - - - !---- Field capacity [m3/m3] and potential at field capacity [m]. ----------------! - soil(s)%sfldcap = 0.535 ! ED-2.2 0.285709966 - soil(s)%slpotfc = matric_potential(s,soil(s)%sfldcap) - !---------------------------------------------------------------------------------! - - - !----- Residual moisture [m3/m3]. Ignored in C74 and the default ED2 method. ----! - soil(s)%soilre = 0. - !---------------------------------------------------------------------------------! - - - !----- Heat capacity. ------------------------------------------------------------! - soil(s)%slcpd = 874000. - !---------------------------------------------------------------------------------! - case (13) - !----- Bedrock. Hydraulics is disabled, only heat capacity is needed. -----------! - soil(s)%method = 'BDRK' - soil(s)%slcons = 0.0 - soil(s)%sltt = 0.0 - soil(s)%slnm = 1.0 - soil(s)%slbs = 1.0 - soil(s)%slmm = 1.0 - soil(s)%slmu = 1.0 - soil(s)%malpha = 0.0 - soil(s)%slpots = 0.0 - soil(s)%slmsts = 0.0 - soil(s)%slpotbp = 0.0 - soil(s)%soilbp = 0.0 - soil(s)%slpotpo = 0.0 - soil(s)%soilpo = 0.0 - soil(s)%soilre = 0.0 - soil(s)%sfldcap = 0.0 - soil(s)%slpotfc = 0.0 - soil(s)%slcpd = 2130000. - !---------------------------------------------------------------------------------! - case default - !---------------------------------------------------------------------------------! - ! Other soils. Decide on hydraulic parameters based on the method. ! - !---------------------------------------------------------------------------------! - select case (soil_hydro_scheme) - case (0) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from BC64/M76. Unless noted otherwise, the ! - ! parameters for the functions are from C84, based on measurements in the ! - ! United States. ! - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. ! - !------------------------------------------------------------------------------! - soil(s)%slcons = (10.**(-0.60 + 1.26*soil(s)%xsand - 0.64*soil(s)%xclay)) & - * 0.0254/hr_sec - !------------------------------------------------------------------------------! - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'BC64' - !------------------------------------------------------------------------------! - - - !---- Pore tortuosity factor. Assumed 1 to be consistent with BC64. -----------! - soil(s)%sltt = 1.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = 1. / (3.10 + 15.7*soil(s)%xclay - 0.3*soil(s)%xsand) - soil(s)%slbs = 1. / soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. ----------------------------------------------! - soil(s)%slpots = -1. & - * (10.**(2.17 - 0.63*soil(s)%xclay - 1.58*soil(s)%xsand)) * 0.01 - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - !----- Soil moisture at saturation (porosity) [m3/m3]. ------------------------! - soil(s)%slmsts = 0.01 * (50.5 - 14.2*soil(s)%xsand - 3.7*soil(s)%xclay) - !------------------------------------------------------------------------------! - - - !----- Bubbling point soil moisture and porosity, assume saturation [m3/m3]. --! - soil(s)%soilbp = soil(s)%slmsts ! Bubbling point - soil(s)%soilpo = soil(s)%slmsts ! Porosity - !------------------------------------------------------------------------------! - - - !----- Residual moisture [m3/m3]. Ignored in C74 and the default ED2 method. -! - soil(s)%soilre = 0.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%sfldcap = soil(s)%slmsts & - * ( soil(s)%slcons / ( fieldcp_K / ( wdns * day_sec ) ) ) & - ** soil(s)%slmu - soil(s)%slpotfc = matric_potential(s,soil(s)%sfldcap) - !------------------------------------------------------------------------------! - - case (1) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from BC64/M76. Unless noted otherwise, the ! - ! parameters for the functions are from TH98, based on measurements in the ! - ! Brazilian Amazon. ! - !------------------------------------------------------------------------------! - - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'BC64' - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. Use C84 settings, follow- ! - ! ing M14. ! - !------------------------------------------------------------------------------! - soil(s)%slcons = (10.**(-0.60 + 1.26*soil(s)%xsand - 0.64*soil(s)%xclay)) & - * 0.0254/hr_sec - !------------------------------------------------------------------------------! - - - !---- Pore tortuosity factor. Assumed 0.5, following M14. ---------------------! - soil(s)%sltt = 0.5 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = exp( - 1.197 - 0.417 * soil(s)%xsilt + 0.450 * soil(s)%xclay & - - 8.940 * soil(s)%xsilt * soil(s)%xclay & - + 10.00 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay ) - soil(s)%slbs = 1./ soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. ----------------------------------------------! - soil(s)%slpots = -1. / grav & - * ( 0.285 + 7.33 * soil(s)%xsilt * soil(s)%xsilt & - - 1.30 * soil(s)%xsilt * soil(s)%xclay & - + 3.60 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay ) - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - !----- Soil moisture at saturation (porosity) [m3/m3]. ------------------------! - soil(s)%slmsts = 0.4061 + 0.165 * soil(s)%xsilt + 0.162 * soil(s)%xclay & - + 1.37e-3 * soil(s)%xsilt * soil(s)%xsilt & - + 1.80e-5 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay - !------------------------------------------------------------------------------! - - - !----- Bubbling point soil moisture and porosity, assume saturation [m3/m3]. --! - soil(s)%soilbp = soil(s)%slmsts ! Bubbling point - soil(s)%soilpo = soil(s)%slmsts ! Porosity - !------------------------------------------------------------------------------! - - - - !----- Residual moisture [m3/m3]. --------------------------------------------! - soil(s)%soilre = max( 0.0 & - , - 0.02095 + 0.047 * soil(s)%xsilt & - + 0.431 * soil(s)%xclay & - - 0.00827 * soil(s)%xsilt * soil(s)%xclay ) - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%slpotfc = slpotfc_MPa * 1.e6 / (grav * wdns) - soil(s)%sfldcap = soil_moisture(s,soil(s)%slpotfc) - !------------------------------------------------------------------------------! - - case (2) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from vG80/M76. Unless noted otherwise, ! - ! the parameters for the function are from HT02, based on measurements in the ! - ! Brazilian Amazon. ! - !------------------------------------------------------------------------------! - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'vG80' - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore tortuosity factor. M14 assumed 0.5, but there is evidence that ! - ! this parameter should be regarded as empirical and some studies suggested ! - ! that it should be even negative (e.g., SL00 and M17). We follow SL00 and ! - ! assume the parameter to be -1.0. ! - !------------------------------------------------------------------------------! - soil(s)%sltt = -1.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = exp( 0.62986 - 0.833 * soil(s)%xclay - 0.529 * soil(s)%slsoc & - + 0.00593 * soil(s)%slph & - + 0.700 * soil(s)%xclay * soil(s)%xclay & - - 1.400 * soil(s)%xsand * soil(s)%xsilt ) - soil(s)%slbs = 1./ soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 1. - 1. / soil(s)%slnm - soil(s)%slmu = soil(s)%slnm / (1. - soil(s)%slnm) - !------------------------------------------------------------------------------! - - - !----- Bubbling point potential [m]. Assume equivalent to saturation. --------! - soil(s)%slpotbp = -1. / grav & - * exp( 0.02294 + 3.526 * soil(s)%xsilt & - - 2.440 * soil(s)%slsoc + 0.076 * soil(s)%slcec & - + 0.11331 * soil(s)%slph & - - 1.90000 * soil(s)%xsilt * soil(s)%xsilt ) - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - - !----- Soil moisture and potential at porosity [m3/m3]. -----------------------! - soil(s)%soilpo = 0.81799 + 0.099 * soil(s)%xclay - 3.142e-4 * soil(s)%sldbd & - + 0.01800 * soil(s)%slcec + 0.00451 * soil(s)%slph & - - 0.050 * soil(s)%xsand * soil(s)%xclay - soil(s)%slpotpo = matric_potential(s,soil(s)%soilpo) - !------------------------------------------------------------------------------! - - - - !----- Residual moisture [m3/m3]. --------------------------------------------! - soil(s)%soilre = max( 0.0 & - , 0.22733 - 0.164 * soil(s)%xsand + 0.235 * soil(s)%slcec & - - 0.00831 * soil(s)%slph & - + 0.18 * soil(s)%xclay * soil(s)%xclay & - + 0.26 * soil(s)%xsand * soil(s)%xclay ) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Soil moisture at "saturation". The vG80 approach assumes that actual ! - ! saturation occurs when soil matric potential is zero, which causes ! - ! singularities in many applications. To prevent FPE errors, we assume that ! - ! water potential zero corresponds to porosity (admittedly this is not ! - ! entirely accurate), and impose "saturation" for ED-2.2 purposes to be when ! - ! matric potential is -0.5 kPa, similar to the highest saturation potential ! - ! values obtained through Cosby et al. (1984) parametrisation. ! - !------------------------------------------------------------------------------! - soil(s)%slpots = slpots_MPa * 1.e6 / (grav * wdns) - soil(s)%slmsts = soil_moisture(s,soil(s)%slpots) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Soil moisture at bubbling point. Unlike other schemes, we account for ! - ! the differences between bubbling point and porosity. ! - !------------------------------------------------------------------------------! - soil(s)%soilbp = soil_moisture(s,soil(s)%slpotbp) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%slpotfc = slpotfc_MPa * 1.e6 / (grav * wdns) - soil(s)%sfldcap = soil_moisture(s,soil(s)%slpotfc) - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. Here we follow O19, which ! - ! depends upon the "effective porosity" (or difference between actual porosity ! - ! and soil moisture at -0.033 MPa). ! - !------------------------------------------------------------------------------! - slpot33 = slpot33_MPa * 1.e6 / (grav * wdns) - soilep = max(0.,soil(s)%slmsts - soil_moisture(s,slpot33)) - soil(s)%slcons = 19.31 / day_sec * soilep ** 1.948 - !------------------------------------------------------------------------------! - end select - !---------------------------------------------------------------------------------! - - end select - !------------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------------! - ! Additional derived parameters. ! - !------------------------------------------------------------------------------------! - select case (s) - case (13) - !----- Bedrock, do nothing. ------------------------------------------------------! - soil(s)%slpotcp = 0.0 - soil(s)%slpotwp = 0.0 - soil(s)%slpotfr = 0.0 - soil(s)%slpotld = 0.0 - soil(s)%slpotfc = 0.0 - soil(s)%slpotbp = 0.0 - soil(s)%slpots = 0.0 - soil(s)%slpotpo = 0.0 - soil(s)%soilcp = 0.0 - soil(s)%soilwp = 0.0 - soil(s)%soilfr = 0.0 - soil(s)%soilld = 0.0 - soil(s)%sfldcap = 0.0 - soil(s)%soilbp = 0.0 - soil(s)%slmsts = 0.0 - soil(s)%soilpo = 0.0 - soil(s)%fhydraul = 0.0 - !---------------------------------------------------------------------------------! - case default - !----- First guess, use water potential. -----------------------------------------! - soil(s)%slpotwp = slpotwp_MPa * 1.e6 / ( grav * wdns ) - soil(s)%slpotcp = slpotcp_MPa * wdns / grav - soil(s)%soilwp = soil_moisture(s,soil(s)%slpotwp) - soil(s)%soilcp = soil_moisture(s,soil(s)%slpotcp) - !----- In case soilcp is less than the residual (very unlikely), recalculate it. -! - if (soil(s)%soilcp < soil(s)%soilre) then - soil(s)%soilcp = soil(s)%soilre - soil(s)%slpotcp = matric_potential(s,soil(s)%soilcp) - end if - !----- Because we may have artificially increased soilcp, check soilwp. ----------! - if (soil(s)%soilwp < soil(s)%soilcp) then - soil(s)%soilwp = soil(s)%soilcp - soil(s)%slpotwp = soil(s)%slpotcp - end if - !---------------------------------------------------------------------------------! - - - - - !---------------------------------------------------------------------------------! - ! Find two remaining properties, that depend on the user choices. ! - ! ! - ! SOILLD/SLPOTLD. ! - ! The critical soil moisture below which drought deciduous plants start drop- ! - ! ping their leaves. The sign of input variable THETACRIT matters here. If ! - ! the user gave a positive number (or 0), then the soil moisture is a ! - ! fraction above wilting point. If it is negative, the value is the potential ! - ! in MPa. ! - ! SOILFR/SLPOTFR. ! - ! The critical soil moisture below which fires may happen, provided that the ! - ! user wants fires, and that there is enough biomass to burn. The sign of the ! - ! input variable SM_FIRE matters here. If the user gave a positive number ! - ! (or 0), then the soil moisture is a fraction above dry air soil. If it is ! - ! negative, the value is the potential in MPa. ! - !---------------------------------------------------------------------------------! - !----- Leaf drop. ----------------------------------------------------------------! - if (thetacrit >= 0.0) then - soil(s)%soilld = soil(s)%soilwp + thetacrit * (soil(s)%slmsts-soil(s)%soilwp) - soil(s)%slpotld = matric_potential(s,soil(s)%soilld) - else - soil(s)%slpotld = thetacrit * 1.e6 / (grav * wdns) - soil(s)%soilld = soil_moisture(s,soil(s)%slpotld) - end if - !----- Fire. ---------------------------------------------------------------------! - if (sm_fire >= 0.0) then - soil(s)%soilfr = soil(s)%soilcp + sm_fire * (soil(s)%slmsts-soil(s)%soilcp) - soil(s)%slpotfr = matric_potential(s,soil(s)%soilfr) - else - soil(s)%slpotfr = sm_fire * 1.e6 / (grav * wdns) - soil(s)%soilfr = soil_moisture(s,soil(s)%slpotfr) - end if - !---------------------------------------------------------------------------------! - - - - - !---------------------------------------------------------------------------------! - ! Define hydraulic parameter decay, similar to TOPMODEL. We currently use ! - ! the default value of 2.0, following N05's SIMTOP model. ! - ! ! - ! Niu GY, Yang ZL, Dickinson RE , Gulden LE. 2005. A simple TOPMODEL-based runoff ! - ! parameterization (SIMTOP) for use in global climate models. J. Geophys. ! - ! Res.-Atmos., 110: D21106. doi:10.1029/2005JD006111 (N05). ! - !---------------------------------------------------------------------------------! - soil(s)%fhydraul = 2.0 - !---------------------------------------------------------------------------------! - end select - !------------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------------! - ! Heat capacity (J/m3/K). Here we take the volume average amongst silt, clay, ! - ! and sand, and consider the contribution of air sitting in. In order to keep it ! - ! simple, we assume that the air fraction won't change, although in reality its ! - ! contribution should be a function of soil moisture. Here we use the amount of air ! - ! in case the soil moisture was halfway between dry air and saturated, so the ! - ! error is not too biased. ! - !------------------------------------------------------------------------------------! - soil(s)%slcpd = (1. - soil(s)%slmsts) & - * ( soil(s)%xsand * sand_hcapv + soil(s)%xsilt * silt_hcapv & - + soil(s)%xclay * clay_hcapv ) & - + 0.5 * ( soil(s)%slmsts - soil(s)%soilcp ) * air_hcapv - !------------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------------! - ! Thermal conductivity is the weighted average of thermal conductivities of all ! - ! materials, although a further weighting factor due to thermal gradient of ! - ! different materials. We use the de Vries model described at: ! - ! ! - ! Camillo, P., T.J. Schmugge, 1981: A computer program for the simulation of heat ! - ! and moisture flow in soils, NASA-TM-82121, Greenbelt, MD, United States. ! - ! ! - ! Parlange, M.B., et al., 1998: Review of heat and water movement in field soils, ! - ! Soil Till. Res., 47(1-2), 5-10. ! - ! ! - !------------------------------------------------------------------------------------! - !---- The k-factors, assuming spherical particles. ----------------------------------! - ksand = 3. * h2o_thcond / ( 2. * h2o_thcond + sand_thcond ) - ksilt = 3. * h2o_thcond / ( 2. * h2o_thcond + silt_thcond ) - kclay = 3. * h2o_thcond / ( 2. * h2o_thcond + clay_thcond ) - kair = 3. * h2o_thcond / ( 2. * h2o_thcond + air_thcond ) - !---- The conductivity coefficients. ------------------------------------------------! - soil(s)%thcond0 = (1. - soil(s)%slmsts ) & - * ( ksand * soil(s)%xsand * sand_thcond & - + ksilt * soil(s)%xsilt * silt_thcond & - + kclay * soil(s)%xclay * clay_thcond ) & - + soil(s)%slmsts * kair * air_thcond - soil(s)%thcond1 = h2o_thcond - kair * air_thcond - soil(s)%thcond2 = (1. - soil(s)%slmsts ) & - * ( ksand * soil(s)%xsand + ksilt * soil(s)%xsilt & - + kclay * soil(s)%xclay ) & - + soil(s)%slmsts * kair - soil(s)%thcond3 = 1. - kair - !------------------------------------------------------------------------------------! - - end do - !---------------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------------! ! Fill in the albedo information regarding the soil colour classes. ! @@ -2335,52 +1689,6 @@ subroutine init_soil_coms - !----- Here we fill soil8, which will be used in Runge-Kutta (double precision). -------! - do s=1,ed_nstyp - soil8(s)%key = soil(s)%key - soil8(s)%method = soil(s)%method - soil8(s)%xsand = dble(soil(s)%xsand ) - soil8(s)%xsilt = dble(soil(s)%xsilt ) - soil8(s)%xclay = dble(soil(s)%xclay ) - soil8(s)%slsoc = dble(soil(s)%slsoc ) - soil8(s)%slph = dble(soil(s)%slph ) - soil8(s)%slcec = dble(soil(s)%slcec ) - soil8(s)%sldbd = dble(soil(s)%sldbd ) - soil8(s)%soilre = dble(soil(s)%soilre ) - soil8(s)%soilcp = dble(soil(s)%soilcp ) - soil8(s)%soilwp = dble(soil(s)%soilwp ) - soil8(s)%soilfr = dble(soil(s)%soilfr ) - soil8(s)%soilld = dble(soil(s)%soilld ) - soil8(s)%sfldcap = dble(soil(s)%sfldcap ) - soil8(s)%soilbp = dble(soil(s)%soilbp ) - soil8(s)%slmsts = dble(soil(s)%slmsts ) - soil8(s)%soilpo = dble(soil(s)%soilpo ) - soil8(s)%slpotcp = dble(soil(s)%slpotcp ) - soil8(s)%slpotwp = dble(soil(s)%slpotwp ) - soil8(s)%slpotfr = dble(soil(s)%slpotfr ) - soil8(s)%slpotld = dble(soil(s)%slpotld ) - soil8(s)%slpotfc = dble(soil(s)%slpotfc ) - soil8(s)%slpotbp = dble(soil(s)%slpotbp ) - soil8(s)%slpots = dble(soil(s)%slpots ) - soil8(s)%slpotpo = dble(soil(s)%slpotpo ) - soil8(s)%sltt = dble(soil(s)%sltt ) - soil8(s)%slnm = dble(soil(s)%slnm ) - soil8(s)%slbs = dble(soil(s)%slbs ) - soil8(s)%slmm = dble(soil(s)%slmm ) - soil8(s)%slmu = dble(soil(s)%slmu ) - soil8(s)%malpha = dble(soil(s)%malpha ) - soil8(s)%slcons = dble(soil(s)%slcons ) - soil8(s)%fhydraul = dble(soil(s)%fhydraul) - soil8(s)%slcpd = dble(soil(s)%slcpd ) - soil8(s)%thcond0 = dble(soil(s)%thcond0 ) - soil8(s)%thcond1 = dble(soil(s)%thcond1 ) - soil8(s)%thcond2 = dble(soil(s)%thcond2 ) - soil8(s)%thcond3 = dble(soil(s)%thcond3 ) - end do - !---------------------------------------------------------------------------------------! - - - !----- Double precision of additional scalar variables. --------------------------------! soil_rough8 = dble(soil_rough ) snow_rough8 = dble(snow_rough ) @@ -2401,70 +1709,6 @@ subroutine init_soil_coms sin_sldrain8 = sin(sldrain8 * pio1808) !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Decide whether to write the table with the soil properties. ! - !---------------------------------------------------------------------------------------! - print_soil_table = btest(idetailed,5) - !---------------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------------! - ! Print the parameters in case the user wants it. ! - !---------------------------------------------------------------------------------------! - if (print_soil_table) then - !----- Open and write header. -------------------------------------------------------! - open (unit=26,file=trim(soil_table_fn),status='replace',action='write') - write(unit=26,fmt='(38(a,1x))') 'ISOIL', ' KEY', 'TYPE' & - ,' XSAND',' XSILT',' XCLAY' & - ,' SLSOC',' SLPH',' SLCEC' & - ,' SLDBD',' SOILRE',' SOILCP' & - ,' SOILWP',' SOILFR',' SOILLD' & - ,' SOILFC',' SOILBP',' SOILPO' & - ,' SLPOTCP',' SLPOTWP',' SLPOTFR' & - ,' SLPOTLD',' SLPOTFC',' SLPOTBP' & - ,' SLPOTPO',' SLTT',' SLNM' & - ,' SLBS',' SLMM',' SLMU' & - ,' MALPHA',' SLCONS_MMHR',' FHYDRAUL' & - ,' SLCPD_MJm3K',' THCOND0',' THCOND1' & - ,' THCOND2',' THCOND3' - !------------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------------! - ! Loop over soil texture types. ! - !------------------------------------------------------------------------------------! - do s=1,ed_nstyp - !----- For some variables, we use different units to make them more legible. -----! - slcons_mmhr = soil(s)%slcons*1000.*hr_sec - slcpd_mjm3k = soil(s)%slcpd*0.001 - !---------------------------------------------------------------------------------! - - !----- Add soil characteristics. -------------------------------------------------! - write(unit=26,fmt='(i5,1x,2(a4,1x),35(f12.5,1x))') & - s,adjustr(soil(s)%key),adjustr(soil(s)%method) & - ,soil(s)%xsand ,soil(s)%xsilt ,soil(s)%xclay & - ,soil(s)%slsoc ,soil(s)%slph ,soil(s)%slcec & - ,soil(s)%sldbd ,soil(s)%soilre ,soil(s)%soilcp & - ,soil(s)%soilwp ,soil(s)%soilfr ,soil(s)%soilld & - ,soil(s)%sfldcap ,soil(s)%soilbp ,soil(s)%slmsts & - ,soil(s)%slpotcp ,soil(s)%slpotwp ,soil(s)%slpotfr & - ,soil(s)%slpotld ,soil(s)%slpotfc ,soil(s)%slpotbp & - ,soil(s)%slpots ,soil(s)%sltt ,soil(s)%slnm & - ,soil(s)%slbs ,soil(s)%slmm ,soil(s)%slmu & - ,soil(s)%malpha ,slcons_mmhr ,soil(s)%fhydraul & - ,slcpd_mjm3k ,soil(s)%thcond0 ,soil(s)%thcond1 & - ,soil(s)%thcond2 ,soil(s)%thcond3 - !---------------------------------------------------------------------------------! - end do - !------------------------------------------------------------------------------------! - - - !----- Close table. -----------------------------------------------------------------! - close(unit=26,status='keep') - !------------------------------------------------------------------------------------! - end if - !---------------------------------------------------------------------------------------! - return end subroutine init_soil_coms !==========================================================================================! @@ -2483,6 +1727,7 @@ subroutine init_phen_coms use phenology_coms, only : thetacrit & ! intent(in) , retained_carbon_fraction & ! intent(out) , root_phen_factor & ! intent(out) + , f_psi_xdry & ! intent(out) , elongf_min & ! intent(out) , elongf_flush & ! intent(out) , spot_phen & ! intent(out) @@ -2536,6 +1781,14 @@ subroutine init_phen_coms + !---------------------------------------------------------------------------------------! + ! Threshold for shedding all leaves when leaf water potential is very low. . ! + !---------------------------------------------------------------------------------------! + f_psi_xdry = 0.95 + !---------------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------------! ! Minimum elongation factor before plants give up completely and shed all remain- ! ! ing leaves. ! @@ -3016,13 +2269,13 @@ subroutine init_pft_alloc_params() real, dimension(3) , parameter :: nleaf = (/ 0.0192512, 0.9749494, 2.5858509 /) real, dimension(2) , parameter :: ncrown_area = (/ 0.1184295, 1.0521197 /) !---------------------------------------------------------------------------------------! - ! Coefficients for leaf and structural biomass (iallom = 3). For adult individuals, ! - ! we use the pantropical allometric equation from C14 that estimates AGB and the leaf ! - ! biomass from an allometric equation derived from F15 data (tropical forest, wild ! - ! flowering trees only), and the size- and site-dependent stratified sampling and ! - ! aggregation (J17). Total individual leaf area was fitted, so to get biomass we must ! - ! divide by SLA. The C2B term is added here but is removed when the coefficients are ! - ! set. ! + ! Coefficients for leaf and structural biomass (iallom = 3 or 5). For adult ! + ! individuals, we use the pantropical allometric equation from C14 that estimates AGB ! + ! and the leaf biomass from an allometric equation derived from F15 data (tropical ! + ! forest, wild flowering trees only), and the size- and site-dependent stratified ! + ! sampling and aggregation (J17). Total individual leaf area was fitted, so to get ! + ! biomass we must divide by SLA. The C2B term is added here but is removed when the ! + ! coefficients are set. ! ! ! ! References: ! ! ! @@ -3033,7 +2286,7 @@ subroutine init_pft_alloc_params() ! ! ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, Aiba M, ! ! Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and allometry database for ! - ! woody plants. Ecology, 96 (5):1445-1445. doi:10.1890/14-1889.1 (F16). ! + ! woody plants. Ecology, 96 (5):1445-1445. doi:10.1890/14-1889.1 (F15). ! ! ! ! Jucker T, Caspersen J, Chave J, Antin C, Barbier N, Bongers F, Dalponte M, ! ! van Ewijk KY, Forrester DI, Haeni M et al. 2017. Allometric equations for ! @@ -3041,7 +2294,7 @@ subroutine init_pft_alloc_params() ! Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). ! ! ! !---------------------------------------------------------------------------------------! - real, dimension(2) , parameter :: c14f15_bl_xx = (/ 0.46769540,0.6410495 /) + real, dimension(2) , parameter :: c14f15_bl_xx = (/ 0.23384770,0.6410495 /) real, dimension(3) , parameter :: c14f15_la_wd = (/-0.5874,0.5679,0.5476 /) real, dimension(3) , parameter :: c14f15_ht_xx = (/0.5709,-0.1007,0.6734 /) real, dimension(2) , parameter :: c14f15_bs_tf = (/ 0.06080334,1.0044785 /) @@ -3315,9 +2568,10 @@ subroutine init_pft_alloc_params() !---------------------------------------------------------------------------------------! ! KIM: ED1/ED2 codes and Moorcroft et al. had the incorrect ratio. ! - ! MLO: The ratio is corrected only for tropical PFTs using iallom=3. To extend this ! - ! fix to other PFTs, one must refit parameters for other tissues (e.g. bdead), ! - ! so the total AGB is consistent with the original allometric equation for AGB. ! + ! MLO: The ratio is corrected only for tropical PFTs using iallom = 3 or 5. To ! + ! extend this fix to other PFTs, one must refit parameters for other tissues ! + ! (e.g. bdead), so the total AGB is consistent with the original allometric ! + ! equation for AGB. ! ! ! ! For the PFTs that were updated, we combine the pipe model with the data from ! ! CA08 and shape parameter from F16 to derive the ratio. ! @@ -3354,7 +2608,7 @@ subroutine init_pft_alloc_params() ! ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3) + case (3,5) do ipft=1,n_pft if (is_liana(ipft)) then !------------------------------------------------------------------------------! @@ -3467,12 +2721,18 @@ subroutine init_pft_alloc_params() ! ! ! The root fraction (Y) above depth D cm for a cohort with max rooting depth as ! ! D_max (cm) can be calculated as: ! - ! Y = 1. - (root_beta) ** (D / D_max) ! ! ! - ! Suggested values range from 0.0001 to 0.01. ! + ! Y = ( 1. - (root_beta) ** (D / D_max) ) / (1 - root_beta) ! + ! ! + ! ! + ! MLO (2020-10-27): I added the denominator (1 - root_beta) to ensure that Y at ! + ! D=D_max is always 1, regardless of the value of root_beta, as ! + ! long as root_beta < 1. ! + ! ! + ! Suggested values range from 0.0001 to 0.1. ! ! ! !---------------------------------------------------------------------------------------! - root_beta(:) = 0.01 + root_beta(:) = 0.1 !---------------------------------------------------------------------------------------! @@ -3500,8 +2760,8 @@ subroutine init_pft_alloc_params() !---------------------------------------------------------------------------------------! ! Set bark thickness and carbon allocation to bark. This is currently done only ! - ! for tropical trees when IALLOM=3, because all biomass pools must be corrected to ! - ! ensure that total aboveground biomass is consistent with the allometric equations. ! + ! for tropical trees when IALLOM = 3 or 5, because all biomass pools must be corrected ! + ! to ensure that total aboveground biomass is consistent with the allometric equations. ! ! This may and should be changed in the future. ! ! ! ! References: ! @@ -3531,7 +2791,7 @@ subroutine init_pft_alloc_params() ! qbark - ratio between leaf biomass and bark biomass per unit height. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3) + case (3,5) !------ New allometry, use estimate based on M01. -----------------------------------! b1Xs(:) = 0.315769481 !------------------------------------------------------------------------------------! @@ -3626,17 +2886,17 @@ subroutine init_pft_alloc_params() !----- hgt_ref is their "Hmax". -----------------------------------------------! hgt_ref(ipft) = 61.7 !------------------------------------------------------------------------------! - case (3) + case (3,5) !------------------------------------------------------------------------------! ! Allometric equation based on the fitted curve using the Sustainable ! ! Landscapes data set (L16) and the size- and site-dependent stratified ! - ! sampling and aggregation (J17). This relationship is fitted using ! - ! Standardised Major Axis (SMA) so the same parameters can be used for ! - ! y=f(x) and x=f(y). This is particularly useful when initialising the model ! - ! with airborne lidar data. Because it would be extremely cumbersome to ! - ! derive a SMA-based regression based on Weibull function, we use a log-linear ! - ! relationship. The maximum height is based on the 99% quantile of all trees ! - ! measured by the SL team. ! + ! sampling and aggregation (J17), as described in (L20). This relationship is ! + ! fitted using Standardised Major Axis (SMA) so the same parameters can be ! + ! used for y=f(x) and x=f(y). This is particularly useful when initialising ! + ! the model with airborne lidar data (L20). Because it would be extremely ! + ! cumbersome to derive a SMA-based regression based on Weibull function, we ! + ! use a log-linear relationship. The maximum height is based on the 99% ! + ! quantile of all trees measured by the SL team. ! ! ! ! References: ! ! ! @@ -3650,6 +2910,11 @@ subroutine init_pft_alloc_params() ! biomass variability across intact and degraded forests in the Brazilian ! ! Amazon. Global Biogeochem. Cycles, 30(11):1639-1660. ! ! doi:10.1002/2016GB005465 (L16). ! + ! ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! !------------------------------------------------------------------------------! b1Ht (ipft) = 1.139963 b2Ht (ipft) = 0.564899 @@ -3717,7 +2982,7 @@ subroutine init_pft_alloc_params() ! Minimum and maximum height allowed for each cohort. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------------! ! This value corresponds to the 99% quantile of all trees measured by the ! ! Sustainable Landscapes. ! @@ -3812,13 +3077,15 @@ subroutine init_pft_alloc_params() b1Ca(ipft) = exp(ncrown_area(1)) b2Ca(ipft) = ncrown_area(2) !------------------------------------------------------------------------------! - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------! ! Allometry using the Sustainable Landscapes data. ! !------------------------------------------------------------------------------! ! ! - ! Longo, M. et al. Carbon Debt and Recovery time of degraded forests in ! - ! the Amazon. Environ. Res. Lett., in prep. ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! ! ! ! Equation was derived from forest inventory measurements carried out at ! ! multiple locations in the Brazilian Amazon, and fitted using a ! @@ -3861,11 +3128,13 @@ subroutine init_pft_alloc_params() ! Poorter L., L. Bongers, F. Bongers, 2006: Architecture of 54 moist-forest tree ! ! species: traits, trade-offs, and functional groups. Ecology, 87, 1289-1301. ! ! ! - ! For iallom = 3, we use the allometric equation based on the Sustainable Landscapes ! - ! data set. ! + ! For iallom = 3 or 5, we use the allometric equation based on the Sustainable ! + ! Landscapes data set. ! ! ! - ! Longo, M. et al. Carbon Debt and Recovery time of degraded forests in the Amazon, ! - ! in prep. ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, Bonal D, ! + ! Brando P, Burban B et al. 2020. Impacts of degradation on water, energy, and ! + ! carbon cycling of the Amazon tropical forests. J. Geophys. Res.-Biogeosci., 125: ! + ! e2020JG005677. doi:10.1029/2020JG005677 (L20). ! ! ! ! Equation was derived from forest inventory measurements carried out at multiple ! ! locations in the Brazilian Amazon, and fitted using a heteroscedastic least ! @@ -3885,7 +3154,7 @@ subroutine init_pft_alloc_params() elseif (is_tropical(ipft)) then !----- Tropical PFTs: check allometry settings. ----------------------------------! select case (iallom) - case (3,4) + case (3,4,5) b1Cl(ipft) = 0.29754 b2Cl(ipft) = 1.0324 case default @@ -3913,9 +3182,9 @@ subroutine init_pft_alloc_params() ! Parameters for DBH -> Bleaf allometry. ! ! ! ! IALLOM = 0,1,2 -- Bleaf = b1Bl * DBH^b2Bl ! - ! IALLOM = 3 -- Bleaf = b1Bl * (DBH*DBH*Height)^b2Bl ! - ! IALLOM = 4 -- leaf_A= b1Bl * (DBH*DBH*Height)^b2Bl ! - ! b1Bl is a fucntion of wood density ! + ! IALLOM = 3,4,5 -- leaf_A= b1Bl * (DBH*DBH*Height)^b2Bl ! + ! b1Bl is a function of wood density (IALLOM=4 only). ! + ! For IALLOM=3,4,5, leaf biomass will depend on SLA. ! ! ! ! The coefficients and thresholds depend on the PFT and allometric equations. In ! ! addition to the coefficients, we define the dbh point that defines adult cohorts as ! @@ -3955,33 +3224,43 @@ subroutine init_pft_alloc_params() b1Bl (ipft) = C2B * exp(nleaf(1)) * rho(ipft) / nleaf(3) b2Bl (ipft) = nleaf(2) !------------------------------------------------------------------------------! - case (3) + case (3,5) !------------------------------------------------------------------------------! - ! Allometry based on the BAAD data based (F15). We only used leaves from ! - ! wild tropical, flowering trees, and applied a stratified sample by DBH class ! - ! and location and cross-validation, following (J17). ! + ! Allometry based on the BAAD data based (F15) and described in (L20). We ! + ! only used leaves from wild tropical, flowering trees, and applied a ! + ! stratified sample by DBH class and location and cross-validation, following ! + ! (J17). ! ! ! ! References: ! ! ! + ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, ! + ! Aiba M, Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and ! + ! allometry database for woody plants. Ecology, 96 (5):1445-1445. ! + ! doi:10.1890/14-1889.1 (F15). ! + ! ! ! Jucker T, Caspersen J, Chave J, Antin C, Barbier N, Bongers F, Dalponte M, ! ! van Ewijk KY, Forrester DI, Haeni M et al. 2017. Allometric equations for ! ! integrating remote sensing imagery into forest monitoring programmes. ! ! Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). ! ! ! - ! Longo M, Keller M, dos-Santos MN, Leitold V, Pinage ER, Baccini A, ! - ! Saatchi S, Nogueira EM, Batistella M , Morton DC. 2016. Aboveground ! - ! biomass variability across intact and degraded forests in the Brazilian ! - ! Amazon. Global Biogeochem. Cycles, 30(11):1639-1660. ! - ! doi:10.1002/2016GB005465 (L16). ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! !------------------------------------------------------------------------------! - b1Bl(ipft) = c14f15_bl_xx(1) / SLA(ipft) ! XX --> MLO: should ther be a C2B here given c14f15_bl_xx is in m2 (?) and SLA is m2/kgC + b1Bl(ipft) = c14f15_bl_xx(1) b2Bl(ipft) = c14f15_bl_xx(2) !------------------------------------------------------------------------------! case (4) !------------------------------------------------------------------------------! ! Allometry based on the BAAD data based (F15). We only used leaves from ! ! wild tropical, note that b1Bl has the unit of m2 leaf under this scenario ! - ! and will be converted to leaf carbon using SLA in size2bl + ! and will be converted to leaf carbon using SLA in size2bl. ! + ! ! + ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, ! + ! Aiba M, Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and ! + ! allometry database for woody plants. Ecology, 96 (5):1445-1445. ! + ! doi:10.1890/14-1889.1 (F15). ! !------------------------------------------------------------------------------! b1Bl(ipft) = exp( c14f15_la_wd(1) + c14f15_la_wd(2) * log(rho(ipft))) b2Bl(ipft) = c14f15_la_wd(3) @@ -4034,7 +3313,7 @@ subroutine init_pft_alloc_params() ! Bdead = { ! ! { b1Bs_large * DBH^b2Bl_large , if dbh > dbh_crit ! ! ! - ! IALLOM = 3, 4 ! + ! IALLOM = 3, 4, 5 ! ! ! ! Bdead = b1Bs_small * (DBH^2 * Height) ^ b2Bs_small ! ! ! @@ -4097,7 +3376,7 @@ subroutine init_pft_alloc_params() b1Bs_large (ipft) = C2B * exp(ndead_large(1)) * rho(ipft) / ndead_large(3) b2Bs_large (ipft) = ndead_large(2) !------------------------------------------------------------------------------! - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------! ! Trees: set parameters based on Chave et al. (2014). ! ! Grasses: set numbers to small values, too keep bdead at a minimum but still ! @@ -4238,7 +3517,7 @@ subroutine init_pft_alloc_params() ! WAI parameters, the choice depends on IALLOM. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------------! ! WAI is defined as a fraction of (potential) LAI. This is just a refit of ! ! allometry 2 but using DBH*DBH*Height as predictor for consistency. ! @@ -4393,7 +3672,7 @@ subroutine init_pft_alloc_params() , +0.4223014 & , is_tropical(:) .and. (.not. is_liana(:)) ) !------------------------------------------------------------------------------------! - case (4) + case (4,5) !------------------------------------------------------------------------------------! ! Test allometry based on excavation data in Panama based on H. ! ! Multiply it by 2 so that a 40 m tree can get access to water below 5m depth ! @@ -4423,11 +3702,6 @@ subroutine init_pft_alloc_params() ! Hydrological niche segregation defines forest structure and drought tolerance ! ! strategies in a seasonal Amazonian forest. J. Ecol., in press. ! ! doi:10.1111/1365-2745.13022 (B18). ! - ! ! - ! Longo M, Keller M, dos-Santos MN, Leitold V, Pinage ER, Baccini A, Saatchi S, ! - ! Nogueira EM, Batistella M , Morton DC. 2016. Aboveground biomass variability ! - ! across intact and degraded forests in the Brazilian Amazon. Global Biogeochem. ! - ! Cycles, 30(11):1639-1660. doi:10.1002/2016GB005465 (L16). ! !---------------------------------------------------------------------------------------! d18O_ref(:) = -5.356 b1d18O (:) = 0.0516 @@ -4716,12 +3990,35 @@ subroutine init_pft_photo_params() !---------------------------------------------------------------------------------------! select case (iphysiol) case (0,2) - !----- Default parameters (Moorcroft et al. 2001; Longo 2014). ----------------------! + !------------------------------------------------------------------------------------! + ! Default parameters (M01/M09/L19). ! + ! ! + ! Longo M, Knox RG, Medvigy DM, Levine NM, Dietze MC, Kim Y, Swann ALS, Zhang K, ! + ! Rollinson CR, Bras RL et al. 2019. The biophysics, ecology, and biogeochemistry ! + ! of functionally diverse, vertically and horizontally heterogeneous ecosystems: ! + ! the Ecosystem Demography model, version 2.2 -- part 1: Model description. ! + ! Geosci. Model Dev., 12: 4309-4346. doi:10.5194/gmd-12-4309-2019 (L19). ! + ! ! + ! Medvigy DM, Wofsy SC, Munger JW, Hollinger DY , Moorcroft PR. 2009. Mechanistic ! + ! scaling of ecosystem function and dynamics in space and time: Ecosystem ! + ! demography model version 2. J. Geophys. Res.-Biogeosci., 114: G01002. ! + ! doi:10.1029/2008JG000812 (M09). ! + ! ! + ! Moorcroft PR, Hurtt GC , Pacala SW. 2001. A method for scaling vegetation ! + ! dynamics: The Ecosystem Demography model (ED). Ecol. Monogr., 71: 557-586. ! + ! doi:10.1890/0012- 9615(2001)071[0557:AMFSVD]2.0.CO;2 (M01). ! + !------------------------------------------------------------------------------------! vm_hor(:) = 3000. vm_q10(:) = merge(q10_c4,q10_c3,photosyn_pathway(:) == 4) !------------------------------------------------------------------------------------! case (1,3) - !----- Use values from von Caemmerer (2000). ----------------------------------------! + !------------------------------------------------------------------------------------! + ! Use values from vC00. ! + ! ! + ! von Caemmerer S. 2000. Biochemical models of leaf photosynthesis. No. 2 in ! + ! Techniques in Plant Sciences. CSIRO Publishing, Collingwood, VIC, Australia. ! + ! doi:10.1006/anbo.2000.1296 (vC00). ! + !------------------------------------------------------------------------------------! vm_hor(:) = 58520. * tphysref / (rmol * (t00+25.)) vm_q10(:) = 2.21 !------------------------------------------------------------------------------------! @@ -5218,7 +4515,7 @@ subroutine init_pft_resp_params() ! names already in use in c2n factors. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (2,3,4) + case (2,3,4,5) !------------------------------------------------------------------------------------! ! For tropical leaves/fine roots, assume the metabolic/structural ratio obtained ! ! by B17. For grasses and temperate plants, use B17 equation and R96 values for ! @@ -5342,10 +4639,6 @@ subroutine init_pft_mort_params() , fire_s_max & ! intent(out) , fire_s_inter & ! intent(out) , fire_s_slope & ! intent(out) - , felling_s_ltharv & ! intent(out) - , felling_s_gtharv & ! intent(out) - , skid_s_ltharv & ! intent(out) - , skid_s_gtharv & ! intent(out) , plant_min_temp & ! intent(out) , frost_mort ! ! intent(out) use consts_coms , only : t00 & ! intent(in) @@ -5356,9 +4649,6 @@ subroutine init_pft_mort_params() , economics_scheme ! ! intent(in) use disturb_coms, only : include_fire & ! intent(in) , time2canopy & ! intent(in) - , sl_skid_s_gtharv & ! intent(in) - , sl_skid_s_ltharv & ! intent(in) - , sl_felling_s_ltharv & ! intent(in) , treefall_disturbance_rate ! ! intent(in) use physiology_coms, only : carbon_mortality_scheme & ! intent(in) , hydraulic_mortality_scheme ! ! intent(in) @@ -5769,18 +5059,6 @@ subroutine init_pft_mort_params() - !---------------------------------------------------------------------------------------! - ! Felling survivorship fraction, and survivorship to collateral damage due to ! - ! logging. ! - !---------------------------------------------------------------------------------------! - felling_s_gtharv(:) = merge(0.70,0.00 ,is_grass(:)) - felling_s_ltharv(:) = merge(0.70,sl_felling_s_ltharv,is_grass(:)) - skid_s_gtharv (:) = merge(1.00,sl_skid_s_gtharv ,is_grass(:)) - skid_s_ltharv (:) = merge(1.00,sl_skid_s_ltharv ,is_grass(:)) - !---------------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------------! ! Fire survivorship fraction. These variables will be replaced by bark thickness ! ! !---------------------------------------------------------------------------------------! @@ -6569,6 +5847,12 @@ subroutine init_pft_phen_params() !------------------------------------------------------------------------------! phenology(ipft) = 5 !------------------------------------------------------------------------------! + case (5) + !------------------------------------------------------------------------------! + ! Combined light and plant-hydraulics driven drought phenology. ! + !------------------------------------------------------------------------------! + phenology(ipft) = 6 + !------------------------------------------------------------------------------! end select !---------------------------------------------------------------------------------! end if @@ -8186,10 +7470,6 @@ subroutine init_derived_params_after_xml() , mort3 & ! intent(in) , seedling_mortality & ! intent(in) , treefall_s_ltht & ! intent(in) - , felling_s_gtharv & ! intent(in) - , felling_s_ltharv & ! intent(in) - , skid_s_gtharv & ! intent(in) - , skid_s_ltharv & ! intent(in) , fire_s_min & ! intent(in) , fire_s_max & ! intent(in) , fire_s_inter & ! intent(in) @@ -8266,6 +7546,7 @@ subroutine init_derived_params_after_xml() , srf_hor & ! intent(inout) , srf_q10 & ! intent(inout) , bleaf_crit & ! intent(inout) + , ddh_allom & ! intent(out) , d1DBH_small & ! intent(out) , d2DBH_small & ! intent(out) , d1DBH_large & ! intent(out) @@ -8457,7 +7738,7 @@ subroutine init_derived_params_after_xml() !------ Make sure the soil carbon fractions add up to one. -----------------------------! if (f0_msc < 0. .or. f0_psc < 0.0 .or. (f0_msc + f0_psc) > 1.0) then write (unit=*,fmt='(a)') '-------------------------------------------------' - write (unit=*,fmt='(a)') ' F0_MSC and F0_SSC must be fractions (0-1)' + write (unit=*,fmt='(a)') ' F0_MSC and F0_PSC must be fractions (0-1)' write (unit=*,fmt='(a)') ' and their sum cannot exceed 1.0' write (unit=*,fmt='(a)') '' write (unit=*,fmt='(a)') ' Current values: ' @@ -8517,7 +7798,7 @@ subroutine init_derived_params_after_xml() ! both in case this simulation is not using light-controlled phenology. ! !---------------------------------------------------------------------------------------! select case (iphen_scheme) - case (3) + case (3,5) !------------------------------------------------------------------------------------! ! Light phenology is enabled. ! !------------------------------------------------------------------------------------! @@ -8594,7 +7875,7 @@ subroutine init_derived_params_after_xml() !---------------------------------------------------------------------------------------! ! Hgt_max of temperate trees cannot exceed b1Ht, and cannot exceed hgt_ref for ! - ! tropical trees (IALLOM=2 or IALLOM=3). ! + ! tropical trees (IALLOM = 2). ! !---------------------------------------------------------------------------------------! select case (iallom) case (2) @@ -8688,6 +7969,14 @@ subroutine init_derived_params_after_xml() !------------------------------------------------------------------------------------! + !----- Set allometric formula. ------------------------------------------------------! + select case (iallom) + case (3,4,5) + ddh_allom(ipft) = is_tropical(ipft) .and. (.not. is_liana(ipft)) + case default + ddh_allom(ipft) = .false. + end select + !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! @@ -8695,8 +7984,7 @@ subroutine init_derived_params_after_xml() ! the size2bd and size2bl functions, and to be consistent, they cannot be ! ! initialised through XML. ! !------------------------------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft)) ) then + if (ddh_allom(ipft)) then !---------------------------------------------------------------------------------! ! Incorporate both heartwood and height allometric equations to derive DBH. ! !---------------------------------------------------------------------------------! @@ -8713,7 +8001,7 @@ subroutine init_derived_params_after_xml() !------ Inverse of the leaf biomass function. ------------------------------------! l2DBH(ipft) = 1. / ( ( 2. + b2Ht(ipft) ) * b2Bl(ipft) ) - l1DBH(ipft) = ( C2B / (b1Bl(ipft) * exp(b1Ht(ipft) * b2Bl(ipft)) ) ) ** l2DBH(ipft) + l1DBH(ipft) = ( 1. / (b1Bl(ipft) * exp(b1Ht(ipft) * b2Bl(ipft)) ) ) ** l2DBH(ipft) !---------------------------------------------------------------------------------! else !---------------------------------------------------------------------------------! @@ -8802,7 +8090,7 @@ subroutine init_derived_params_after_xml() ! allometry sets define the minimum sizes as before, for back-compability. ! !------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !---------------------------------------------------------------------------------! ! New method, each PFT has a minimum resolvable density. The fraction ensures ! ! that plants start as resolvable. ! @@ -9698,41 +8986,43 @@ subroutine init_derived_params_after_xml() !----- Print allometric coefficients. --------------------------------------------------! if (print_zero_table) then open (unit=18,file=trim(allom_file),status='replace',action='write') - write(unit=18,fmt='(54(1x,a))') ' PFT',' TROPICAL',' GRASS' & + write(unit=18,fmt='(55(1x,a))') ' PFT',' TROPICAL',' GRASS' & ,' CONIFER',' SAVANNAH',' LIANA' & - ,' RHO',' B1HT',' B2HT' & - ,' HGT_REF',' B1BL',' B2BL' & - ,' B1BS_SMALL',' B2BS_SMALL',' B1BS_LARGE' & - ,' B2BS_LARGE',' D1DBH_SMALL',' D2DBH_SMALL' & - ,' D1DBH_LARGE',' D2DBH_LARGE',' L1DBH' & - ,' L2DBH',' B1CA',' B2CA' & - ,' B1WAI',' B2WAI',' B1SA' & - ,' B2SA',' B1RD',' B2RD' & - ,' B1XS',' B1XB',' HGT_MIN' & - ,' HGT_MAX',' MIN_DBH',' DBH_CRIT' & - ,' DBH_BIGLEAF',' BDEAD_CRIT',' BLEAF_CRIT' & - ,' BALIVE_CRIT',' BEVERY_CRIT',' INIT_DENS' & - ,' SLA',' F_BSTOR_INIT',' Q' & - ,' QSW',' QBARK',' QRHOB' & - ,' d18O_REF',' B1_D18O',' B2_D18O' & - ,' B1_EFRD',' B2_EFRD',' INIT_LAIMAX' - + ,' DDH_ALLOM',' RHO',' B1HT' & + ,' B2HT',' HGT_REF',' B1BL' & + ,' B2BL',' B1BS_SMALL',' B2BS_SMALL' & + ,' B1BS_LARGE',' B2BS_LARGE',' D1DBH_SMALL' & + ,' D2DBH_SMALL',' D1DBH_LARGE',' D2DBH_LARGE' & + ,' L1DBH',' L2DBH',' B1CA' & + ,' B2CA',' B1WAI',' B2WAI' & + ,' B1SA',' B2SA',' B1RD' & + ,' B2RD',' B1XS',' B1XB' & + ,' HGT_MIN',' HGT_MAX',' MIN_DBH' & + ,' DBH_CRIT',' DBH_BIGLEAF',' BDEAD_CRIT' & + ,' BLEAF_CRIT',' BALIVE_CRIT',' BEVERY_CRIT' & + ,' INIT_DENS',' SLA',' F_BSTOR_INIT' & + ,' Q',' QSW',' QBARK' & + ,' QRHOB',' d18O_REF',' B1_D18O' & + ,' B2_D18O',' B1_EFRD',' B2_EFRD' & + ,' INIT_LAIMAX' + do ipft=1,n_pft - write (unit=18,fmt='(9x,i5,5(13x,l1),47(1x,f13.6),1(1x,es13.6))') & + write (unit=18,fmt='(9x,i5,6(13x,l1),47(1x,f13.6),1(1x,es13.6))') & ipft,is_tropical(ipft),is_grass(ipft),is_conifer(ipft) & - ,is_savannah(ipft),is_liana(ipft),rho(ipft),b1Ht(ipft),b2Ht(ipft) & - ,hgt_ref(ipft),b1Bl(ipft),b2Bl(ipft),b1Bs_small(ipft) & - ,b2Bs_small(ipft),b1Bs_large(ipft),b2Bs_large(ipft) & - ,d1DBH_small(ipft),d2DBH_small(ipft),d1DBH_large(ipft) & - ,d2DBH_large(ipft),l1DBH(ipft),l2DBH(ipft),b1Ca(ipft),b2Ca(ipft) & - ,b1WAI(ipft),b2WAI(ipft),b1SA(ipft),b2SA(ipft),b1Rd(ipft) & - ,b2Rd(ipft),b1Xs(ipft),b1Xb(ipft),hgt_min(ipft),hgt_max(ipft) & - ,min_dbh(ipft),dbh_crit(ipft),dbh_bigleaf(ipft),bdead_crit(ipft) & - ,bleaf_crit(ipft),balive_crit(ipft),bevery_crit(ipft) & - ,init_density(ipft),sla(ipft),f_bstorage_init(ipft),q(ipft) & - ,qsw(ipft),qbark(ipft),qrhob(ipft),d18O_ref(ipft),b1d18O(ipft) & - ,b2d18O(ipft),b1Efrd(ipft),b2Efrd(ipft),init_laimax(ipft) + ,is_savannah(ipft),is_liana(ipft),ddh_allom(ipft),rho(ipft) & + ,b1Ht(ipft),b2Ht(ipft),hgt_ref(ipft),b1Bl(ipft),b2Bl(ipft) & + ,b1Bs_small(ipft),b2Bs_small(ipft),b1Bs_large(ipft) & + ,b2Bs_large(ipft),d1DBH_small(ipft),d2DBH_small(ipft) & + ,d1DBH_large(ipft),d2DBH_large(ipft),l1DBH(ipft),l2DBH(ipft) & + ,b1Ca(ipft),b2Ca(ipft),b1WAI(ipft),b2WAI(ipft),b1SA(ipft) & + ,b2SA(ipft),b1Rd(ipft),b2Rd(ipft),b1Xs(ipft),b1Xb(ipft) & + ,hgt_min(ipft),hgt_max(ipft),min_dbh(ipft),dbh_crit(ipft) & + ,dbh_bigleaf(ipft),bdead_crit(ipft),bleaf_crit(ipft) & + ,balive_crit(ipft),bevery_crit(ipft),init_density(ipft),sla(ipft) & + ,f_bstorage_init(ipft),q(ipft),qsw(ipft),qbark(ipft),qrhob(ipft) & + ,d18O_ref(ipft),b1d18O(ipft),b2d18O(ipft),b1Efrd(ipft),b2Efrd(ipft) & + ,init_laimax(ipft) end do close(unit=18,status='keep') end if @@ -9741,7 +9031,7 @@ subroutine init_derived_params_after_xml() !----- Print trait coefficients. -------------------------------------------------------! if (print_zero_table) then open (unit=19,file=trim(strat_file),status='replace',action='write') - write(unit=19,fmt='(102(1x,a))') ' PFT',' TROPICAL',' GRASS' & + write(unit=19,fmt='( 98(1x,a))') ' PFT',' TROPICAL',' GRASS' & ,' CONIFER',' SAVANNAH',' LIANA' & ,' R_BANG',' RHO',' SLA' & ,' SRA',' ROOT_BETA',' VM0' & @@ -9749,8 +9039,7 @@ subroutine init_derived_params_after_xml() ,' ROOT_TOR',' BARK_TOR',' STORAGE_TOR' & ,' FLABILE_LEAF',' FLABILE_STEM',' MORT0' & ,' MORT1',' MORT2',' MORT3' & - ,' SEED_MORT',' TFALL_S_GTHT',' FELL_S_GTHV' & - ,' FELL_S_LTHV',' SKID_S_GTHV',' SKID_S_LTHV' & + ,' SEED_MORT',' TFALL_S_GTHT' & ,' FIRE_S_MIN',' FIRE_S_MAX',' FIRE_S_INTER' & ,' FIRE_S_SLOPE',' ST_FRACT',' R_FRACT' & ,' R_CV50',' NONLOC_DISP',' SEED_RAIN' & @@ -9777,7 +9066,7 @@ subroutine init_derived_params_after_xml() ,' STOMA_PSI_C',' HIGH_PSI_THR',' LOW_PSI_THR' do ipft=1,n_pft - write (unit=19,fmt='(9x,i5,6(13x,l1),93(1x,f13.6),2(1x,i13))') & + write (unit=19,fmt='(9x,i5,6(13x,l1),89(1x,f13.6),2(1x,i13))') & ipft,is_tropical(ipft),is_grass(ipft),is_conifer(ipft) & ,is_savannah(ipft),is_liana(ipft),r_bang(ipft),rho(ipft),SLA(ipft) & ,SRA(ipft),root_beta(ipft),Vm0(ipft),dark_respiration_factor(ipft) & @@ -9786,8 +9075,7 @@ subroutine init_derived_params_after_xml() ,storage_turnover_rate(ipft),f_labile_leaf(ipft) & ,f_labile_stem(ipft),mort0(ipft),mort1(ipft),mort2(ipft) & ,mort3(ipft),seedling_mortality(ipft),treefall_s_ltht(ipft) & - ,felling_s_gtharv(ipft),felling_s_ltharv(ipft),skid_s_gtharv(ipft) & - ,skid_s_ltharv(ipft),fire_s_min(ipft),fire_s_max(ipft) & + ,fire_s_min(ipft),fire_s_max(ipft) & ,fire_s_inter(ipft),fire_s_slope(ipft),st_fract(ipft),r_fract(ipft) & ,r_cv50(ipft),nonlocal_dispersal(ipft),seed_rain(ipft) & ,effarea_heat,effarea_evap,effarea_transp(ipft) & diff --git a/ED/src/init/ed_type_init.f90 b/ED/src/init/ed_type_init.f90 index 456c93fd4..91822fa17 100644 --- a/ED/src/init/ed_type_init.f90 +++ b/ED/src/init/ed_type_init.f90 @@ -19,7 +19,8 @@ module ed_type_init !---------------------------------------------------------------------------------------! subroutine init_ed_cohort_vars(cpatch,ico, lsl,mzg,ntext_soil) use ed_state_vars , only : patchtype ! ! structure - use allometry , only : size2krdepth ! ! function + use allometry , only : size2krdepth & ! function + , distrib_root ! ! sub-routine use pft_coms , only : phenology & ! intent(in) , cuticular_cond & ! intent(in) , leaf_turnover_rate & ! intent(in) @@ -201,6 +202,12 @@ subroutine init_ed_cohort_vars(cpatch,ico, lsl,mzg,ntext_soil) !------------------------------------------------------------------------------------! + + !------ Find the root distribution. -------------------------------------------------! + call distrib_root(kroot,ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Start variables related with plant hydraulics. ! !------------------------------------------------------------------------------------! @@ -1128,6 +1135,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%fmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%fmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%fmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%fmean_snowfac (ipaa:ipaz) = 0.0 csite%fmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%fmean_par_gnd (ipaa:ipaz) = 0.0 csite%fmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1210,6 +1218,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%dmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%dmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%dmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%dmean_snowfac (ipaa:ipaz) = 0.0 csite%dmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%dmean_par_gnd (ipaa:ipaz) = 0.0 csite%dmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1286,6 +1295,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%mmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%mmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%mmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%mmean_snowfac (ipaa:ipaz) = 0.0 csite%mmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%mmean_par_gnd (ipaa:ipaz) = 0.0 csite%mmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1409,6 +1419,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%qmean_sfcw_mass (:,ipaa:ipaz) = 0.0 csite%qmean_sfcw_temp (:,ipaa:ipaz) = 0.0 csite%qmean_sfcw_fliq (:,ipaa:ipaz) = 0.0 + csite%qmean_snowfac (:,ipaa:ipaz) = 0.0 csite%qmean_rshort_gnd (:,ipaa:ipaz) = 0.0 csite%qmean_par_gnd (:,ipaa:ipaz) = 0.0 csite%qmean_rlong_gnd (:,ipaa:ipaz) = 0.0 @@ -1522,6 +1533,7 @@ subroutine init_ed_site_vars(cpoly) , writing_eorq & ! intent(in) , writing_dcyc & ! intent(in) , economics_scheme ! ! intent(in) + use consts_coms , only : huge_num ! ! intent(in) implicit none !----- Arguments. -------------------------------------------------------------------! type(polygontype), target :: cpoly @@ -1674,7 +1686,7 @@ subroutine init_ed_site_vars(cpoly) ! Initialise the minimum monthly temperature with a very large value, this is ! ! going to be reduced as the canopy temperature is updated. ! !------------------------------------------------------------------------------------! - cpoly%min_monthly_temp(:) = huge(1.) + cpoly%min_monthly_temp(:) = huge_num !------------------------------------------------------------------------------------! @@ -1684,7 +1696,7 @@ subroutine init_ed_site_vars(cpoly) ! by actual rainfall after 12 months. In the future we may initialise with climato- ! ! logical rainfall. ! !------------------------------------------------------------------------------------! - cpoly%avg_monthly_pcpg(:,:) = 500. + cpoly%avg_monthly_accp(:,:) = 500. !------------------------------------------------------------------------------------! @@ -2084,6 +2096,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%fmean_sfcw_mass (ipy) = 0.0 cgrid%fmean_sfcw_temp (ipy) = 0.0 cgrid%fmean_sfcw_fliq (ipy) = 0.0 + cgrid%fmean_snowfac (ipy) = 0.0 cgrid%fmean_rshort_gnd (ipy) = 0.0 cgrid%fmean_par_gnd (ipy) = 0.0 cgrid%fmean_rlong_gnd (ipy) = 0.0 @@ -2257,6 +2270,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = 0.0 cgrid%dmean_sfcw_temp (ipy) = 0.0 cgrid%dmean_sfcw_fliq (ipy) = 0.0 + cgrid%dmean_snowfac (ipy) = 0.0 cgrid%dmean_rshort_gnd (ipy) = 0.0 cgrid%dmean_par_gnd (ipy) = 0.0 cgrid%dmean_rlong_gnd (ipy) = 0.0 @@ -2414,6 +2428,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = 0.0 cgrid%mmean_sfcw_temp (ipy) = 0.0 cgrid%mmean_sfcw_fliq (ipy) = 0.0 + cgrid%mmean_snowfac (ipy) = 0.0 cgrid%mmean_rshort_gnd (ipy) = 0.0 cgrid%mmean_par_gnd (ipy) = 0.0 cgrid%mmean_rlong_gnd (ipy) = 0.0 @@ -2656,6 +2671,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%qmean_sfcw_mass (:,ipy) = 0.0 cgrid%qmean_sfcw_temp (:,ipy) = 0.0 cgrid%qmean_sfcw_fliq (:,ipy) = 0.0 + cgrid%qmean_snowfac (:,ipy) = 0.0 cgrid%qmean_rshort_gnd (:,ipy) = 0.0 cgrid%qmean_par_gnd (:,ipy) = 0.0 cgrid%qmean_rlong_gnd (:,ipy) = 0.0 diff --git a/ED/src/init/landuse_init.f90 b/ED/src/init/landuse_init.f90 index 77de83090..60da8a5ba 100644 --- a/ED/src/init/landuse_init.f90 +++ b/ED/src/init/landuse_init.f90 @@ -8,31 +8,41 @@ module landuse_init !---------------------------------------------------------------------------------------! subroutine read_landuse_matrix - use ed_state_vars , only : edtype & ! structure - , polygontype & ! structure - , sitetype & ! structure - , edgrid_g ! ! structure - use consts_coms , only : erad & ! intent(in) - , pio180 ! ! intent(in) - use disturb_coms , only : lutime & ! intent(in) - , max_lu_years & ! intent(in) - , num_lu_trans & ! intent(in) - , ianth_disturb & ! intent(in) - , lu_database & ! intent(in) - , sl_pft & ! intent(in) - , sl_scale & ! intent(in) - , sl_nyrs & ! intent(in) - , sl_yr_first & ! intent(in) - , sl_mindbh_harvest & ! intent(in) - , sl_prob_harvest ! ! intent(in) - use ed_misc_coms , only : iyeara & ! intent(in) - , iyearz ! ! intent(in) - use grid_coms , only : ngrids ! ! intent(in) - use ed_max_dims , only : str_len & ! intent(in) - , huge_lu & ! intent(in) - , n_pft & ! intent(in) - , maxlist ! ! intent(in) - use detailed_coms , only : idetailed ! ! intent(in) + use ed_state_vars , only : edtype & ! structure + , polygontype & ! structure + , sitetype & ! structure + , edgrid_g ! ! structure + use pft_coms , only : is_grass & ! intent(in) + , is_liana ! ! intent(in) + use consts_coms , only : erad & ! intent(in) + , pio180 & ! intent(in) + , lnexp_max ! ! intent(in) + use disturb_coms , only : lutime & ! intent(in) + , max_lu_years & ! intent(in) + , num_lu_trans & ! intent(in) + , ianth_disturb & ! intent(in) + , lu_database & ! intent(in) + , sl_pft & ! intent(in) + , sl_scale & ! intent(in) + , sl_nyrs & ! intent(in) + , sl_yr_first & ! intent(in) + , sl_skid_rel_area & ! intent(in) + , sl_skid_dbh_thresh & ! intent(in) + , sl_skid_s_gtharv & ! intent(in) + , sl_skid_s_ltharv & ! intent(in) + , sl_felling_s_ltharv & ! intent(in) + , sl_mindbh_harvest & ! intent(in) + , sl_prob_harvest ! ! intent(in) + use ed_misc_coms , only : iyeara & ! intent(in) + , iyearz ! ! intent(in) + use grid_coms , only : ngrids ! ! intent(in) + use ed_max_dims , only : str_len & ! intent(in) + , huge_lu & ! intent(in) + , n_pft & ! intent(in) + , maxlist & ! intent(in) + , undef_real & ! intent(in) + , undef_integer ! ! intent(in) + use detailed_coms , only : idetailed ! ! intent(in) implicit none !----- Local variables --------------------------------------------------------------! @@ -49,6 +59,7 @@ subroutine read_landuse_matrix character(len=6) :: hform character(len=str_len) :: lu_name character(len=str_len) :: cdum + character(len=str_len) :: vkey character(len=13) :: hifmt character(len=15) :: hffmt integer :: nharvest @@ -67,12 +78,19 @@ subroutine read_landuse_matrix integer :: yd_1st integer :: yd_this integer :: yd_last + integer :: poseq logical :: inside logical :: write_lu_settings + real :: skid_rel_area real , dimension(n_pft) :: mindbh_slog real , dimension(n_pft) :: harvprob_slog real , dimension(n_pft) :: mindbh_fplt real , dimension(n_pft) :: harvprob_fplt + real , dimension(n_pft) :: skid_dbh_thresh + real , dimension(n_pft) :: felling_s_gtharv + real , dimension(n_pft) :: felling_s_ltharv + real , dimension(n_pft) :: skid_s_gtharv + real , dimension(n_pft) :: skid_s_ltharv real , dimension(num_lu_trans) :: landuse_now real :: lu_area real :: lu_area_i @@ -83,7 +101,6 @@ subroutine read_landuse_matrix !----- Local constants. -------------------------------------------------------------! character(len=12) , parameter :: fffmt = '(a,1x,f12.5)' character(len=13) , parameter :: esfmt = '(a,1x,es12.5)' - integer , parameter :: hoff = 18 real , parameter :: huge_dbh = huge(1.) character(len=str_len), parameter :: lu_table = "anth_disturb_table.txt" !----- External function. -----------------------------------------------------------! @@ -112,7 +129,7 @@ subroutine read_landuse_matrix write (unit=*,fmt='(a)') ' so MAX_LU_YEARS >= IYEARZ-IYEARA+1, then recompile' write (unit=*,fmt='(a)') ' your model.' call fatal_error ('Simulation is too long for anthropogenic disturbance.' & - ,'landuse_init','landuse_init.f90') + ,'read_landuse_matrix','landuse_init.f90') end if !------------------------------------------------------------------------------------! @@ -148,9 +165,15 @@ subroutine read_landuse_matrix !----- Set the parameters in a way that no logging/ploughing will happen. --! do isi = 1,cpoly%nsites - cpoly%num_landuse_years(isi) = 1 - cpoly%mindbh_harvest (1:n_pft,isi) = huge_dbh - cpoly%prob_harvest (1:n_pft,isi) = 0. + cpoly%num_landuse_years (isi) = 1 + cpoly%mindbh_harvest (:,isi) = huge_dbh + cpoly%prob_harvest (:,isi) = 0. + cpoly%skid_dbh_thresh (:,isi) = huge_dbh + cpoly%skid_s_gtharv (:,isi) = 1. + cpoly%skid_s_ltharv (:,isi) = 1. + cpoly%felling_s_gtharv(:,isi) = 1. + cpoly%felling_s_ltharv(:,isi) = 1. + cpoly%clutimes(1,isi)%landuse_year = iyeara cpoly%clutimes(1,isi)%landuse(1:num_lu_trans) = 0.0 end do @@ -167,9 +190,22 @@ subroutine read_landuse_matrix - !----- Initialise the PFT-dependent arrays. --------------------------------! - cpoly%mindbh_harvest (:,:) = huge_dbh - cpoly%prob_harvest (:,:) = 0. + !---------------------------------------------------------------------------! + ! Initialise the PFT-dependent arrays with namelist data, but keep ! + ! harvest probability zero and minimum DBH for harvesting to infinity, to ! + ! prevent felling of these PFTs. ! + !---------------------------------------------------------------------------! + do isi = 1,cpoly%nsites + cpoly%mindbh_harvest (:,isi) = huge_dbh + cpoly%prob_harvest (:,isi) = 0. + cpoly%skid_dbh_thresh (:,isi) = merge(huge_dbh,sl_skid_dbh_thresh & + ,is_grass(:)) + cpoly%skid_s_gtharv (:,isi) = merge( 1.00,sl_skid_s_gtharv,is_grass(:)) + cpoly%skid_s_ltharv (:,isi) = merge( 1.00,sl_skid_s_ltharv,is_grass(:)) + cpoly%felling_s_gtharv(:,isi) = merge( 0.70, 0.00,is_grass(:)) + cpoly%felling_s_ltharv(:,isi) = merge( 0.70,sl_felling_s_ltharv & + ,is_grass(:)) + end do !---------------------------------------------------------------------------! @@ -201,76 +237,279 @@ subroutine read_landuse_matrix open(unit=12,file=trim(lu_name),form='formatted',status='old',action='read') !---------------------------------------------------------------------------! + + !---------------------------------------------------------------------------! + ! Top header variables. Initialise them with dummy values. Except for ! + ! skid_area, they must be all assigned. Skid area by default the value ! + ! from the namelist. ! + !---------------------------------------------------------------------------! + wlon = undef_real + elon = undef_real + slat = undef_real + nlat = undef_real + lu_area = undef_real + yd_1st = undef_integer + yd_last = undef_integer + skid_rel_area = sl_skid_rel_area + nharvest = undef_integer + !---------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------! + ! Initialise the temporary arrays with dummy values. These are all ! + ! optional variables, but they are useful to define logging strategies in ! + ! more detail. ! !---------------------------------------------------------------------------! - ! Initialise the temporary arrays with data that will not cause any ! - ! harvesting. The actual variables will be read in the following block. ! + harvest_pft (1:n_pft) = undef_integer + mindbh_slog (1:n_pft) = undef_real + harvprob_slog (1:n_pft) = undef_real + mindbh_fplt (1:n_pft) = undef_real + harvprob_fplt (1:n_pft) = undef_real + skid_dbh_thresh (1:n_pft) = undef_real + skid_s_gtharv (1:n_pft) = undef_real + skid_s_ltharv (1:n_pft) = undef_real + felling_s_gtharv(1:n_pft) = undef_real + felling_s_ltharv(1:n_pft) = undef_real !---------------------------------------------------------------------------! - harvest_pft (1:n_pft) = -1 - mindbh_slog (1:n_pft) = huge_dbh - harvprob_slog(1:n_pft) = 0. - mindbh_fplt (1:n_pft) = huge_dbh - harvprob_fplt(1:n_pft) = 0. + !----- Define the format for the header. -----------------------------------! write(hform,fmt='(a,i3.3,a)') '(a',str_len,')' + !---------------------------------------------------------------------------! - !----- Read the header. ----------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) wlon - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) elon + !---------------------------------------------------------------------------! + ! Read the top header. ! + !---------------------------------------------------------------------------! + read_tophead: do + !---- Read line. --------------------------------------------------------! + read (unit=12,fmt=hform) cdum + poseq = index(cdum,'=') + !------------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) slat + !---- If we reached the header, exit the loop. --------------------------! + if (poseq == 0) exit read_tophead + !------------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) nlat - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) lu_area + !---- If not, read the variable key for now and remove it from line. ----! + vkey = cdum(:poseq-1) + cdum = cdum(poseq+1:) + !------------------------------------------------------------------------! + + + !------------------------------------------------------------------------! + ! Identify which variable to read (multiple options are for ! + ! back compatibility). ! + !------------------------------------------------------------------------! + select case (trim(vkey)) + case ('WEST_LONGITUDE','WEST.LONGITUDE') + !---- Longitude of the west edge of the domain. ----------------------! + read(cdum,fmt=*) wlon + !---------------------------------------------------------------------! + case ('EAST_LONGITUDE','EAST.LONGITUDE') + !---- Longitude of the east edge of the domain. ----------------------! + read(cdum,fmt=*) elon + !---------------------------------------------------------------------! + case ('SOUTH_LATITUDE','SOUTH.LATITUDE') + !---- Latitude of the south edge of the domain. ----------------------! + read(cdum,fmt=*) slat + !---------------------------------------------------------------------! + case ('NORTH_LATITUDE','NORTH.LATITUDE') + !---- Latitude of the north edge of the domain. ----------------------! + read(cdum,fmt=*) nlat + !---------------------------------------------------------------------! + case ('BLOCK_AREA' ,'BLOCK.AREA' ) + !---- Domain area. ---------------------------------------------------! + read(cdum,fmt=*) lu_area + !---------------------------------------------------------------------! + case ('FIRST_LUYEAR' ,'FIRST.LUYEAR' ) + !---- First year with disturbance data. ------------------------------! + read(cdum,fmt=*) yd_1st + !---------------------------------------------------------------------! + case ('LAST_LUYEAR' ,'LAST.LUYEAR' ) + !---- Last year with disturbance data. -------------------------------! + read(cdum,fmt=*) yd_last + !---------------------------------------------------------------------! + case ('SKID_AREA' ,'SKID.AREA' ) + !---- Damage area due to skid trails and roads. ----------------------! + read(cdum,fmt=*) skid_rel_area + !---------------------------------------------------------------------! + case ('N_PFT_HARVEST' ,'N.PFT.HARVEST' ) + !---- Number of PFTs to harvest. -------------------------------------! + read(cdum,fmt=*) nharvest + !---------------------------------------------------------------------! + + !----- This should precede the PFT-specific instructions. ------------! + exit read_tophead + !---------------------------------------------------------------------! + case default + !----- Key is not recognised. Stop the model. ------------------------! + write (unit=*,fmt='(a)' ) '-----------------------------------' + write (unit=*,fmt='(a,1x,a)' ) 'File: ',trim(lu_name) + write (unit=*,fmt='(a,2(1x,a))') 'Key: ',trim(vkey),'is invalid!' + write (unit=*,fmt='(a)' ) '-----------------------------------' + call fatal_error(' Problems reading input file (not an ED2 bug)!' & + ,'read_landuse_matrix','landuse_init.f90') + !---------------------------------------------------------------------! + end select + !------------------------------------------------------------------------! + end do read_tophead + !---------------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) yd_1st - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) yd_last - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) nharvest + !---------------------------------------------------------------------------! + ! Before proceeding, ensure that all top header variables have been ! + ! properly read. ! + !---------------------------------------------------------------------------! + if ( wlon == undef_real .or. elon == undef_real .or. & + slat == undef_real .or. nlat == undef_real .or. & + lu_area == undef_real .or. yd_1st == undef_integer .or. & + yd_last == undef_integer .or. nharvest == undef_integer ) then + write (unit=*,fmt='(a)') '------------------------------------' + write (unit=*,fmt='(2(a,1x))') ' - File: ',trim(lu_name) + write (unit=*,fmt='(a)') '------------------------------------' + write (unit=*,fmt='(a,1x,es12.5)') ' - WEST_LONGITUDE = ',wlon + write (unit=*,fmt='(a,1x,es12.5)') ' - EAST_LONGITUDE = ',elon + write (unit=*,fmt='(a,1x,es12.5)') ' - SOUTH_LATITUDE = ',slat + write (unit=*,fmt='(a,1x,es12.5)') ' - NORTH_LATITUDE = ',nlat + write (unit=*,fmt='(a,1x,es12.5)') ' - BLOCK_AREA = ',lu_area + write (unit=*,fmt='(a,1x,i6)') ' - FIRST_LUYEAR = ',yd_1st + write (unit=*,fmt='(a,1x,i6)') ' - LAST_LUYEAR = ',yd_last + write (unit=*,fmt='(a,1x,es12.5)') ' - SKID_AREA = ',skid_rel_area + write (unit=*,fmt='(a,1x,i6)') ' - N_PFT_HARVEST = ',nharvest + write (unit=*,fmt='(a)') '------------------------------------' + call fatal_error('Missing variables in input file (not an ED2 bug)!' & + ,'read_landuse_matrix','landuse_init.f90') + end if + !---------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------! + ! Decide whether or not to read PFT specific harvest instructions. ! + !---------------------------------------------------------------------------! if (nharvest > 0 ) then !------------------------------------------------------------------------! - ! If nharvest is not 0, then the harvesting is not PFT-blind, read ! - ! the PFT information in the file. ! + ! If nharvest is not 0, then the harvesting is not PFT-agnostic, ! + ! read the PFT information in the file. To allow for back-compatibility ! + ! we must check every variable until we reach the header. ! !------------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) (harvest_pft(h) ,h=1,nharvest) + read_harvest: do + !---- Read line. -----------------------------------------------------! + read (unit=12,fmt=hform) cdum + poseq = index(cdum,'=') + !---------------------------------------------------------------------! + + !---- If we reached the header, exit the loop. -----------------------! + if (poseq == 0) exit read_harvest + !---------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) (mindbh_slog(h) ,h=1,nharvest) - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) (harvprob_slog(h) ,h=1,nharvest) + !---- If not, read the variable key for now and remove it from line. -! + vkey = cdum(:poseq-1) + cdum = cdum(poseq+1:) + !---------------------------------------------------------------------! - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) (mindbh_fplt(h) ,h=1,nharvest) - read (unit=12,fmt=hform) cdum - cdum = cdum(hoff:) - read (cdum, fmt=*) (harvprob_fplt(h) ,h=1,nharvest) + !---------------------------------------------------------------------! + ! Identify which variable to read (multiple options are for ! + ! back compatibility). ! + !---------------------------------------------------------------------! + select case (trim(vkey)) + case ('HARVEST_PFT','HARVEST.PFT') + !---- PFTs to read. -----------------------------------------------! + read (cdum, fmt=*) (harvest_pft(h) ,h=1,nharvest) + !------------------------------------------------------------------! + + !------------------------------------------------------------------! + ! Assign defaults to variables in case they have not been ! + ! read yet. ! + !------------------------------------------------------------------! + mindbh_slog = merge( mindbh_slog , 0. & + , harvest_pft /= undef_integer .and. & + mindbh_slog /= undef_real ) + harvprob_slog = merge( harvprob_slog , 1. & + , harvest_pft /= undef_integer .and. & + harvprob_slog /= undef_real ) + mindbh_fplt = merge( mindbh_fplt , 0. & + , harvest_pft /= undef_integer .and. & + mindbh_fplt /= undef_real ) + harvprob_fplt = merge( harvprob_fplt , 1. & + , harvest_pft /= undef_integer .and. & + harvprob_fplt /= undef_real ) + skid_dbh_thresh = merge( skid_dbh_thresh , sl_skid_dbh_thresh & + , harvest_pft /= undef_integer .and. & + skid_dbh_thresh /= undef_real ) + skid_s_gtharv = merge( skid_s_gtharv , sl_skid_s_gtharv & + , harvest_pft /= undef_integer .and. & + skid_s_gtharv /= undef_real ) + skid_s_ltharv = merge( skid_s_ltharv , sl_skid_s_ltharv & + , harvest_pft /= undef_integer .and. & + skid_s_ltharv /= undef_real ) + felling_s_ltharv = merge( felling_s_ltharv, sl_felling_s_ltharv & + , harvest_pft /= undef_integer .and. & + felling_s_ltharv /= undef_real ) + felling_s_gtharv = merge( felling_s_gtharv, 0. & + , harvest_pft /= undef_integer .and. & + felling_s_gtharv /= undef_real ) + !------------------------------------------------------------------! + + case ('MINDBH_SLOG','MINDBH.SLOG','MINDBH_1ARY','MINDBH.1ARY') + !---- Minimum DBH for harvesting: (selective) logging. ------------! + read (cdum, fmt=*) (mindbh_slog (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('HARVPROB_SLOG','HARVPROB.SLOG','HARVPROB_1ARY','HARVPROB.1ARY') + !---- Harvest probability: (selective) logging. -------------------! + read (cdum, fmt=*) (harvprob_slog (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('MINDBH_FPLT','MINDBH.FPLT','MINDBH_2ARY','MINDBH.2ARY') + !---- Minimum DBH for harvesting: forest plantation. --------------! + read (cdum, fmt=*) (mindbh_fplt (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('HARVPROB_FPLT','HARVPROB.FPLT','HARVPROB_2ARY','HARVPROB.2ARY') + !---- Harvest probability: forest plantation. ---------------------! + read (cdum, fmt=*) (harvprob_fplt (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('SKID_DBH_THRESH','SKID.DBH.THRESH') + !---- Skid damage: DBH threshold for small/large tree. ------------! + read (cdum, fmt=*) (skid_dbh_thresh (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('SKID_S_GTHARV','SKID.S.GTHARV') + !---- Skid damage: Survivorship of large trees. -------------------! + read (cdum, fmt=*) (skid_s_gtharv (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('SKID_S_LTHARV','SKID.S.LTHARV') + !---- Skid damage: Survivorship of small trees. -------------------! + read (cdum, fmt=*) (skid_s_ltharv (h),h=1,nharvest) + !------------------------------------------------------------------! + case ('FELLING_S_LTHARV','FELLING.S.LTHARV') + !---- Tree felling: Survivorship of small trees. ------------------! + read (cdum, fmt=*) (felling_s_ltharv(h),h=1,nharvest) + !------------------------------------------------------------------! + case ('FELLING_S_GTHARV','FELLING.S.GTHARV') + !------------------------------------------------------------------! + ! Tree felling: Survivorship of large trees. Leaving this as ! + ! a future option, though there is no strong reason to make this ! + ! survivorship anything other than 0. ! + !------------------------------------------------------------------! + read (cdum, fmt=*) (felling_s_ltharv(h),h=1,nharvest) + !------------------------------------------------------------------! + case default + !----- Key is not recognised. Stop the model. ---------------------! + write (unit=*,fmt='(a)' ) '--------------------------------' + write (unit=*,fmt='(a,1x,a)' ) 'File: ',trim(lu_name) + write (unit=*,fmt='(a,2(1x,a))') 'Key: ',trim(vkey),'is invalid!' + write (unit=*,fmt='(a)' ) '--------------------------------' + call fatal_error(' Problems reading input file (not an ED2 bug)!' & + ,'read_landuse_matrix','landuse_init.f90') + !------------------------------------------------------------------! + end select + !---------------------------------------------------------------------! + end do read_harvest + !------------------------------------------------------------------------! else !------------------------------------------------------------------------! ! No specific PFT information was given, this is likely to be a case ! @@ -279,13 +518,32 @@ subroutine read_landuse_matrix !------------------------------------------------------------------------! h = 0 nopftloop: do ipft=1,n_pft - h=h+1 - harvest_pft(h) = ipft - mindbh_slog(1:n_pft) = 0. - mindbh_fplt(1:n_pft) = 0. + !--- Skip grasses and lianas. ----------------------------------------! + if ( is_grass(ipft) .or. is_liana(ipft) ) cycle nopftloop + !---------------------------------------------------------------------! + + + !----- Fill in with default. -----------------------------------------! + h = h + 1 + mindbh_slog (h) = 0. + harvprob_slog (h) = 1. + mindbh_fplt (h) = 0. + harvprob_fplt (h) = 1. + skid_dbh_thresh (h) = sl_skid_dbh_thresh + skid_s_gtharv (h) = sl_skid_s_gtharv + skid_s_ltharv (h) = sl_skid_s_ltharv + felling_s_ltharv(h) = sl_felling_s_ltharv + felling_s_gtharv(h) = 0. + !---------------------------------------------------------------------! end do nopftloop + !------------------------------------------------------------------------! + + + !--- Skip header and be ready for reading transitions. ------------------! + read (unit=12,fmt=*) + !------------------------------------------------------------------------! end if - read (unit=12,fmt=*) + !---------------------------------------------------------------------------! !----- Use file_lat to compute the physical area sampled by the file. ------! if (lu_area == 0.) then @@ -301,7 +559,7 @@ subroutine read_landuse_matrix write (unit=*,fmt='(a,1x,i6)') ' - Nharvest:',nharvest write (unit=*,fmt='(a)') '------------------------------------' call fatal_error('Land use area is zero, it doesn''t make any sense!' & - ,'landuse_init','landuse_init.f90') + ,'read_landuse_matrix','landuse_init.f90') else lu_area_i = 1. / lu_area end if @@ -323,10 +581,17 @@ subroutine read_landuse_matrix !----- Copy the file information to the first site. ---------------------! isi = 1 csite => cpoly%site(isi) + !------------------------------------------------------------------------! !----- Determine the number of disturbance years. -----------------------! cpoly%num_landuse_years(isi) = max(yd_last,iyearz)-min(yd_1st,iyeara) + 1 + !------------------------------------------------------------------------! + + + !----- Define the degree of damage relative to felling. -----------------! + cpoly%skid_rel_area(isi) = skid_rel_area + !------------------------------------------------------------------------! !----- Fill the arrays with the appropriate PFT. ------------------------! @@ -351,6 +616,24 @@ subroutine read_landuse_matrix !------------------------------------------------------------------------! + + !------------------------------------------------------------------------! + ! These variables are filled the same way for selective logging ! + ! and forest plantations. ! + !------------------------------------------------------------------------! + skidloop_site: do h=1,nharvest + ipft = harvest_pft(h) + if (ipft >= 1 .and. ipft <= n_pft) then + cpoly%skid_dbh_thresh (ipft,isi) = skid_dbh_thresh (h) + cpoly%skid_s_gtharv (ipft,isi) = skid_s_gtharv (h) + cpoly%skid_s_ltharv (ipft,isi) = skid_s_ltharv (h) + cpoly%felling_s_ltharv(ipft,isi) = felling_s_ltharv(h) + cpoly%felling_s_gtharv(ipft,isi) = felling_s_gtharv(h) + end if + end do skidloop_site + !------------------------------------------------------------------------! + + !----- Padding disturbances with zero before first available lu year. ---! iyear = 0 do yd_this = iyeara,(yd_1st-1) @@ -405,9 +688,19 @@ subroutine read_landuse_matrix !---------------------------------------------------------------------! + !----- Define the degree of damage relative to felling. --------------! + cpoly%skid_rel_area(isi) = cpoly%skid_rel_area(1) + !---------------------------------------------------------------------! + + !----- PFT-dependent harvest characteristics. ------------------------! - cpoly%mindbh_harvest(:,isi) = cpoly%mindbh_harvest(:,1) - cpoly%prob_harvest (:,isi) = cpoly%prob_harvest (:,1) + cpoly%mindbh_harvest (:,isi) = cpoly%mindbh_harvest (:,1) + cpoly%prob_harvest (:,isi) = cpoly%prob_harvest (:,1) + cpoly%skid_dbh_thresh (:,isi) = cpoly%skid_dbh_thresh (:,1) + cpoly%skid_s_gtharv (:,isi) = cpoly%skid_s_gtharv (:,1) + cpoly%skid_s_ltharv (:,isi) = cpoly%skid_s_ltharv (:,1) + cpoly%felling_s_ltharv(:,isi) = cpoly%felling_s_ltharv(:,1) + cpoly%felling_s_gtharv(:,isi) = cpoly%felling_s_gtharv(:,1) !---------------------------------------------------------------------! @@ -419,6 +712,7 @@ subroutine read_landuse_matrix clutime%landuse_year = onelutime%landuse_year clutime%landuse(1:num_lu_trans) = onelutime%landuse(1:num_lu_trans) end do + !---------------------------------------------------------------------! end do siteloop_one else @@ -450,8 +744,14 @@ subroutine read_landuse_matrix do isi = 1,cpoly%nsites cpoly%clutimes(1,isi)%landuse_year = iyeara cpoly%clutimes(1,isi)%landuse(1:num_lu_trans) = 0.0 - cpoly%mindbh_harvest(1:n_pft,isi) = huge_dbh - cpoly%prob_harvest (1:n_pft,isi) = 0. + cpoly%skid_rel_area (isi) = 0. + cpoly%mindbh_harvest (:,isi) = huge_dbh + cpoly%prob_harvest (:,isi) = 0. + cpoly%skid_dbh_thresh (:,isi) = huge_dbh + cpoly%skid_s_gtharv (:,isi) = 1. + cpoly%skid_s_ltharv (:,isi) = 1. + cpoly%felling_s_ltharv(:,isi) = 1. + cpoly%felling_s_gtharv(:,isi) = 1. end do end if !---------------------------------------------------------------------------! @@ -488,9 +788,20 @@ subroutine read_landuse_matrix !---------------------------------------------------------------------------! + !----- Define the degree of damage relative to felling. --------------------! + cpoly%skid_rel_area(isi) = cpoly%skid_rel_area(1) + !---------------------------------------------------------------------------! + + !----- Initialise the PFT-dependent arrays. --------------------------------! - cpoly%mindbh_harvest (1:n_pft,isi) = huge_dbh - cpoly%prob_harvest (1:n_pft,isi) = 0. + cpoly%mindbh_harvest (:,isi) = huge_dbh + cpoly%prob_harvest (:,isi) = 0. + cpoly%skid_dbh_thresh (:,isi) = merge(huge_dbh,sl_skid_dbh_thresh & + ,is_grass(:)) + cpoly%skid_s_gtharv (:,isi) = merge( 1.00,sl_skid_s_gtharv ,is_grass(:)) + cpoly%skid_s_ltharv (:,isi) = merge( 1.00,sl_skid_s_ltharv ,is_grass(:)) + cpoly%felling_s_gtharv(:,isi) = merge( 0.70, 0.00 ,is_grass(:)) + cpoly%felling_s_ltharv(:,isi) = merge( 0.70,sl_felling_s_ltharv,is_grass(:)) !---------------------------------------------------------------------------! @@ -528,6 +839,7 @@ subroutine read_landuse_matrix if (yd_this >= sl_yr_first) then if ( (sl_scale == 1) .or. (mod(yd_this-sl_yr_first,sl_nyrs) == 0) ) & then + clutime%landuse(11) = lnexp_max clutime%landuse(12) = -1.0 clutime%landuse(14) = -1.0 end if @@ -548,9 +860,19 @@ subroutine read_landuse_matrix !------------------------------------------------------------------------! + !----- Define the degree of damage relative to felling. -----------------! + cpoly%skid_rel_area(isi) = cpoly%skid_rel_area(1) + !------------------------------------------------------------------------! + + !----- PFT-dependent harvest characteristics. ---------------------------! - cpoly%mindbh_harvest(:,isi) = cpoly%mindbh_harvest(:,1) - cpoly%prob_harvest (:,isi) = cpoly%prob_harvest (:,1) + cpoly%mindbh_harvest (:,isi) = cpoly%mindbh_harvest (:,1) + cpoly%prob_harvest (:,isi) = cpoly%prob_harvest (:,1) + cpoly%skid_dbh_thresh (:,isi) = cpoly%skid_dbh_thresh (:,1) + cpoly%skid_s_gtharv (:,isi) = cpoly%skid_s_gtharv (:,1) + cpoly%skid_s_ltharv (:,isi) = cpoly%skid_s_ltharv (:,1) + cpoly%felling_s_gtharv(:,isi) = cpoly%felling_s_gtharv(:,1) + cpoly%felling_s_ltharv(:,isi) = cpoly%felling_s_ltharv(:,1) !------------------------------------------------------------------------! @@ -593,40 +915,62 @@ subroutine read_landuse_matrix do ipft=1,n_pft if (cpoly%prob_harvest(ipft,isi) > 0.0) then h = h + 1 - harvest_pft (h) = ipft - mindbh_slog (h) = cpoly%mindbh_harvest(ipft,isi) - harvprob_slog(h) = cpoly%prob_harvest (ipft,isi) - mindbh_fplt (h) = cpoly%mindbh_harvest(ipft,isi) - harvprob_fplt(h) = cpoly%prob_harvest (ipft,isi) + harvest_pft (h) = ipft + mindbh_slog (h) = cpoly%mindbh_harvest (ipft,isi) + harvprob_slog (h) = cpoly%prob_harvest (ipft,isi) + mindbh_fplt (h) = cpoly%mindbh_harvest (ipft,isi) + harvprob_fplt (h) = cpoly%prob_harvest (ipft,isi) + skid_dbh_thresh (h) = cpoly%skid_dbh_thresh (ipft,isi) + skid_s_gtharv (h) = cpoly%skid_s_gtharv (ipft,isi) + skid_s_ltharv (h) = cpoly%skid_s_ltharv (ipft,isi) + felling_s_ltharv(h) = cpoly%felling_s_ltharv(ipft,isi) + felling_s_gtharv(h) = cpoly%felling_s_gtharv(ipft,isi) end if end do !---------------------------------------------------------------------------! + !---------------------------------------------------------------------------! + ! Write the LU-like file. ! + !---------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------! ! Write the LU-like file. ! !---------------------------------------------------------------------------! open(unit=16,file=trim(lu_table),status='replace',action='write') - write(unit=16,fmt='(a,1x,f8.3)' ) 'WEST.LONGITUDE = ',wlon - write(unit=16,fmt='(a,1x,f8.3)' ) 'EAST.LONGITUDE = ',elon - write(unit=16,fmt='(a,1x,f8.3)' ) 'SOUTH.LATITUDE = ',slat - write(unit=16,fmt='(a,1x,f8.3)' ) 'NORTH.LATITUDE = ',nlat - write(unit=16,fmt='(a,1x,f20.5)') 'BLOCK.AREA = ',lu_area - write(unit=16,fmt='(a,1x,i4.4)' ) 'FIRST.LUYEAR = ',iyeara - write(unit=16,fmt='(a,1x,i4.4)' ) 'LAST.LUYEAR = ',iyearz - write(unit=16,fmt='(a,1x,i2)' ) 'N.PFT.HARVEST = ',nharvest + write(unit=16,fmt='(a,1x,f8.3)' ) 'WEST_LONGITUDE = ',wlon + write(unit=16,fmt='(a,1x,f8.3)' ) 'EAST_LONGITUDE = ',elon + write(unit=16,fmt='(a,1x,f8.3)' ) 'SOUTH_LATITUDE = ',slat + write(unit=16,fmt='(a,1x,f8.3)' ) 'NORTH_LATITUDE = ',nlat + write(unit=16,fmt='(a,1x,f20.5)') 'BLOCK_AREA = ',lu_area + write(unit=16,fmt='(a,1x,i4.4)' ) 'FIRST_LUYEAR = ',iyeara + write(unit=16,fmt='(a,1x,i4.4)' ) 'LAST_LUYEAR = ',iyearz + write(unit=16,fmt='(a,1x,f8.3)' ) 'SKID_AREA = ',skid_rel_area + write(unit=16,fmt='(a,1x,i2)' ) 'N_PFT_HARVEST = ',nharvest if (nharvest > 0) then write(unit=16,fmt=hifmt) & - 'HARVEST.PFT = ',(harvest_pft (h),h=1,nharvest) + 'HARVEST_PFT = ',(harvest_pft (h),h=1,nharvest) + write(unit=16,fmt=hffmt) & + 'MINDBH_SLOG = ',(mindbh_slog (h),h=1,nharvest) + write(unit=16,fmt=hffmt) & + 'HARVPROB_SLOG = ',(harvprob_slog (h),h=1,nharvest) + write(unit=16,fmt=hffmt) & + 'MINDBH_FPLT = ',(mindbh_fplt (h),h=1,nharvest) + write(unit=16,fmt=hffmt) & + 'HARVPROB_FPLT = ',(harvprob_fplt (h),h=1,nharvest) + write(unit=16,fmt=hffmt) & + 'SKID_DBH_THRESH = ',(skid_dbh_thresh (h),h=1,nharvest) write(unit=16,fmt=hffmt) & - 'MINDBH.SLOG = ',(mindbh_slog (h),h=1,nharvest) + 'SKID_S_GTHARV = ',(skid_s_gtharv (h),h=1,nharvest) write(unit=16,fmt=hffmt) & - 'HARVPROB.SLOG = ',(harvprob_slog(h),h=1,nharvest) + 'SKID_S_LTHARV = ',(skid_s_ltharv (h),h=1,nharvest) write(unit=16,fmt=hffmt) & - 'MINDBH.FPLT = ',(mindbh_fplt (h),h=1,nharvest) + 'FELLING_S_LTHARV = ',(felling_s_ltharv(h),h=1,nharvest) write(unit=16,fmt=hffmt) & - 'HARVPROB.FPLT = ',(harvprob_fplt(h),h=1,nharvest) + 'FELLING_S_GTHARV = ',(felling_s_gtharv(h),h=1,nharvest) end if write(unit=16,fmt='(a,19(1x,a))') 'YEAR',' CPL_PST',' PST_CPL' & ,' PST_VEG',' VEG_PST',' VEG_CLP',' CPL_VEG' & diff --git a/ED/src/io/average_utils.f90 b/ED/src/io/average_utils.f90 index 152c09294..722b61051 100644 --- a/ED/src/io/average_utils.f90 +++ b/ED/src/io/average_utils.f90 @@ -493,6 +493,9 @@ subroutine aggregate_polygon_fmean(cgrid) cgrid%fmean_sfcw_mass (ipy) = cgrid%fmean_sfcw_mass (ipy) & + csite%fmean_sfcw_mass (ipa) & * patch_wgt + cgrid%fmean_snowfac (ipy) = cgrid%fmean_snowfac (ipy) & + + csite%fmean_snowfac (ipa) & + * patch_wgt cgrid%fmean_rshort_gnd (ipy) = cgrid%fmean_rshort_gnd (ipy) & + csite%fmean_rshort_gnd (ipa) & * patch_wgt @@ -1425,11 +1428,13 @@ subroutine zero_ed_fmean_vars(cgrid) cgrid%fmean_sfcw_mass ( ipy) = 0.0 cgrid%fmean_sfcw_temp ( ipy) = 0.0 cgrid%fmean_sfcw_fliq ( ipy) = 0.0 + cgrid%fmean_snowfac ( ipy) = 0.0 cgrid%fmean_soil_energy (:,ipy) = 0.0 cgrid%fmean_soil_mstpot (:,ipy) = 0.0 cgrid%fmean_soil_water (:,ipy) = 0.0 cgrid%fmean_soil_temp (:,ipy) = 0.0 cgrid%fmean_soil_fliq (:,ipy) = 0.0 + cgrid%fmean_snowfac ( ipy) = 0.0 cgrid%fmean_rshort_gnd ( ipy) = 0.0 cgrid%fmean_par_gnd ( ipy) = 0.0 cgrid%fmean_rlong_gnd ( ipy) = 0.0 @@ -1574,6 +1579,7 @@ subroutine zero_ed_fmean_vars(cgrid) csite%fmean_sfcw_mass ( ipa) = 0.0 csite%fmean_sfcw_temp ( ipa) = 0.0 csite%fmean_sfcw_fliq ( ipa) = 0.0 + csite%fmean_snowfac ( ipa) = 0.0 csite%fmean_soil_energy (:,ipa) = 0.0 csite%fmean_soil_mstpot (:,ipa) = 0.0 csite%fmean_soil_water (:,ipa) = 0.0 @@ -2059,6 +2065,9 @@ subroutine integrate_ed_dmean_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = cgrid%dmean_sfcw_mass (ipy) & + cgrid%fmean_sfcw_mass (ipy) & * frqsum_o_daysec + cgrid%dmean_snowfac (ipy) = cgrid%dmean_snowfac (ipy) & + + cgrid%fmean_snowfac (ipy) & + * frqsum_o_daysec cgrid%dmean_rshort_gnd (ipy) = cgrid%dmean_rshort_gnd (ipy) & + cgrid%fmean_rshort_gnd (ipy) & * frqsum_o_daysec @@ -2363,6 +2372,9 @@ subroutine integrate_ed_dmean_vars(cgrid) csite%dmean_sfcw_mass (ipa) = csite%dmean_sfcw_mass (ipa) & + csite%fmean_sfcw_mass (ipa) & * frqsum_o_daysec + csite%dmean_snowfac (ipa) = csite%dmean_snowfac (ipa) & + + csite%fmean_snowfac (ipa) & + * frqsum_o_daysec csite%dmean_rshort_gnd (ipa) = csite%dmean_rshort_gnd (ipa) & + csite%fmean_rshort_gnd (ipa) & * frqsum_o_daysec @@ -2812,10 +2824,11 @@ end subroutine normalize_ed_today_vars !=======================================================================================! !=======================================================================================! - ! SUBROUTINE: NORMALIZE_ED_TODAYNPP_VARS - !> \brief This subroutine will scale the daily NPP allocation terms + ! SUBROUTINE: COPY_TODAY_TO_DMEAN_VARS + !> \brief This subroutine scales the daily NPP allocation terms and transfer today + !! variables to dmean. !---------------------------------------------------------------------------------------! - subroutine normalize_ed_todayNPP_vars(cgrid) + subroutine copy_today_to_dmean_vars(cgrid) use ed_state_vars , only : edtype & ! structure , polygontype & ! structure , sitetype & ! structure @@ -2833,47 +2846,70 @@ subroutine normalize_ed_todayNPP_vars(cgrid) integer :: isi integer :: ipa integer :: ico + !------------------------------------------------------------------------------------! + + !------ Skip sub-routine and do nothing in case we are not writing daily averages. --! + if (.not. writing_long) return + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Loop through polygons. ! + !------------------------------------------------------------------------------------! polyloop: do ipy=1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + + !---------------------------------------------------------------------------------! + ! Loop through sites. ! + !---------------------------------------------------------------------------------! siteloop: do isi=1,cpoly%nsites csite => cpoly%site(isi) - patchloop: do ipa=1,csite%npatches + !------------------------------------------------------------------------------! + ! Loop through patches. ! + !------------------------------------------------------------------------------! + patchloop: do ipa=1,csite%npatches cpatch => csite%patch(ipa) - - !----- Included a loop so it won't crash with empty cohorts... -------------! + + !---------------------------------------------------------------------------! + ! Loop through cohorts. This must be a loop, so it won't crash with ! + ! empty patches. ! + !---------------------------------------------------------------------------! cohortloop: do ico=1,cpatch%ncohorts !------------------------------------------------------------------------! ! We now update the daily means of NPP allocation terms ! ! and we convert them to kgC/plant/yr ! !------------------------------------------------------------------------! - if (writing_long) then - cpatch%dmean_nppleaf (ico) = cpatch%today_nppleaf (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppfroot (ico) = cpatch%today_nppfroot (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppsapwood(ico) = cpatch%today_nppsapwood(ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppbark (ico) = cpatch%today_nppbark (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppcroot (ico) = cpatch%today_nppcroot (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppseeds (ico) = cpatch%today_nppseeds (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppwood (ico) = cpatch%today_nppwood (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppdaily (ico) = cpatch%today_nppdaily (ico) & - * yr_day / cpatch%nplant (ico) - end if + cpatch%dmean_nppleaf (ico) = cpatch%today_nppleaf (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppfroot (ico) = cpatch%today_nppfroot (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppsapwood(ico) = cpatch%today_nppsapwood(ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppbark (ico) = cpatch%today_nppbark (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppcroot (ico) = cpatch%today_nppcroot (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppseeds (ico) = cpatch%today_nppseeds (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppwood (ico) = cpatch%today_nppwood (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppdaily (ico) = cpatch%today_nppdaily (ico) & + * yr_day / cpatch%nplant (ico) + !------------------------------------------------------------------------! end do cohortloop + !---------------------------------------------------------------------------! end do patchloop + !------------------------------------------------------------------------------! end do siteloop + !---------------------------------------------------------------------------------! end do polyloop + !------------------------------------------------------------------------------------! return - end subroutine normalize_ed_todayNPP_vars + end subroutine copy_today_to_dmean_vars !=======================================================================================! !=======================================================================================! @@ -3702,6 +3738,7 @@ subroutine zero_ed_dmean_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = 0.0 cgrid%dmean_sfcw_temp (ipy) = 0.0 cgrid%dmean_sfcw_fliq (ipy) = 0.0 + cgrid%dmean_snowfac (ipy) = 0.0 cgrid%dmean_soil_energy (:,ipy) = 0.0 cgrid%dmean_soil_mstpot (:,ipy) = 0.0 cgrid%dmean_soil_water (:,ipy) = 0.0 @@ -3824,6 +3861,7 @@ subroutine zero_ed_dmean_vars(cgrid) csite%dmean_sfcw_mass (ipa) = 0.0 csite%dmean_sfcw_temp (ipa) = 0.0 csite%dmean_sfcw_fliq (ipa) = 0.0 + csite%dmean_snowfac (ipa) = 0.0 csite%dmean_soil_energy (:,ipa) = 0.0 csite%dmean_soil_mstpot (:,ipa) = 0.0 csite%dmean_soil_water (:,ipa) = 0.0 @@ -4426,6 +4464,9 @@ subroutine integrate_ed_mmean_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = cgrid%mmean_sfcw_mass (ipy) & + cgrid%dmean_sfcw_mass (ipy) & * ndaysi + cgrid%mmean_snowfac (ipy) = cgrid%mmean_snowfac (ipy) & + + cgrid%dmean_snowfac (ipy) & + * ndaysi cgrid%mmean_soil_energy (:,ipy) = cgrid%mmean_soil_energy (:,ipy) & + cgrid%dmean_soil_energy (:,ipy) & * ndaysi @@ -4951,6 +4992,9 @@ subroutine integrate_ed_mmean_vars(cgrid) csite%mmean_sfcw_mass (ipa) = csite%mmean_sfcw_mass (ipa) & + csite%dmean_sfcw_mass (ipa) & * ndaysi + csite%mmean_snowfac (ipa) = csite%mmean_snowfac (ipa) & + + csite%dmean_snowfac (ipa) & + * ndaysi csite%mmean_soil_energy (:,ipa) = csite%mmean_soil_energy (:,ipa) & + csite%dmean_soil_energy (:,ipa) & * ndaysi @@ -6086,6 +6130,7 @@ subroutine zero_ed_mmean_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = 0.0 cgrid%mmean_sfcw_temp (ipy) = 0.0 cgrid%mmean_sfcw_fliq (ipy) = 0.0 + cgrid%mmean_snowfac (ipy) = 0.0 cgrid%mmean_soil_energy (:,ipy) = 0.0 cgrid%mmean_soil_mstpot (:,ipy) = 0.0 cgrid%mmean_soil_water (:,ipy) = 0.0 @@ -6274,6 +6319,7 @@ subroutine zero_ed_mmean_vars(cgrid) csite%mmean_sfcw_mass (ipa) = 0.0 csite%mmean_sfcw_temp (ipa) = 0.0 csite%mmean_sfcw_fliq (ipa) = 0.0 + csite%mmean_snowfac (ipa) = 0.0 csite%mmean_soil_energy (:,ipa) = 0.0 csite%mmean_soil_mstpot (:,ipa) = 0.0 csite%mmean_soil_water (:,ipa) = 0.0 @@ -6838,6 +6884,9 @@ subroutine integrate_ed_qmean_vars(cgrid) cgrid%qmean_sfcw_mass (t,ipy) = cgrid%qmean_sfcw_mass (t,ipy) & + cgrid%fmean_sfcw_mass (ipy) & * ndaysi + cgrid%qmean_snowfac (t,ipy) = cgrid%qmean_snowfac (t,ipy) & + + cgrid%fmean_snowfac (ipy) & + * ndaysi cgrid%qmean_soil_energy (:,t,ipy) = cgrid%qmean_soil_energy (:,t,ipy) & + cgrid%fmean_soil_energy (:,ipy) & * ndaysi @@ -7230,6 +7279,9 @@ subroutine integrate_ed_qmean_vars(cgrid) csite%qmean_sfcw_mass (t,ipa) = csite%qmean_sfcw_mass (t,ipa) & + csite%fmean_sfcw_mass (ipa) & * ndaysi + csite%qmean_snowfac (t,ipa) = csite%qmean_snowfac (t,ipa) & + + csite%fmean_snowfac (ipa) & + * ndaysi csite%qmean_soil_energy (:,t,ipa) = csite%qmean_soil_energy (:,t,ipa) & + csite%fmean_soil_energy (:,ipa) & * ndaysi @@ -7796,6 +7848,25 @@ subroutine normalize_ed_qmean_vars(cgrid) + !---------------------------------------------------------------------------! + ! Find the derived properties for the canopy air space. ! + !---------------------------------------------------------------------------! + do t=1,ndcycle + can_exner = press2exner ( csite%qmean_can_prss (t,ipa)) + csite%qmean_can_temp(t,ipa) = extheta2temp( can_exner & + , csite%qmean_can_theta(t,ipa)) + csite%qmean_can_rhos(t,ipa) = idealdenssh ( csite%qmean_can_prss (t,ipa) & + , csite%qmean_can_temp (t,ipa) & + , csite%qmean_can_shv (t,ipa)) + csite%qmean_can_dmol(t,ipa) = idealdmolsh ( csite%qmean_can_prss (t,ipa) & + , csite%qmean_can_temp (t,ipa) & + , csite%qmean_can_shv (t,ipa)) + end do + !---------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------! ! Soil matric potential, temperature, and liquid water. ! !---------------------------------------------------------------------------! @@ -8163,6 +8234,7 @@ subroutine zero_ed_qmean_vars(cgrid) cgrid%qmean_sfcw_mass (:,ipy) = 0.0 cgrid%qmean_sfcw_temp (:,ipy) = 0.0 cgrid%qmean_sfcw_fliq (:,ipy) = 0.0 + cgrid%qmean_snowfac (:,ipy) = 0.0 cgrid%qmean_soil_energy (:,:,ipy) = 0.0 cgrid%qmean_soil_mstpot (:,:,ipy) = 0.0 cgrid%qmean_soil_water (:,:,ipy) = 0.0 @@ -8309,6 +8381,7 @@ subroutine zero_ed_qmean_vars(cgrid) csite%qmean_sfcw_mass (:,ipa) = 0.0 csite%qmean_sfcw_temp (:,ipa) = 0.0 csite%qmean_sfcw_fliq (:,ipa) = 0.0 + csite%qmean_snowfac (:,ipa) = 0.0 csite%qmean_soil_energy (:,:,ipa) = 0.0 csite%qmean_soil_mstpot (:,:,ipa) = 0.0 csite%qmean_soil_water (:,:,ipa) = 0.0 diff --git a/ED/src/io/ed_init_history.f90 b/ED/src/io/ed_init_history.f90 index f4d91cc49..7453fb2f1 100644 --- a/ED/src/io/ed_init_history.f90 +++ b/ED/src/io/ed_init_history.f90 @@ -23,31 +23,48 @@ module ed_init_history ! polygons and populate the model states with what is found in the files tree. ! !---------------------------------------------------------------------------------------! subroutine resume_from_history() - use ed_max_dims , only : n_pft & ! intent(in) - , str_len ! ! intent(in) - use ed_misc_coms , only : sfilin & ! intent(in) - , current_time & ! intent(in) - , max_poihist_dist ! ! intent(in) - use ed_state_vars , only : polygontype & ! structure - , sitetype & ! structure - , patchtype & ! structure - , edtype & ! structure - , edgrid_g & ! structure - , allocate_sitetype & ! subroutine - , allocate_patchtype & ! subroutine - , allocate_polygontype ! ! subroutine - use soil_coms , only : alloc_soilgrid ! ! subroutine - use grid_coms , only : ngrids ! ! intent(in) - use phenology_startup, only : phenology_init ! ! subroutine - use ed_node_coms , only : mynum ! ! intent(in) + use ed_max_dims , only : n_pft & ! intent(in) + , str_len & ! intent(in) + , ed_nstyp & ! intent(in) + , undef_real ! ! intent(in) + use ed_misc_coms , only : sfilin & ! intent(in) + , current_time & ! intent(in) + , max_poihist_dist ! ! intent(in) + use ed_state_vars , only : polygontype & ! structure + , sitetype & ! structure + , patchtype & ! structure + , edtype & ! structure + , edgrid_g & ! structure + , allocate_sitetype & ! subroutine + , allocate_patchtype & ! subroutine + , allocate_polygontype ! ! subroutine + use grid_coms , only : ngrids & ! intent(in) + , nzg & ! intent(out) + , nzs ! ! intent(out) + use soil_coms , only : slz & ! intent(out) + , slhydro_ref & ! intent(out) + , slxclay_ref & ! intent(out) + , slxsilt_ref & ! intent(out) + , slxsand_ref & ! intent(out) + , slsoc_ref & ! intent(out) + , slph_ref & ! intent(out) + , slcec_ref & ! intent(out) + , sldbd_ref & ! intent(out) + , alloc_soilgrid ! ! sub-routine + use fusion_fission_coms, only : ff_nhgt & ! intent(in) + , hgt_class ! ! intent(in) + use phenology_startup , only : phenology_init ! ! subroutine + use ed_node_coms , only : mynum & ! intent(in) + , nnodetot ! ! intent(in) + use ed_init , only : sfcdata_ed ! ! sub-routine use hdf5 - use hdf5_coms , only : file_id & ! intent(inout) - , dset_id & ! intent(inout) - , dspace_id & ! intent(inout) - , globdims & ! intent(inout) - , chnkdims & ! intent(inout) - , chnkoffs ! ! intent(inout) - use landuse_init , only : read_landuse_matrix ! ! intent(in) + use hdf5_coms , only : file_id & ! intent(inout) + , dset_id & ! intent(inout) + , dspace_id & ! intent(inout) + , globdims & ! intent(inout) + , chnkdims & ! intent(inout) + , chnkoffs ! ! intent(inout) + use landuse_init , only : read_landuse_matrix ! ! sub-routine implicit none !------ Local variables. ------------------------------------------------------------! type(edtype) , pointer :: cgrid @@ -88,6 +105,7 @@ subroutine resume_from_history() write (unit=*,fmt='(a)') '-----------------------------------------------------' write (unit=*,fmt='(a)') ' Loading Full State (HISTORY)' + write (unit=*,fmt='(a)') '-----------------------------------------------------' !----- Open the HDF environment. ----------------------------------------------------! @@ -133,6 +151,182 @@ subroutine resume_from_history() ,'resume_from_history','ed_init_history.f90') end if end if + !---------------------------------------------------------------------------------! + + + + + !---------------------------------------------------------------------------------! + ! If this is the first grid, we read global dimensions and vectors. ! + !---------------------------------------------------------------------------------! + select case (ngr) + case (1) + if (mynum == nnodetot) write (unit=*,fmt='(a)') & + ' [-] Load global dimensions...' + + !------------------------------------------------------------------------------! + ! Retrieve global vector sizes. This includes the number of soil and snow ! + ! layers, and the number of height classes for patch fusion. ! + ! ! + ! Note: if running HISTORY, this will overwrite the ED2IN settings. It is ! + ! not anyway a good idea to change settings in simulations using ! + ! HISTORY (you can always have a "soft" initialisation for forest ! + ! structure only, using RUNTYPE='INITIAL' and IED_INIT_MODE=5, and this ! + ! would allow you to change as many settings as you want, and likely ! + ! even different versions of code if you dare. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = 1_8 + + call h5dopen_f(file_id,'NZG', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,nzg,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'NZS', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,nzs,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'FF_NHGT', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,ff_nhgt,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Retrieve soil layers. These will overwrite ED2IN settings if they are ! + ! different. It is very unwise to change the soil grid during a HISTORY run. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(nzg,8) + + slz(:) = undef_real + call h5dopen_f(file_id,'SLZ', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slz(1:nzg),globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Height classes for patch fusion. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(ff_nhgt,8) + + if (allocated(hgt_class)) deallocate(hgt_class) + allocate(hgt_class(ff_nhgt)) + call h5dopen_f(file_id,'HGT_CLASS', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,hgt_class,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Retrieve default soil characteristics (texture and approach). This will ! + ! effectively supersede the ISOIL_HYDRO settings (it's not wise to change ! + ! settings in the middle of a simulation). ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(ed_nstyp,8) + + call h5dopen_f(file_id,'SLHYDRO_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,slhydro_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXSAND_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxsand_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXSILT_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxsilt_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXCLAY_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxclay_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLSOC_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slsoc_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLPH_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slph_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLCEC_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slcec_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLDBD_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,sldbd_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Allocate soil grid arrays. ! + !------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [-] Alloc_Soilgrid...' + call alloc_soilgrid() + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise variables that are related to soil layers. ! + !------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [-] Sfcdata_ED...' + call sfcdata_ed() + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! @@ -424,13 +618,13 @@ subroutine resume_from_history() !----- Load the anthropogenic disturbance (or set them all to zero). ----------------! - write(unit=*,fmt='(a,i2.2)') ' Checking anthropogenic disturbance. Node: ',mynum + write(unit=*,fmt='(a,i2.2)') ' Loading anthropogenic disturbance. Node: ',mynum call read_landuse_matrix() !------------------------------------------------------------------------------------! !----- Load phenology in case it is prescribed (or set them with defaults). ---------! - write(unit=*,fmt='(a,i2.2)') ' Checking prescribed phenology. Node: ',mynum + write(unit=*,fmt='(a,i2.2)') ' Loading prescribed phenology. Node: ',mynum call phenology_init() return @@ -1004,6 +1198,8 @@ subroutine fill_history_grid_p11dmean(cgrid,ipy,py_index) ,'DMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_sfcw_fliq (ipy:ipy) & ,'DMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%dmean_snowfac (ipy:ipy) & + ,'DMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_rshort_gnd (ipy:ipy) & ,'DMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_par_gnd (ipy:ipy) & @@ -1432,6 +1628,8 @@ subroutine fill_history_grid_p11mmean(cgrid,ipy,py_index) ,'MMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_sfcw_fliq (ipy:ipy) & ,'MMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%mmean_snowfac (ipy:ipy) & + ,'MMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_rshort_gnd (ipy:ipy) & ,'MMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_par_gnd (ipy:ipy) & @@ -2055,6 +2253,8 @@ subroutine fill_history_grid_m11(cgrid,ipy,py_index) ,'QMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_sfcw_fliq (:,ipy) & ,'QMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%qmean_snowfac (:,ipy) & + ,'QMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_rshort_gnd (:,ipy) & ,'QMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_par_gnd (:,ipy) & @@ -3257,8 +3457,8 @@ subroutine fill_history_polygon(cpoly,pysi_index,nsites_global,nsites_now,is_bur memoffs (2) = 0_8 call hdf_getslab_r(cpoly%lambda_fire & ,'LAMBDA_FIRE ',dsetrank,iparallel,.true.,foundvar) - call hdf_getslab_r(cpoly%avg_monthly_pcpg & - ,'AVG_MONTHLY_PCPG ',dsetrank,iparallel,.true.,foundvar) + call hdf_getslab_r(cpoly%avg_monthly_accp & + ,'AVG_MONTHLY_ACCP ',dsetrank,iparallel,.true.,foundvar) call hdf_getslab_r(cpoly%crop_yield & ,'CROP_YIELD_SI ',dsetrank,iparallel,.true.,foundvar) !------------------------------------------------------------------------------------! @@ -4069,6 +4269,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'DMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_sfcw_fliq & ,'DMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%dmean_snowfac & + ,'DMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_rshort_gnd & ,'DMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_par_gnd & @@ -4238,6 +4440,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'MMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_sfcw_fliq & ,'MMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%mmean_snowfac & + ,'MMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_rshort_gnd & ,'MMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_par_gnd & @@ -4443,6 +4647,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'QMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_sfcw_fliq & ,'QMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%qmean_snowfac & + ,'QMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_rshort_gnd & ,'QMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_par_gnd & @@ -5691,6 +5897,8 @@ subroutine fill_history_patch(cpatch,paco_index,ncohorts_global) memdims (2) = int(cpatch%ncohorts,8) memsize (2) = int(cpatch%ncohorts,8) memoffs (2) = 0_8 + call hdf_getslab_r(cpatch%root_frac & + ,'ROOT_FRAC ',dsetrank,iparallel,.true. ,foundvar) call hdf_getslab_r(cpatch%wflux_gw_layer & ,'WFLUX_GW_LAYER ',dsetrank,iparallel,.true. ,foundvar) if (writing_long) then diff --git a/ED/src/io/ed_load_namelist.f90 b/ED/src/io/ed_load_namelist.f90 index 37a430c8b..e5967bc04 100644 --- a/ED/src/io/ed_load_namelist.f90 +++ b/ED/src/io/ed_load_namelist.f90 @@ -659,11 +659,6 @@ subroutine copy_nl(copy_type) imontha = nl%imontha iyeara = nl%iyeara - nzg = nl%nzg - nzs = nl%nzs - - slz(1:nzgmax) = nl%slz(1:nzgmax) - !------------------------------------------------------------------------------------! ! Set current time to initial time here. If this is a history run, reset ! ! current time in subroutine history_start. ! diff --git a/ED/src/io/ed_opspec.F90 b/ED/src/io/ed_opspec.F90 index 1011fcf90..210c4255c 100644 --- a/ED/src/io/ed_opspec.F90 +++ b/ED/src/io/ed_opspec.F90 @@ -51,6 +51,7 @@ subroutine ed_opspec_grid , ed_reg_lonmin & ! intent(in) , ed_reg_lonmax ! ! intent(in) use soil_coms , only : slz ! ! intent(in) + use ed_misc_coms, only : runtype ! ! intent(in) implicit none !----- Local variables. ----------------------------------------------------------------! @@ -285,60 +286,67 @@ subroutine ed_opspec_grid end if !---------------------------------------------------------------------------------------! - ! Check whether ED soil layers are reasonable, i.e, enough layers, sorted from the ! - ! deepest to the shallowest. ! + ! The checks on surface and snow settings should be made only for INITIAL runs. ! !---------------------------------------------------------------------------------------! - if (nzg < 2) then - write (reason,'(a,1x,i4,a)') & - 'Too few soil layers. Set it to at least 2. Your nzg is currently set to' & - ,nzg,'...' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - elseif (nzg > nzgmax) then - write (reason,'(2(a,1x,i5,a))') & - 'The number of soil layers cannot be greater than ',nzgmax,'.' & - ,' Your nzg is currently set to',nzg,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - end if - do k=1,nzg - if (slz(k) > -.001) then - write (reason,'(a,1x,i4,1x,a,1x,es14.7,a)') & - 'Your soil level #',k,'is not enough below ground. It is currently set to' & - ,slz(k),', make it deeper than -0.001...' + select case (trim(runtype)) + case ('INITIAL') + !------------------------------------------------------------------------------------! + ! Check whether ED soil layers are reasonable, i.e, enough layers, sorted from ! + ! the deepest to the shallowest. ! + !------------------------------------------------------------------------------------! + if (nzg < 2) then + write (reason,'(a,1x,i4,a)') & + 'Too few soil layers. Set it to at least 2. Your nzg is currently set to' & + ,nzg,'...' call opspec_fatal(reason,'opspec_grid') ifaterr=ifaterr+1 + elseif (nzg > nzgmax) then + write (reason,'(2(a,1x,i5,a))') & + 'The number of soil layers cannot be greater than ',nzgmax,'.' & + ,' Your nzg is currently set to',nzg,'.' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 end if - end do + do k=1,nzg + if (slz(k) > -.001) then + write (reason,'(a,1x,i4,1x,a,1x,es14.7,a)') & + 'Your soil level #',k,'is too thin. It is currently set to',slz(k) & + ,', make it deeper than -0.001...' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 + end if + end do + + do k=1,nzg-1 + if (slz(k)-slz(k+1) > .001) then + write (reason,'(2(a,1x,i4,1x),a,2x,a,1x,es14.7,1x,a,1x,es14.7,a)') & + 'Soil layers #',k,'and',k+1,'are not enough apart (i.e. > 0.001).' & + ,'They are currently set as ',slz(k),'and',slz(k+1),'...' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 + end if + end do - do k=1,nzg-1 - if (slz(k)-slz(k+1) > .001) then - write (reason,'(2(a,1x,i4,1x),a,2x,a,1x,es14.7,1x,a,1x,es14.7,a)') & - 'Soil layers #',k,'and',k+1,'are not enough apart (i.e. > 0.001).' & - ,'They are currently set as ',slz(k),'and',slz(k+1),'...' + + !------------------------------------------------------------------------------------! + ! Check whether ED snow layers are well set, i.e., the number of soil levels is ! + ! within the allowed range. ! + !------------------------------------------------------------------------------------! + if (nzs < 1) then + write (reason,'(a,2x,a,1x,i4,a)') & + 'Too few maximum # of snow layers. Set it to at least 1.' & + ,'Your nzs is currently set to',nzs,'.' call opspec_fatal(reason,'opspec_grid') ifaterr=ifaterr+1 + elseif (nzs > nzsmax) then + write (reason,'(2(a,1x,i5,a))') & + 'The number of snow layers cannot be greater than ',nzsmax,'.' & + ,' Your nzs is currently set to',nzs,'.' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 end if - end do - - - !---------------------------------------------------------------------------------------! - ! Check whether ED snow layers are well set, i.e., the number of soil levels is ! - ! within the allowed range. ! - !---------------------------------------------------------------------------------------! - if (nzs < 1) then - write (reason,'(a,2x,a,1x,i4,a)') & - 'Too few maximum # of snow layers. Set it to at least 1.' & - ,'Your nzs is currently set to',nzs,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - elseif (nzs > nzsmax) then - write (reason,'(2(a,1x,i5,a))') & - 'The number of snow layers cannot be greater than ',nzsmax,'.' & - ,' Your nzs is currently set to',nzs,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - end if + !------------------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------------------! @@ -1145,6 +1153,8 @@ end subroutine ed_opspec_times !------------------------------------------------------------------------------------------! subroutine ed_opspec_misc use ed_max_dims , only : n_pft & ! intent(in) + , ed_nstyp & ! intent(in) + , ed_nscol & ! intent(in) , str_len & ! intent(in) , skip_integer & ! intent(in) , skip_real ! ! intent(in) @@ -1189,9 +1199,7 @@ subroutine ed_opspec_misc , lwidth_nltree & ! intent(in) , ribmax & ! intent(in) , leaf_maxwhc ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) - , ed_nscol & ! intent(in) - , isoilflg & ! intent(in) + use soil_coms , only : isoilflg & ! intent(in) , islcolflg & ! intent(in) , nslcon & ! intent(in) , isoilcol & ! intent(in) @@ -1263,6 +1271,7 @@ subroutine ed_opspec_misc , sl_mindbh_harvest & ! intent(in) , sl_biomass_harvest & ! intent(in) , sl_skid_rel_area & ! intent(in) + , sl_skid_dbh_thresh & ! intent(in) , sl_skid_s_gtharv & ! intent(in) , sl_skid_s_ltharv & ! intent(in) , sl_felling_s_ltharv & ! intent(in) @@ -1440,7 +1449,8 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (ied_init_mode == -8) then + select case (ied_init_mode) + case (-8) !------------------------------------------------------------------------------------! ! The special 8-layer model works only in size- and age-structured runs. ! !------------------------------------------------------------------------------------! @@ -1471,20 +1481,22 @@ subroutine ed_opspec_misc write (unit=*,fmt='(a)') ' simulations only. If that''s not what you wanted, change ' write (unit=*,fmt='(a)') ' your IED_INIT_MODE variable on your ED2IN. ' write (unit=*,fmt='(a)') '===========================================================' - elseif ((ied_init_mode < -1 .or. ied_init_mode > 7) .and. & - (ied_init_mode /= 99 )) then + case (-1:8,99) + !----- Valid options, do nothing. ---------------------------------------------------! + continue + !------------------------------------------------------------------------------------! + case default write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IED_INIT_MODE, it must be between -1 and 7. Yours is set to' & + 'Invalid IED_INIT_MODE, it must be between -1 and 8. Yours is set to' & ,ied_init_mode,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 - end if + end select - if (ied_init_mode == 7 .and. isoilstateinit>0 ) then - write (reason,fmt='(a)') & - 'Please set ISOILSTATEINIT=0 if using IED_INIT_MODE=7' + if (ied_init_mode == 7 .and. isoilstateinit > 0) then + write (reason,fmt='(a)') 'Please set ISOILSTATEINIT = 0 if using IED_INIT_MODE = 7.' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 end if @@ -1631,9 +1643,9 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (isoilbc < 0 .or. isoilbc > 3) then + if (isoilbc < -1 .or. isoilbc > 3) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid ISOILBC, it must be between 0 and 3. Yours is set to',isoilbc,'...' + 'Invalid ISOILBC, it must be between -1 and 3. Yours is set to',isoilbc,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 else if(isoilbc == 2 .and. (sldrain < 0. .or. sldrain > 90.)) then @@ -1841,9 +1853,9 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (iallom < 0 .or. iallom > 4) then + if (iallom < 0 .or. iallom > 5) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IALLOM, it must be between 0 and 4. Yours is set to' & + 'Invalid IALLOM, it must be between 0 and 5. Yours is set to' & ,iallom,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 @@ -1872,9 +1884,9 @@ subroutine ed_opspec_misc end if - if (iphen_scheme < -1 .or. iphen_scheme > 4) then + if (iphen_scheme < -1 .or. iphen_scheme > 5) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IPHEN_SCHEME, it must be between -1 and 4. Yours is set to' & + 'Invalid IPHEN_SCHEME, it must be between -1 and 5. Yours is set to' & ,iphen_scheme,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 @@ -1893,7 +1905,7 @@ subroutine ed_opspec_misc ! model may be linear or log-linear. Don't bother checking if IPHEN_SCHEME is not 3. ! !---------------------------------------------------------------------------------------! select case (iphen_scheme) - case (3) + case (3,5) !----- Light-driven phenology is enabled. Check settings. --------------------------! select case (economics_scheme) case (1) @@ -2387,7 +2399,15 @@ subroutine ed_opspec_misc write (reason,fmt='(2a,1x,es12.5,a)') & 'Invalid SL_SKID_REL_AREA, it must be between 0. and 5.' & ,' Yours is set to',sl_skid_rel_area,'...' - call opspec_fatal(reason,'opspec_misc') + call opspec_fatal(reason,'opspec_misc') + ifaterr = ifaterr +1 + end if + + if (sl_skid_dbh_thresh < 0. .or. sl_skid_dbh_thresh > 1000.) then + write (reason,fmt='(2a,1x,es12.5,a)') & + 'Invalid SL_SKID_DBH_THRESH, it must be between 0. and 1000.' & + ,' Yours is set to',sl_skid_dbh_thresh,'...' + call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 end if @@ -2395,7 +2415,7 @@ subroutine ed_opspec_misc write (reason,fmt='(2a,1x,es12.5,a)') & 'Invalid SL_SKID_S_GTHARV, it must be between 0. and 1.' & ,' Yours is set to',sl_skid_s_gtharv,'...' - call opspec_fatal(reason,'opspec_misc') + call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 end if @@ -2403,7 +2423,7 @@ subroutine ed_opspec_misc write (reason,fmt='(2a,1x,es12.5,a)') & 'Invalid SL_SKID_S_LTHARV, it must be between 0. and 1.' & ,' Yours is set to',sl_skid_s_ltharv,'...' - call opspec_fatal(reason,'opspec_misc') + call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 end if diff --git a/ED/src/io/ed_print.F90 b/ED/src/io/ed_print.F90 index aeb2115b8..33f5a51a7 100644 --- a/ED/src/io/ed_print.F90 +++ b/ED/src/io/ed_print.F90 @@ -30,6 +30,7 @@ module ed_print subroutine print_fields(ifm,cgrid) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum & ! intent(in) @@ -49,10 +50,6 @@ subroutine print_fields(ifm,cgrid) , num_var ! ! intent(in) use ed_max_dims , only : str_len_short ! ! intent(in) implicit none - !----- Standard common blocks. ------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. -------------------------------------------------------------------! integer , intent(in) :: ifm type(edtype) , target :: cgrid diff --git a/ED/src/io/ed_read_ed10_20_history.f90 b/ED/src/io/ed_read_ed10_20_history.f90 index 083c6e93e..e1b0ef959 100644 --- a/ED/src/io/ed_read_ed10_20_history.f90 +++ b/ED/src/io/ed_read_ed10_20_history.f90 @@ -881,12 +881,18 @@ subroutine read_ed10_ed20_history_file end select !------------------------------------------------------------------! + !------------------------------------------------------------------! - ! Initialise SLA with the look-up table value, this may be ! - ! updated during phenology initialisation, but an initial assign- ! - ! ment is needed to obtain area indices. ! + ! Initialise SLA, Vm0, Rd0, and with the look-up table value. ! + ! These variables may be updated during phenology initialisation, ! + ! or trait plasticity, but they must have an initial assignment so ! + ! we can even calculate the initial area indices and inicial trait ! + ! values needed for the trait update. ! !------------------------------------------------------------------! - cpatch%sla(ic2) = SLA(ipft(ic)) + cpatch%sla (ic2) = SLA (ipft(ic)) + cpatch%vm_bar(ic2) = Vm0 (ipft(ic)) + cpatch%rd_bar(ic2) = Rd0 (ipft(ic)) + cpatch%llspan(ic2) = leaf_lifespan(ipft(ic)) !------------------------------------------------------------------! diff --git a/ED/src/io/ed_read_ed21_history.f90 b/ED/src/io/ed_read_ed21_history.f90 index 3e84faf03..bba663ff7 100644 --- a/ED/src/io/ed_read_ed21_history.f90 +++ b/ED/src/io/ed_read_ed21_history.f90 @@ -691,36 +691,52 @@ subroutine read_ed21_history_file !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4)) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! @@ -2082,36 +2098,52 @@ subroutine read_ed21_history_unstruct !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if (iallom == 3 .or. iallom == 4) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! @@ -3456,36 +3488,52 @@ subroutine read_ed21_polyclone !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if (iallom == 3 .or. iallom == 4) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! diff --git a/ED/src/io/ed_read_ed22_initial.f90 b/ED/src/io/ed_read_ed22_initial.f90 new file mode 100644 index 000000000..bcdd1a5ef --- /dev/null +++ b/ED/src/io/ed_read_ed22_initial.f90 @@ -0,0 +1,1339 @@ +!==========================================================================================! +!==========================================================================================! +! This subroutine reads ED-2.2 initial files. The format is very similar to the ! +! ED-1.0/ED-2.0 "history" format, except that it has additional fields to initialise the ! +! necromass, and a site file. ! +!------------------------------------------------------------------------------------------! +subroutine read_ed22_initial_file + + use ed_max_dims , only : n_pft & ! intent(in) + , huge_site & ! intent(in) + , huge_patch & ! intent(in) + , huge_cohort & ! intent(in) + , max_water & ! intent(in) + , str_len & ! intent(in) + , maxfiles & ! intent(in) + , maxlist & ! intent(in) + , undef_character & ! intent(in) + , undef_integer & ! intent(in) + , undef_real ! ! intent(in) + use pft_coms , only : q & ! intent(in) + , qsw & ! intent(in) + , qbark & ! intent(in) + , SLA & ! intent(in) + , min_dbh & ! intent(in) + , is_grass & ! intent(in) + , include_pft & ! intent(in) + , include_pft_ag & ! intent(in) + , pft_1st_check & ! intent(in) + , agf_bs & ! intent(in) + , f_bstorage_init & ! intent(in) + , include_these_pft & ! intent(in) + , leaf_turnover_rate & ! intent(in) + , vm0 & ! intent(in) + , rd0 & ! intent(in) + , negligible_nplant ! ! intent(in) + use ed_misc_coms , only : sfilin ! ! intent(in) + use consts_coms , only : pio180 & ! intent(in) + , pio4 & ! intent(in) + , almost_zero & ! intent(in) + , tiny_num ! ! intent(in) + use ed_misc_coms , only : use_target_year & ! intent(in) + , restart_target_year ! ! intent(in) + use ed_state_vars , only : polygontype & ! variable type + , sitetype & ! variable type + , patchtype & ! variable type + , edtype & ! variable type + , edgrid_g & ! variable type + , allocate_polygontype & ! subroutine + , allocate_sitetype & ! subroutine + , allocate_patchtype ! ! subroutine + use grid_coms , only : ngrids & ! intent(in) + , nzg ! ! intent(in) + use soil_coms , only : soil_hydro_scheme & ! intent(in) + , slz & ! intent(in) + , slxkey_ref & ! intent(inout) + , slxsand_ref & ! intent(inout) + , slxsilt_ref & ! intent(inout) + , slxclay_ref & ! intent(inout) + , slhydro_ref & ! intent(inout) + , slsoc_ref & ! intent(inout) + , slph_ref & ! intent(inout) + , slcec_ref & ! intent(inout) + , sldbd_ref & ! intent(inout) + , ed_gen_soil_table ! ! subroutine + use allometry , only : bd2dbh & ! function + , dbh2h & ! function + , size2bd & ! function + , size2bl & ! function + , size2bt & ! function + , size2xb & ! function + , ed_balive & ! function + , ed_biomass & ! function + , area_indices ! ! subroutine + use fuse_fiss_utils , only : sort_cohorts & ! subroutine + , sort_patches ! ! subroutine + use decomp_coms , only : decomp_scheme & ! intent(in) + , c2n_structural ! ! intent(in) + use phenology_coms , only : llspan_inf ! ! intent(in) + use physiology_coms , only : iddmort_scheme & ! intent(in) + , trait_plasticity_scheme ! ! intent(in) + use update_derived_utils, only : update_cohort_plastic_trait ! ! subroutine + use ed_init , only : soil_default_fill & ! sub-routine + , sfcdata_ed ! ! sub-routine + use ed_type_init , only : init_ed_cohort_vars & ! subroutine + , init_ed_patch_vars & ! subroutine + , init_ed_site_vars & ! subroutine + , init_ed_poly_vars ! ! subroutine + use ed_init , only : calc_flow_routing ! ! subroutine + implicit none + + !----- Local constants. ----------------------------------------------------------------! + real(kind=8), parameter :: min_area = 1.d-7 ! Minimum acceptable area. + real(kind=8), parameter :: min_ok = 1.d-20 ! Minimum acceptable value for + ! any restart variable. + !----- Local variables. ----------------------------------------------------------------! + type(edtype) , pointer :: cgrid + type(polygontype) , pointer :: cpoly + type(sitetype) , pointer :: csite + type(patchtype) , pointer :: cpatch + character(len=str_len), dimension(maxlist) :: full_list + character(len=str_len), dimension(maxfiles) :: sss_list + character(len=str_len), dimension(maxfiles) :: pss_list + character(len=str_len), dimension(maxfiles) :: css_list + character(len=str_len), dimension(huge_site) :: sname + character(len=str_len), dimension(huge_patch) :: psname + character(len=str_len), dimension(huge_patch) :: pname + character(len=str_len), dimension(huge_cohort) :: csname + character(len=str_len), dimension(huge_cohort) :: cpname + character(len=str_len), dimension(huge_cohort) :: cname + character(len=str_len) :: sss_name + character(len=str_len) :: pss_name + character(len=str_len) :: css_name + character(len=str_len) :: cdum + integer , dimension(huge_site) :: nscol + integer , dimension(huge_site) :: ntext + integer , dimension(huge_site) :: lsl + integer , dimension(huge_site) :: patch_count + integer , dimension(huge_site) :: last_ipa + integer , dimension(huge_patch) :: dtype + integer , dimension(huge_patch) :: psite_id + integer , dimension(huge_patch) :: ppatch_id + integer , dimension(huge_patch) :: cohort_count + integer , dimension(huge_patch) :: last_ico + integer , dimension(huge_cohort) :: ipft + integer , dimension(huge_cohort) :: cpatch_id + integer , dimension(huge_cohort) :: csite_id + integer :: year + integer :: igr + integer :: ipy + integer :: gsi + integer :: gpa + integer :: gco + integer :: isi + integer :: ipa + integer :: ico + integer :: apa + integer :: aco + integer :: ierr + integer :: nf + integer :: nflist + integer :: nflsss + integer :: nflpss + integer :: nflcss + integer :: nclosest + integer :: ncohorts + integer :: npatches + integer :: nsites + logical , dimension(n_pft) :: discarded_pft + logical , dimension(:) , allocatable :: shmask + logical :: single_poi + real(kind=8) :: darea + real , dimension(huge_site) :: s_area + real , dimension(huge_site) :: depth + real , dimension(huge_site) :: sand + real , dimension(huge_site) :: clay + real , dimension(huge_site) :: slsoc + real , dimension(huge_site) :: slph + real , dimension(huge_site) :: slcec + real , dimension(huge_site) :: sldbd + real , dimension(huge_site) :: elevation + real , dimension(huge_site) :: slope + real , dimension(huge_site) :: aspect + real , dimension(huge_site) :: tci + real , dimension(huge_site) :: moist_f + real , dimension(huge_site) :: moist_w + real , dimension(huge_patch) :: time + real , dimension(huge_patch) :: age + real , dimension(huge_patch) :: p_area + real , dimension(huge_patch) :: fgc + real , dimension(huge_patch) :: fsc + real , dimension(huge_patch) :: stgc + real , dimension(huge_patch) :: stgl + real , dimension(huge_patch) :: stsc + real , dimension(huge_patch) :: stsl + real , dimension(huge_patch) :: msc + real , dimension(huge_patch) :: ssc + real , dimension(huge_patch) :: psc + real , dimension(huge_patch) :: fsn + real , dimension(huge_patch) :: msn + real , dimension(huge_cohort) :: balive + real , dimension(huge_cohort) :: bdead + real , dimension(huge_cohort) :: nplant + real , dimension(huge_cohort) :: hite + real , dimension(huge_cohort) :: dbh + real , dimension(huge_cohort) :: ctime + real , dimension(maxfiles) :: slon_list + real , dimension(maxfiles) :: slat_list + real , dimension(maxfiles) :: plon_list + real , dimension(maxfiles) :: plat_list + real , dimension(maxfiles) :: clon_list + real , dimension(maxfiles) :: clat_list + real , dimension(maxfiles) :: file_sdist + real , dimension(maxfiles) :: file_pdist + real , dimension(maxfiles) :: file_cdist + real , dimension(n_pft) :: leaf_lifespan + real , dimension(:) , allocatable :: ed_slz + real :: dummy + real :: area_sum + !----- External function. --------------------------------------------------------------! + real , external :: sngloff + real , external :: dist_gc + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Define PFT-dependent leaf life span, used for initialisation. ! + !---------------------------------------------------------------------------------------! + leaf_lifespan(:) = merge( 12.0 / leaf_turnover_rate(:) & + , llspan_inf & + , leaf_turnover_rate(:) > 0.0 ) + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Allocate temporary variables used during initialisation. ! + !---------------------------------------------------------------------------------------! + allocate(shmask(nzg)) + allocate(ed_slz(nzg)) + shmask(:) = .false. + ed_slz(:) = slz(1:nzg) + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Now we loop over all all grids and polygons, and fill them with patches and ! + ! cohorts from the closest polygon. ! + !---------------------------------------------------------------------------------------! + main_gridloop: do igr = 1,ngrids + cgrid => edgrid_g(igr) + + !----- Retrieve all files with the specified prefix. --------------------------------! + call ed_filelist(full_list,sfilin(igr),nflist) + !------------------------------------------------------------------------------------! + + !----- Retrieve LON/LAT information for sites, patches and cohorts ------------------! + call ed1_fileinfo('.sss',nflist,full_list,nflsss,sss_list,slon_list,slat_list) + call ed1_fileinfo('.pss',nflist,full_list,nflpss,pss_list,plon_list,plat_list) + call ed1_fileinfo('.css',nflist,full_list,nflcss,css_list,clon_list,clat_list) + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Save logical flag to decide whether or not this is a single-grid, single- ! + ! -polygon simulation. This information allows us to change the default soil ! + ! properties so they are site-specific. ! + !------------------------------------------------------------------------------------! + single_poi = (ngrids == 1) .and. (cgrid%npolygons == 1) + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Loop through every polygon. ! + !------------------------------------------------------------------------------------! + main_polyloop: do ipy = 1,cgrid%npolygons + cpoly => cgrid%polygon(ipy) + + !----- Initialise load adjacency with dummy value. -------------------------------! + cgrid%load_adjacency(ipy) = 0 + cgrid%wbar (ipy) = 0.0 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Reset patch and cohort count. ! + !---------------------------------------------------------------------------------! + patch_count (:) = 0 + cohort_count(:) = 0 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Initialise the distances as very large numbers, so if we don't fill all the ! + ! patches and cohorts, we will not going to take non-sense as a valid polygon. ! + !---------------------------------------------------------------------------------! + file_sdist(:) = 1.e20 + file_pdist(:) = 1.e20 + file_cdist(:) = 1.e20 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Reset the other placeholder variables. ! + !---------------------------------------------------------------------------------! + !------ Site-level variables. ----------------------------------------------------! + sname (:) = undef_character + nscol (:) = undef_integer + ntext (:) = undef_integer + lsl (:) = undef_integer + patch_count (:) = undef_integer + dtype (:) = undef_integer + s_area (:) = undef_real + depth (:) = undef_real + sand (:) = undef_real + clay (:) = undef_real + slsoc (:) = undef_real + slph (:) = undef_real + slcec (:) = undef_real + sldbd (:) = undef_real + elevation (:) = undef_real + slope (:) = undef_real + aspect (:) = undef_real + tci (:) = undef_real + moist_f (:) = undef_real + moist_w (:) = undef_real + !------ Patch-level variables. ---------------------------------------------------! + psname (:) = undef_character + pname (:) = undef_character + psite_id (:) = undef_integer + ppatch_id (:) = undef_integer + cohort_count (:) = undef_integer + time (:) = undef_real + age (:) = undef_real + p_area (:) = undef_real + fgc (:) = undef_real + fsc (:) = undef_real + stgc (:) = undef_real + stgl (:) = undef_real + stsc (:) = undef_real + stsl (:) = undef_real + msc (:) = undef_real + ssc (:) = undef_real + psc (:) = undef_real + fsn (:) = undef_real + msn (:) = undef_real + !------ Cohort-level variables. --------------------------------------------------! + csname (:) = undef_character + cpname (:) = undef_character + cname (:) = undef_character + csite_id (:) = undef_integer + cpatch_id (:) = undef_integer + ipft (:) = undef_integer + balive (:) = undef_real + bdead (:) = undef_real + nplant (:) = undef_real + hite (:) = undef_real + dbh (:) = undef_real + ctime (:) = undef_real + !---------------------------------------------------------------------------------! + + + + + + !---------------------------------------------------------------------------------! + ! Compute the distances between every polygon in the initial files and the ! + ! current polygon. ! + !---------------------------------------------------------------------------------! + do nf=1,nflsss + file_sdist(nf) = dist_gc(cgrid%lon(ipy),slon_list(nf) & + ,cgrid%lat(ipy),slat_list(nf) ) + end do + do nf=1,nflpss + file_pdist(nf) = dist_gc(cgrid%lon(ipy),plon_list(nf) & + ,cgrid%lat(ipy),plat_list(nf) ) + end do + do nf=1,nflcss + file_cdist(nf) = dist_gc(cgrid%lon(ipy),clon_list(nf) & + ,cgrid%lat(ipy),clat_list(nf) ) + end do + !---------------------------------------------------------------------------------! + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read site file. ! + !---------------------------------------------------------------------------------! + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(file_sdist,dim=1) + sss_name = trim(sss_list(nclosest)) + write (unit=*,fmt='(2a)') '+ Using site file: ',trim(sss_name) + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Open the patch file and read skip the header. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(sss_name),form='formatted',status='old',action='read') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Now we loop over all patches and decide whether they should be included or ! + ! not. ! + !---------------------------------------------------------------------------------! + gsi = 1 + read_sites: do + + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of sites ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gsi > huge_site) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(sss_name) + write (unit=*,fmt='(a)') ' Number of sites is > HUGE_SITE...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_SITE:',huge_site + write (unit=*,fmt='(a)') ' Increase HUGE_SITE to read this...' + call fatal_error('Too many patches to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + !----- Read line. Exit loop when finished reading sites. ---------------------! + read(unit=12,fmt=*,iostat=ierr) sname(gsi),darea,depth(gsi),nscol(gsi) & + ,ntext(gsi),sand(gsi),clay(gsi),slsoc(gsi) & + ,slph(gsi),slcec(gsi),sldbd(gsi),elevation(gsi) & + ,slope(gsi),aspect(gsi),tci(gsi),moist_f(gsi) & + ,moist_w(gsi) + if (ierr /= 0) exit read_sites + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Add site only if the area is above minimum, we avoid including ! + ! sites that are tiny since they will be overwritten by the next site. ! + !------------------------------------------------------------------------------! + s_area(gsi) = sngloff(darea, min_area) + if (s_area(gsi) > min_area) gsi = gsi + 1 + !------------------------------------------------------------------------------! + end do read_sites + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of sites. We also make sure that there is at ! + ! least one valid site, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + nsites = gsi - 1 + if (nsites <= 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(sss_name) + write (unit=*,fmt='(a)') ' Invalid number of sites: ',nsites + write (unit=*,fmt='(a)') ' File is probably corrupted...' + else + !------ Make sure the sum of site areas is 1. ---------------------------------! + area_sum = sum(s_area(1:nsites)) + s_area(1:nsites) = s_area(1:nsites) / area_sum + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read patch file. ! + !---------------------------------------------------------------------------------! + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(file_pdist,dim=1) + pss_name = trim(pss_list(nclosest)) + write (unit=*,fmt='(2a)') 'Using patch file: ',trim(pss_name) + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Open the patch file and skip the header. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(pss_name),form='formatted',status='old',action='read') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop over all patches and decide whether they should be included or not. ! + !---------------------------------------------------------------------------------! + gpa = 1 + read_patches: do + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of patches ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gpa > huge_patch) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Number of patches is > HUGE_PATCH...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_PATCH:',huge_patch + write (unit=*,fmt='(a)') ' Increase HUGE_PATCH to read this...' + call fatal_error('Too many patches to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + + !----- Read line. Exit loop when finished reading patches. -------------------! + read(unit=12,fmt=*,iostat=ierr) time(gpa),psname(gpa),pname(gpa),dtype(gpa) & + ,age(gpa),darea,fgc(gpa),fsc(gpa),stgc(gpa) & + ,stgl(gpa),stsc(gpa),stsl(gpa),msc(gpa) & + ,ssc(gpa),psc(gpa),fsn(gpa),msn(gpa) & + ,dummy,dummy,dummy,dummy + if (ierr /= 0) exit read_patches + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Add site only if the area is above minimum, we avoid including ! + ! sites that are tiny since they will be overwritten by the next site. ! + !------------------------------------------------------------------------------! + p_area(gpa) = sngloff(darea, min_area) + if (p_area(gpa) > min_area) gpa = gpa + 1 + !------------------------------------------------------------------------------! + end do read_patches + !---------------------------------------------------------------------------------! + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of patches. We also make sure that there is ! + ! at least one valid patch, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + npatches = gpa - 1 + if (npatches <= 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Invalid number of patches: ',npatches + write (unit=*,fmt='(a)') ' File is probably corrupted...' + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read cohort file. ! + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(abs(file_pdist(nclosest)-file_cdist),dim=1) + css_name = trim(css_list(nclosest)) + write (unit=*,fmt='(2a)') 'Using cohort file: ',trim(css_name) + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Open the cohort file and read in all cohorts. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(css_name),form='formatted',status='old') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop over all cohorts and decide whether they should be included or not. ! + !---------------------------------------------------------------------------------! + discarded_pft(:) = .false. + gco = 1 + read_cohorts: do + + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of patches ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gco > huge_cohort) then + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a)') ' Number of cohorts is > HUGE_COHORT...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_COHORT:',huge_cohort + write (unit=*,fmt='(a)') ' Increase HUGE_COHORT to read this...' + call fatal_error('Too many cohorts to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + + + + !----- Read line. Exit loop when finished reading cohorts. -------------------! + read(unit=12,fmt=*,iostat=ierr) ctime(gco),csname(gco),cpname(gco),cname(gco) & + ,dbh(gco),hite(gco),ipft(gco),nplant(gco) & + ,bdead(gco),balive(gco),dummy,dummy + if (ierr /= 0) exit read_cohorts + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Make sure this cohort qualifies to be included (if not qualified, we ! + ! cycle the read_cohorts loop without updating gco. ! + !------------------------------------------------------------------------------! + year = int(ctime(gco)) + if (use_target_year == 1 .and. year /= restart_target_year) then + !----- User wants css year to match the restart target year. ---------------! + cycle read_cohorts + !---------------------------------------------------------------------------! + else if (nplant(gco) < negligible_nplant(ipft(gco))) then + !----- Cohort population is negligible. ------------------------------------! + cycle read_cohorts + !---------------------------------------------------------------------------! + else if (.not. include_pft(ipft(gco))) then + !---------------------------------------------------------------------------! + ! This PFT is not in the list of PFTs to include. Decide what to do ! + ! based on the PFT_1ST_CHECK settings. ! + !---------------------------------------------------------------------------! + select case (pft_1st_check) + case (0) + !----- Stop the run. ----------------------------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Either edit NL%INCLUDE_THESE_PFT or' & + ,'set NL%PFT_1ST_CHECK to 1 or 2.' + call fatal_error('Invalid PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !------------------------------------------------------------------------! + case (1) + !----- Warn user about the unexpected PFT. ------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Changing include_these_pft to' & + ,'incorporate the PFT.' + call warning('Unexpected PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !------------------------------------------------------------------------! + + + !----- Add the unexpected PFT to the list of possible PFTs. -------------! + include_pft(ipft(gco)) = .true. + include_these_pft(count(include_pft)) = ipft(gco) + call sort_up(include_these_pft,n_pft) + if (is_grass(ipft(gco))) include_pft_ag(ipft(gco)) = .true. + !------------------------------------------------------------------------! + case (2) + if (.not. discarded_pft(ipft(gco))) then + !---------------------------------------------------------------------! + ! In case this is the first time finding this unexpected PFT, ! + ! warn user. ! + !---------------------------------------------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Discarding PFT.' + call warning('Unexpected PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !---------------------------------------------------------------------! + + + !------ Switch flag so we don't overwhelm the output with warnings. --! + discarded_pft(ipft(gco)) = .true. + !---------------------------------------------------------------------! + end if + !------------------------------------------------------------------------! + + !----- Skip the cohort. -------------------------------------------------! + cycle read_cohorts + !------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------! + else + !----- Keep the cohort. ----------------------------------------------------! + gco = gco + 1 + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + end do read_cohorts + !---------------------------------------------------------------------------------! + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of sites. We also make sure that there is at ! + ! least one valid site, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + ncohorts = gco - 1 + if (npatches < 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Invalid number of patches: ',npatches + write (unit=*,fmt='(a)') ' File is probably corrupted...' + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + !---------------------------------------------------------------------------------! + ! Link patches and cohorts to sites. To reduce the computational burden of ! + ! long patch/cohort files, we skip the beginning of the loop when all the initial ! + ! patches and cohorts have already been assigned. This will only be effective ! + ! if the files are organised (most of the time they are, but the code doesn't ! + ! assume they are). ! + !---------------------------------------------------------------------------------! + apa = 1 + aco = 1 + do gsi=1,nsites + !----- Flag all patches associated with this site. ----------------------------! + do gpa=apa,npatches + !----- Link patch to site if the names match. ------------------------------! + if (trim(psname(gpa)) == trim(sname(gsi))) then + psite_id(gpa) = gsi + + + !------------------------------------------------------------------------! + ! Update apa in case all patch elements up to this point have been ! + ! assigned to a site. ! + !------------------------------------------------------------------------! + if (gpa == apa) then + apa = apa + 1 + end if + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------! + ! Link cohorts to patches. ! + !---------------------------------------------------------------------------! + do gco=aco,ncohorts + !----- Flag all cohorts associated with this patch and site. ------------! + if ( (trim(cpname(gco)) == trim(pname (gpa))) .and. & + (trim(csname(gco)) == trim(psname(gpa))) .and. & + (trim(csname(gco)) == trim(sname (gsi))) ) then + cpatch_id(gco) = gpa + csite_id (gco) = gsi + + !---------------------------------------------------------------------! + ! Update apa in case all cohort elements up to this point have ! + ! been assigned to a patch/site. ! + !---------------------------------------------------------------------! + if (gco == aco) then + aco = aco + 1 + end if + !---------------------------------------------------------------------! + + end if + !------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------! + + + !----- Count cohorts belonging to this patch. ------------------------------! + cohort_count(gpa) = count(cpatch_id(:) == gpa) + !---------------------------------------------------------------------------! + end do + !------------------------------------------------------------------------------! + + + !----- Count patches belonging to this site. ----------------------------------! + patch_count(gsi) = count(psite_id(:) == gsi) + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! In case this site does not have any patch, issue an error. Sites should ! + ! always have at least one patch. ! + !------------------------------------------------------------------------------! + if (patch_count(gsi) == 0) then + write (unit=*,fmt='(a)' ) '==========================================' + write (unit=*,fmt='(a)' ) ' Site without patches found!' + write (unit=*,fmt='(a)' ) '==========================================' + write (unit=*,fmt='(a,1x,a)' ) ' Site file: ',trim(sss_name) + write (unit=*,fmt='(a,1x,a)' ) ' Patch file:',trim(pss_name) + write (unit=*,fmt='(a,1x,i5)') ' Site ID: ',gsi + write (unit=*,fmt='(a,1x,a)' ) ' Site name: ',sname(gsi) + write (unit=*,fmt='(a)' ) '==========================================' + call fatal_error('A site without corresponding patches was found!' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------------! + + + + + + !---------------------------------------------------------------------------------! + ! Allocate sites. ! + !---------------------------------------------------------------------------------! + call allocate_polygontype(cpoly,nsites) + call soil_default_fill(cgrid,igr,ipy) + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop through sites and allocate patches and cohorts. ! + !---------------------------------------------------------------------------------! + gsi = 0 + init_sites: do isi=1,cpoly%nsites + !------ Update pointers and counters. -----------------------------------------! + csite => cpoly%site(isi) + gsi = gsi + 1 + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! In case this is a single-grid, single-polygon simulation, we rewrite ! + ! the site properties of the first soil classes with the site-level ! + ! information. ! + !------------------------------------------------------------------------------! + if (single_poi) then + !----- Replace texture with the site ID. -----------------------------------! + ntext(gsi) = isi + !---------------------------------------------------------------------------! + + + !----- Overwrite reference properties of the isi-th site. ------------------! + slxkey_ref (isi) = 'Site' + slhydro_ref(isi) = soil_hydro_scheme + slxsand_ref(isi) = sand (gsi) + slxclay_ref(isi) = clay (gsi) + slxsilt_ref(isi) = 1. - slxsand_ref(isi) - slxclay_ref(isi) + slsoc_ref (isi) = slsoc(gsi) + slph_ref (isi) = slph (gsi) + slcec_ref (isi) = slcec(gsi) + sldbd_ref (isi) = sldbd(gsi) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! Initialise site variables. If TOPMODEL becomes again functional, this ! + ! list may need to be expanded. ! + !------------------------------------------------------------------------------! + cpoly%area (isi) = s_area (gsi) + cpoly%ntext_soil(:,isi) = ntext (gsi) + cpoly%ncol_soil (isi) = nscol (gsi) + cpoly%elevation (isi) = elevation(gsi) + cpoly%slope (isi) = slope (gsi) + cpoly%aspect (isi) = aspect (gsi) + cpoly%tci (isi) = tci (gsi) + cpoly%moist_f (isi) = moist_f (gsi) + cpoly%moist_w (isi) = moist_w (gsi) + !------------------------------------------------------------------------------! + + + !------ Dummy variables. ------------------------------------------------------! + cpoly%sitenum (isi) = isi + !------------------------------------------------------------------------------! + + + !------ Find the lowest soil level to simulate. -------------------------------! + shmask(:) = ed_slz(:) <= - abs(depth(gsi)) + cpoly%lsl(isi) = min(max(1,maxloc(ed_slz(:),dim=1,mask=shmask)),nzg-1) + !------------------------------------------------------------------------------! + + + !------ Copy patch count. -----------------------------------------------------! + cpoly%patch_count(isi) = patch_count(gsi) + !------------------------------------------------------------------------------! + + + !------ Update the polygon average topographic moisture index. ----------------! + cgrid%wbar(ipy) = cgrid%wbar(ipy) + cpoly%moist_w(isi) * cpoly%area(isi) + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! Allocate patches for this site. ! + !------------------------------------------------------------------------------! + call allocate_sitetype(csite,patch_count(gsi)) + !------------------------------------------------------------------------------! + end do init_sites + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop through all patches, and initialise them at the appropriate site. ! + !---------------------------------------------------------------------------------! + last_ipa(:) = 0 + init_patches: do gpa=1,npatches + !------------------------------------------------------------------------------! + ! Try setting the site. If the site had a tiny area, this patch may be ! + ! orphaned, in which case we skip it. ! + !------------------------------------------------------------------------------! + if (psite_id(gpa) == undef_integer) then + !----- Invalid patch, skip it. ---------------------------------------------! + cycle init_patches + !---------------------------------------------------------------------------! + else + !----- Valid patch, assign site. -------------------------------------------! + isi = psite_id(gpa) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Set other counters and pointers. ---------------------------------------! + ipa = last_ipa(isi) + 1 + ppatch_id(gpa) = ipa + csite => cpoly%site (isi) + cpatch => csite%patch(ipa) + !------------------------------------------------------------------------------! + + + + !------ Set patch-level variables. --------------------------------------------! + csite%pname (ipa) = trim(pname (gpa)) + csite%dist_type (ipa) = dtype (gpa) + csite%age (ipa) = age (gpa) + csite%area (ipa) = p_area (gpa) + csite%fast_grnd_C (ipa) = fgc (gpa) + csite%fast_soil_C (ipa) = fsc (gpa) + csite%structural_grnd_C (ipa) = stgc (gpa) + csite%structural_grnd_L (ipa) = stgl (gpa) + csite%structural_soil_C (ipa) = stsc (gpa) + csite%structural_soil_L (ipa) = stsl (gpa) + csite%mineralized_soil_N(ipa) = msn (gpa) + csite%cohort_count (ipa) = cohort_count(gpa) + !------------------------------------------------------------------------------! + + + + !------ Set fast nitrogen pools so they are proportional to the carbon pools. -! + if ( (fgc(gpa)+fsc(gpa)) > tiny_num) then + csite%fast_grnd_N (ipa) = fgc(gpa) * fsn(gpa) / (fgc(gpa)+fsc(gpa)) + csite%fast_soil_N (ipa) = fsc(gpa) * fsn(gpa) / (fgc(gpa)+fsc(gpa)) + else + csite%fast_grnd_C (ipa) = 0.0 + csite%fast_soil_C (ipa) = 0.0 + csite%fast_grnd_N (ipa) = 0.0 + csite%fast_soil_N (ipa) = 0.0 + end if + !------------------------------------------------------------------------------! + + + + !------ Use stoichiometry to derive structural N pools. -----------------------! + csite%structural_grnd_N (ipa) = csite%structural_grnd_C (ipa) / c2n_structural + csite%structural_soil_N (ipa) = csite%structural_soil_C (ipa) / c2n_structural + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Check decomposition scheme before assigning microbial carbon. ! + !------------------------------------------------------------------------------! + select case (decomp_scheme) + case (5) + csite%microbial_soil_C(ipa) = msc(gpa) + csite%slow_soil_C (ipa) = ssc(gpa) + csite%passive_soil_C (ipa) = psc(gpa) + case default + csite%microbial_soil_C(ipa) = 0.0 + csite%slow_soil_C (ipa) = msc(gpa) + ssc(gpa) + psc(gpa) + csite%passive_soil_C (ipa) = 0.0 + end select + !------------------------------------------------------------------------------! + + + !----- Initialise other properties. -------------------------------------------! + csite%fbeam (ipa) = 1.0 + csite%light_type (ipa) = 1 + csite%sum_dgd (ipa) = 0.0 + csite%sum_chd (ipa) = 0.0 + csite%plant_ag_biomass (ipa) = 0.0 + !------------------------------------------------------------------------------! + + + !------ Allocate cohorts for this patch. --------------------------------------! + if ( cohort_count(gpa) /= 0) then + call allocate_patchtype(cpatch,cohort_count(gpa)) + end if + !------------------------------------------------------------------------------! + + + !------ Update last_ipa for this site. ----------------------------------------! + last_ipa(isi) = ipa + !------------------------------------------------------------------------------! + end do init_patches + !---------------------------------------------------------------------------------! + + + + + !---------------------------------------------------------------------------------! + ! Loop through all cohort, and initialise them at the appropriate patch and ! + ! site. ! + !---------------------------------------------------------------------------------! + last_ico(:) = 0 + init_cohorts: do gco=1,ncohorts + !------------------------------------------------------------------------------! + ! Try setting the site and patch. If the site or the patch had a tiny ! + ! area, this cohort may be orphaned, in which case we skip it. ! + !------------------------------------------------------------------------------! + if (csite_id(gco) == undef_integer .or. cpatch_id(gco) == undef_integer) then + !----- Invalid cohort, skip it. --------------------------------------------! + cycle init_cohorts + !---------------------------------------------------------------------------! + else + !----- Valid cohort, assign site and global patch. -------------------------! + isi = csite_id (gco) + gpa = cpatch_id(gco) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Set other counters and pointers. ---------------------------------------! + ipa = ppatch_id(gpa) + ico = last_ico (gpa) + 1 + csite => cpoly%site(isi) + cpatch => csite%patch(ipa) + !------------------------------------------------------------------------------! + + + + + !------ Copy data from files to cohort. ---------------------------------------! + cpatch%nplant(ico) = nplant(gco) + cpatch%pft (ico) = ipft (gco) + cpatch%dbh (ico) = max(dbh(gco),min_dbh(ipft(gco))) + !------------------------------------------------------------------------------! + + + + + !------ Update allometry to define height and heartwood. ----------------------! + cpatch%hite (ico) = dbh2h(cpatch%pft(ico),cpatch%dbh(ico)) + bdead (gco) = size2bd(cpatch%dbh(ico),cpatch%hite(ico),cpatch%pft(ico)) + cpatch%bdeada(ico) = agf_bs(cpatch%pft(ico)) * bdead(gco) + cpatch%bdeadb(ico) = (1.0 - agf_bs(cpatch%pft(ico))) * bdead(gco) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise SLA, Vm0, Rd0, and with the look-up table value. These ! + ! variables may be updated during phenology initialisation, or trait ! + ! plasticity, but they must have an initial assignment so we can even ! + ! calculate the initial area indices and inicial trait values needed for the ! + ! trait update. ! + !------------------------------------------------------------------------------! + cpatch%sla (ico) = SLA (ipft(gco)) + cpatch%vm_bar(ico) = Vm0 (ipft(gco)) + cpatch%rd_bar(ico) = Rd0 (ipft(gco)) + cpatch%llspan(ico) = leaf_turnover_rate(ipft(gco)) + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! Use allometry to define leaf and the other live biomass pools. ! + !------------------------------------------------------------------------------! + cpatch%bleaf (ico) = size2bl(cpatch%dbh(ico),cpatch%hite(ico) & + ,cpatch%sla(ico),ipft(gco)) + cpatch%broot (ico) = cpatch%bleaf(ico) * q(ipft(gco)) + cpatch%bsapwooda(ico) = agf_bs(ipft(gco)) & + * cpatch%bleaf(ico) * qsw(ipft(gco)) * cpatch%hite(ico) + cpatch%bsapwoodb(ico) = (1.-agf_bs(ipft(gco))) & + * cpatch%bleaf(ico) * qsw(ipft(gco)) * cpatch%hite(ico) + cpatch%bbarka(ico) = agf_bs(ipft(gco)) & + * cpatch%bleaf(ico) * qbark(ipft(gco)) * cpatch%hite(ico) + cpatch%bbarkb(ico) = (1.-agf_bs(ipft(gco))) & + * cpatch%bleaf(ico) * qbark(ipft(gco)) * cpatch%hite(ico) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Start plants with full phenology, we will take care of phenology after ! + ! this sub-routine. ! + !------------------------------------------------------------------------------! + cpatch%phenology_status(ico) = 0 + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! In case we are representing trait plasticity, update traits (SLA, Vm0). ! + ! This must be done before calculating LAI and before ed_balive. ! + !------------------------------------------------------------------------------! + select case (trait_plasticity_scheme) + case (0) + continue + case default + call update_cohort_plastic_trait(cpatch,ico,.true. & + ,leaf_lifespan(ipft(gco)) & + ,vm0 (ipft(gco)) & + ,rd0 (ipft(gco)) & + ,sla (ipft(gco)) ) + end select + !------------------------------------------------------------------------------! + + + + + !----- Assign biomass of living tissues. --------------------------------------! + cpatch%balive(ico) = ed_balive(cpatch, ico) + !------------------------------------------------------------------------------! + + + !----- Initialise storage biomass (after setting balive). ---------------------! + cpatch%bstorage(ico) = max( almost_zero, f_bstorage_init(ipft(gco))) & + * cpatch%balive(ico) + !------------------------------------------------------------------------------! + + + + !----- Assign LAI, WAI, and CAI -----------------------------------------------! + call area_indices(cpatch, ico) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise the carbon balance. For initial conditions, we always assume ! + ! storage biomass for the previous months so the scale is correct (carbon ! + ! balance is given in kgC/pl). The current month carbon balance must be ! + ! initialised consistently with the iddmort_scheme we are using. ! + !------------------------------------------------------------------------------! + cpatch%cb (1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_lightmax(1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_moistmax(1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_mlmax (1:12,ico) = cpatch%bstorage(ico) + select case (iddmort_scheme) + case (0) + !------ Storage is not accounted. ------------------------------------------! + cpatch%cb (13,ico) = 0.0 + cpatch%cb_lightmax(13,ico) = 0.0 + cpatch%cb_moistmax(13,ico) = 0.0 + cpatch%cb_mlmax (13,ico) = 0.0 + !---------------------------------------------------------------------------! + case (1) + !------ Storage is accounted. ----------------------------------------------! + cpatch%cb (13,ico) = cpatch%bstorage(ico) + cpatch%cb_lightmax(13,ico) = cpatch%bstorage(ico) + cpatch%cb_moistmax(13,ico) = cpatch%bstorage(ico) + cpatch%cb_mlmax (13,ico) = cpatch%bstorage(ico) + !---------------------------------------------------------------------------! + end select + cpatch%cbr_bar (ico) = 1.0 + !------------------------------------------------------------------------------! + + + + !----- Above ground biomass, use the allometry. -------------------------------! + cpatch%agb (ico) = ed_biomass(cpatch, ico) + cpatch%basarea(ico) = pio4 * cpatch%dbh(ico) * cpatch%dbh(ico) + cpatch%btimber(ico) = size2bt( cpatch%dbh (ico) & + , cpatch%hite (ico) & + , cpatch%bdeada (ico) & + , cpatch%bsapwooda (ico) & + , cpatch%bbarka (ico) & + , cpatch%pft (ico) ) + cpatch%thbark (ico) = size2xb( cpatch%dbh (ico) & + , cpatch%hite (ico) & + , cpatch%bbarka (ico) & + , cpatch%bbarkb (ico) & + , cpatch%sla (ico) & + , cpatch%pft (ico) ) + !------------------------------------------------------------------------------! + + + + !----- Growth rates, start with zero. -----------------------------------------! + cpatch%dagb_dt (ico) = 0. + cpatch%dlnagb_dt(ico) = 0. + cpatch%dba_dt (ico) = 0. + cpatch%dlnba_dt (ico) = 0. + cpatch%ddbh_dt (ico) = 0. + cpatch%dlndbh_dt(ico) = 0. + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! Initialise other cohort variables. Some of them won't be updated ! + ! unless the lai exceeds lai_min. ! + !------------------------------------------------------------------------------! + cpatch%fsw(ico) = 1.0 + cpatch%gpp(ico) = 0.0 + cpatch%par_l(ico) = 0.0 + !------------------------------------------------------------------------------! + + + !----- Update the patch level above-ground biomass. ---------------------------! + csite%plant_ag_biomass(ipa) = csite%plant_ag_biomass(ipa) & + + cpatch%agb(ico) * cpatch%nplant(ico) + !------------------------------------------------------------------------------! + + + + !------ Update last_ico for this patch. ---------------------------------------! + last_ico(gpa) = ico + !------------------------------------------------------------------------------! + end do init_cohorts + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Find site adjacency (unlikely to be needed here). + !---------------------------------------------------------------------------------! + if (cgrid%load_adjacency(ipy) /= 0) then + call calc_flow_routing(cgrid,ipy) + end if + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Initialise additional site-, patch-, and cohort-level variables. ! + !---------------------------------------------------------------------------------! + init2_sites: do isi = 1,cpoly%nsites + + !----- Make sure that the total patch area is 1. ------------------------------! + csite => cpoly%site(isi) + area_sum = sum(csite%area(1:csite%npatches)) + csite%area(1:csite%npatches) = csite%area(1:csite%npatches) / area_sum + !------------------------------------------------------------------------------! + + + + + !----- Initialise the cohort variables, then sort them by size. ---------------! + init2_patches: do ipa = 1,csite%npatches + cpatch => csite%patch(ipa) + + !----- Initialise additional cohort variables. -----------------------------! + init2_cohorts: do ico = 1,cpatch%ncohorts + call init_ed_cohort_vars(cpatch,ico,cpoly%lsl(isi),nzg & + ,cpoly%ntext_soil(:,isi)) + end do init2_cohorts + !---------------------------------------------------------------------------! + + !----- Make sure that cohorts are organised from tallest to shortest. ------! + call sort_cohorts(cpatch) + !---------------------------------------------------------------------------! + end do init2_patches + !------------------------------------------------------------------------------! + + + + !----- Initialise the remaining patch-level variables. ------------------------! + call init_ed_patch_vars(csite,1,csite%npatches,cpoly%lsl(isi)) + !------------------------------------------------------------------------------! + + !----- Make sure that patches are organised from oldest to youngest. ----------! + call sort_patches(csite) + !------------------------------------------------------------------------------! + end do init2_sites + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! In case this is a single site simulation, we must update the soil ! + ! properties before initialising the site-level variables, because soil ! + ! characteristics are read from the site file. ! + !---------------------------------------------------------------------------------! + if (single_poi) then + call sfcdata_ed() + end if + !---------------------------------------------------------------------------------! + + + + !----- Initialise the remaining site-level variables. ----------------------------! + call init_ed_site_vars(cpoly) + !---------------------------------------------------------------------------------! + end do main_polyloop + !------------------------------------------------------------------------------------! + + + + !----- Initialise the polygon-level variables. --------------------------------------! + call init_ed_poly_vars(cgrid) + !------------------------------------------------------------------------------------! + end do main_gridloop + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Update the soil parameter table as soil properties have been overwritten for ! + ! a few sites. ! + !---------------------------------------------------------------------------------------! + call ed_gen_soil_table() + !---------------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------------! + ! Free memory. ! + !---------------------------------------------------------------------------------------! + deallocate(shmask) + deallocate(ed_slz) + !---------------------------------------------------------------------------------------! + + + return +end subroutine read_ed22_initial_file +!==========================================================================================! +!==========================================================================================! +!==========================================================================================! +!==========================================================================================! diff --git a/ED/src/io/ed_xml_config.f90 b/ED/src/io/ed_xml_config.f90 index 22e741ecd..6ac5a3cbd 100644 --- a/ED/src/io/ed_xml_config.f90 +++ b/ED/src/io/ed_xml_config.f90 @@ -1472,6 +1472,12 @@ recursive subroutine read_ed_xml_config(filename) if(texist) retained_carbon_fraction = sngloff(rval,tiny_offset) call getConfigREAL ('root_phen_factor','phenology',i,rval,texist) if(texist) root_phen_factor = sngloff(rval,tiny_offset) + call getConfigREAL ('f_psi_xdry','phenology',i,rval,texist) + if(texist) f_psi_xdry = sngloff(rval,tiny_offset) + call getConfigREAL ('elongf_min','phenology',i,rval,texist) + if(texist) elongf_min = sngloff(rval,tiny_offset) + call getConfigREAL ('elongf_flush','phenology',i,rval,texist) + if(texist) elongf_flush = sngloff(rval,tiny_offset) call getConfigREAL ('theta_crit','phenology',i,rval,texist) if(texist) thetacrit= sngloff(rval,tiny_offset) call getConfigREAL ('dl_tr','phenology',i,rval,texist) @@ -2431,6 +2437,9 @@ subroutine write_ed_xml_config call libxml2f90_ll_opentag("phenology") call putConfigREAL("retained_carbon_fraction",retained_carbon_fraction) call putConfigREAL("root_phen_factor" ,root_phen_factor ) + call putConfigREAL("f_psi_xdry" ,f_psi_xdry ) + call putConfigREAL("elongf_min" ,elongf_min ) + call putConfigREAL("elongf_flush" ,elongf_flush ) call putConfigREAL("theta_crit" ,thetacrit ) call putConfigREAL("dl_tr" ,dl_tr ) call putConfigREAL("st_tr1" ,st_tr1 ) diff --git a/ED/src/io/h5_output.F90 b/ED/src/io/h5_output.F90 index 209b184aa..e72fdcccf 100644 --- a/ED/src/io/h5_output.F90 +++ b/ED/src/io/h5_output.F90 @@ -30,6 +30,7 @@ subroutine h5_output(vtype) , stride & ! intent(in) , globdims ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , recvnum & ! intent(in) @@ -50,10 +51,6 @@ subroutine h5_output(vtype) , gdpy ! ! intent(in) implicit none - !------ Include standard common blocks. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !------ Arguments. ---------------------------------------------------------------------! character(len=*) , intent(in) :: vtype !------ Local variables. ---------------------------------------------------------------! @@ -879,8 +876,9 @@ subroutine geth5dims(idim_type,varlen,globid,var_len_global,dsetrank,varn,nrec,i !---------------------------------------------------------------------------------------! select case (idim_type) - case(90,91,92,96) ! No polygon-site-patch or cohort dimension, or single-dim. vector - + case(90,91,92,96,98,980) + ! No polygon-site-patch or cohort dimension, or single-dim. vector + dsetrank = 1 chnkdims(1) = int(varlen,8) chnkoffs(1) = int(globid,8) diff --git a/ED/src/memory/consts_coms.F90 b/ED/src/memory/consts_coms.F90 index 2345913b0..7fe069102 100644 --- a/ED/src/memory/consts_coms.F90 +++ b/ED/src/memory/consts_coms.F90 @@ -381,7 +381,7 @@ Module consts_coms !---------------------------------------------------------------------------------------! real, parameter :: srtwo = 1.414213562373095 ! Square root of 2. [ ---] real, parameter :: srthree = 1.732050807568877 ! Square root of 3. [ ---] - real, parameter :: sqrt2o2 = 0.5 * srtwo ! ½ Square root of 2. [ ---] + real, parameter :: sqrt2o2 = 0.5 * srtwo ! 1/2 * Square root of 2. [ ---] real, parameter :: srtwoi = 1./srtwo ! 1./ Square root of 2. [ ---] real, parameter :: srthreei = 1./srthree ! 1./ Square root of 3. [ ---] real, parameter :: onethird = 1./3. ! 1/3 [ ---] @@ -394,12 +394,12 @@ Module consts_coms !---------------------------------------------------------------------------------------! ! Universal constants ! !---------------------------------------------------------------------------------------! - real, parameter :: stefan = 5.6696e-8 ! Stefan-Boltzmann constant [ W/m²/K^4] - real, parameter :: boltzmann = 1.3806503e-23 ! Boltzmann constant [m²kg/s²/K] - real, parameter :: t00 = 273.15 ! 0°C [ °C] - real, parameter :: rmol = 8.314510 ! Molar gas constant [ J/mol/K] - real, parameter :: volmol = 0.022710980 ! Molar volume at STP [ m³] - real, parameter :: volmoll = volmol*1e3 ! Molar volume at STP [ L] + real, parameter :: stefan = 5.6696e-8 ! Stefan-Boltzmann constant [ W/m2/K4] + real, parameter :: boltzmann = 1.3806503e-23 ! Boltzmann constant [m2 kg/s2/K] + real, parameter :: t00 = 273.15 ! 0 degC [ degC] + real, parameter :: rmol = 8.314510 ! Molar gas constant [ J/mol/K] + real, parameter :: volmol = 0.022710980 ! Molar volume at STP [ m3] + real, parameter :: volmoll = volmol*1e3 ! Molar volume at STP [ L] !---------------------------------------------------------------------------------------! @@ -438,11 +438,11 @@ Module consts_coms !---------------------------------------------------------------------------------------! ! General Earth properties ! !---------------------------------------------------------------------------------------! - real, parameter :: vonk = 0.40 ! Von Kármán constant [ ---] - real, parameter :: grav = 9.80665 ! Gravity acceleration [ m/s²] + real, parameter :: vonk = 0.40 ! Von Karman constant [ ---] + real, parameter :: grav = 9.80665 ! Gravity acceleration [ m/s2] real, parameter :: erad = 6370997. ! Earth radius [ m] real, parameter :: erad2 = 2.*erad ! Earth diameter [ m] - real, parameter :: solar = 1.3533e3 ! Solar constant [ W/m²] + real, parameter :: solar = 1.3533e3 ! Solar constant [ W/m2] real, parameter :: p00 = 1.e5 ! Reference pressure [ Pa] real, parameter :: prefsea = 101325. ! Reference sea level pressure [ Pa] real, parameter :: p00i = 1. / p00 ! 1/p00 [ 1/Pa] @@ -458,7 +458,7 @@ Module consts_coms ! third edition, Academic Press, Amsterdam, 418pp. (Chapters 3 and 10). ! ! ! ! Air diffusion properties. These properties are temperature-dependent in reality, ! - ! but for simplicity we assume them constants, using the value at 20°C. ! + ! but for simplicity we assume them constants, using the value at 20 degC. ! ! ! ! Thermal diffusivity - Computed from equation on page 32 of MU08; ! ! Kinematic viscosity - Computed from equation on page 32 of MU08; ! @@ -466,9 +466,9 @@ Module consts_coms ! 10.11 (MU08). ! ! These terms could be easily made function of temperature in the future if needed be. ! !---------------------------------------------------------------------------------------! - real, parameter :: th_diff0 = 1.89e-5 ! Air thermal diffusivity [ m²/s] + real, parameter :: th_diff0 = 1.89e-5 ! Air thermal diffusivity [ m2/s] real, parameter :: dth_diff = 0.007 ! Temperature dependency slope [ 1/K] - real, parameter :: kin_visc0 = 1.33e-5 ! Kinematic viscosity [ m²/s] + real, parameter :: kin_visc0 = 1.33e-5 ! Kinematic viscosity [ m2/s] real, parameter :: dkin_visc = 0.007 ! Temperature dependency slope [ 1/K] !---------------------------------------------------------------------------------------! @@ -516,8 +516,8 @@ Module consts_coms !---------------------------------------------------------------------------------------! ! Liquid water properties ! !---------------------------------------------------------------------------------------! - real, parameter :: wdns = 1.000e3 ! Liquid water density [ kg/m³] - real, parameter :: wdnsi = 1./wdns ! Inverse of liquid water density [ m³/kg] + real, parameter :: wdns = 1.000e3 ! Liquid water density [ kg/m3] + real, parameter :: wdnsi = 1./wdns ! Inverse of liquid water density [ m3/kg] real, parameter :: cliq = 4.186e3 ! Liquid water specific heat (Cl) [ J/kg/K] real, parameter :: cliqi = 1./cliq ! Inverse of water heat capacity [ kg K/J] !---------------------------------------------------------------------------------------! @@ -527,12 +527,12 @@ Module consts_coms !---------------------------------------------------------------------------------------! ! Ice properties ! !---------------------------------------------------------------------------------------! - real, parameter :: idns = 9.167e2 ! "Hard" ice density [ kg/m³] - real, parameter :: idnsi = 1./idns ! Inverse of ice density [ m³/kg] - real, parameter :: fdns = 2.000e2 ! Frost density [ kg/m³] - real, parameter :: fdnsi = 1./fdns ! Inverse of frost density [ m³/kg] - real, parameter :: fsdns = 1.000e2 ! Fresh snow density [ kg/m³] - real, parameter :: fsdnsi = 1./fsdns ! Inverse of liquid water density [ m³/kg] + real, parameter :: idns = 9.167e2 ! "Hard" ice density [ kg/m3] + real, parameter :: idnsi = 1./idns ! Inverse of ice density [ m3/kg] + real, parameter :: fdns = 2.000e2 ! Frost density [ kg/m3] + real, parameter :: fdnsi = 1./fdns ! Inverse of frost density [ m3/kg] + real, parameter :: fsdns = 1.000e2 ! Fresh snow density [ kg/m3] + real, parameter :: fsdnsi = 1./fsdns ! Inverse of liquid water density [ m3/kg] real, parameter :: cice = 2.093e3 ! Ice specific heat (Ci) [ J/kg/K] real, parameter :: cicei = 1. / cice ! Inverse of ice heat capacity [ kg K/J] !---------------------------------------------------------------------------------------! @@ -547,8 +547,8 @@ Module consts_coms real, parameter :: t3plei = 1./t3ple ! 1./T3 [ 1/K] real, parameter :: es3ple = 611.65685464 ! Vapour pressure at T3 (es3) [ Pa] real, parameter :: es3plei = 1./es3ple ! 1./es3 [ 1/Pa] - real, parameter :: epes3ple = ep * es3ple ! epsilon × es3 [ Pa kg/kg] - real, parameter :: rh2ot3ple = rh2o * t3ple ! Rv × T3 [ J/kg] + real, parameter :: epes3ple = ep * es3ple ! epsilon * es3 [ Pa kg/kg] + real, parameter :: rh2ot3ple = rh2o * t3ple ! Rv * T3 [ J/kg] real, parameter :: alli = 3.34e5 ! Lat. heat - fusion (Lf)[ J/kg] real, parameter :: alvl3 = 2.50e6 ! Lat. heat - vaporisation (Lv)[ J/kg] real, parameter :: alvi3 = alli + alvl3 ! Lat. heat - sublimation (Ls)[ J/kg] @@ -558,8 +558,8 @@ Module consts_coms real, parameter :: lvordry = alvl3 / rdry ! Lv/Ra [ K] real, parameter :: lvorvap = alvl3 / rh2o ! Lv/Rv [ K] real, parameter :: lsorvap = alvi3 / rh2o ! Ls/Rv [ K] - real, parameter :: lvt3ple = alvl3 * t3ple ! Lv × T3 [ K J/kg] - real, parameter :: lst3ple = alvi3 * t3ple ! Ls × T3 [ K J/kg] + real, parameter :: lvt3ple = alvl3 * t3ple ! Lv * T3 [ K J/kg] + real, parameter :: lst3ple = alvi3 * t3ple ! Ls * T3 [ K J/kg] real, parameter :: uiicet3 = cice * t3ple ! u at triple point, only ice [ J/kg] real, parameter :: uiliqt3 = uiicet3 + alli ! u at triple point, only liq. [ J/kg] real, parameter :: dcpvl = cph2o - cliq ! difference of sp. heat [ J/kg/K] @@ -671,16 +671,16 @@ Module consts_coms !---------------------------------------------------------------------------------------! ! Carbon-related unit conversions. ! !---------------------------------------------------------------------------------------! - real, parameter :: mol_2_umol = 1.e6 ! mol => µmol - real, parameter :: umol_2_mol = 1.e-6 ! µmol => mol - real, parameter :: umol_2_kgC = 1.20107e-8 ! µmol(CO2) => kg(C) - real, parameter :: Watts_2_Ein = 4.6e-6 ! W/m2 => mol/m²/s - real, parameter :: Ein_2_Watts = 1./Watts_2_Ein ! mol/m²/s => W/m2 - real, parameter :: kgC_2_umol = 1. / umol_2_kgC ! kg(C) => µmol(CO2) - real, parameter :: kgom2_2_tonoha = 10. ! kg(C)/m² => ton(C)/ha - real, parameter :: tonoha_2_kgom2 = 0.1 ! ton(C)/ha => kg(C)/m² - real, parameter :: umols_2_kgCyr = umol_2_kgC * yr_sec ! µmol(CO2)/s => kg(C)/yr - real, parameter :: kgCday_2_umols = kgC_2_umol / day_sec ! kg(C)/day => µmol(CO2)/s + real, parameter :: mol_2_umol = 1.e6 ! mol => umol + real, parameter :: umol_2_mol = 1.e-6 ! umol => mol + real, parameter :: umol_2_kgC = 1.20107e-8 ! umol(CO2) => kg(C) + real, parameter :: Watts_2_Ein = 4.6e-6 ! W/m2 => mol/m2/s + real, parameter :: Ein_2_Watts = 1./Watts_2_Ein ! mol/m2/s => W/m2 + real, parameter :: kgC_2_umol = 1. / umol_2_kgC ! kg(C) => umol(CO2) + real, parameter :: kgom2_2_tonoha = 10. ! kg(C)/m2 => ton(C)/ha + real, parameter :: tonoha_2_kgom2 = 0.1 ! ton(C)/ha => kg(C)/m2 + real, parameter :: umols_2_kgCyr = umol_2_kgC * yr_sec ! umol(CO2)/s => kg(C)/yr + real, parameter :: kgCday_2_umols = kgC_2_umol / day_sec ! kg(C)/day => umol(CO2)/s !---------------------------------------------------------------------------------------! #endif diff --git a/ED/src/memory/disturb_coms.f90 b/ED/src/memory/disturb_coms.f90 index 942e401df..2d19bfc06 100644 --- a/ED/src/memory/disturb_coms.f90 +++ b/ED/src/memory/disturb_coms.f90 @@ -140,6 +140,7 @@ module disturb_coms ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! @@ -158,6 +159,7 @@ module disturb_coms real(kind=4), dimension(n_pft) :: sl_mindbh_harvest real(kind=4) :: sl_biomass_harvest real(kind=4) :: sl_skid_rel_area + real(kind=4) :: sl_skid_dbh_thresh real(kind=4) :: sl_skid_s_gtharv real(kind=4) :: sl_skid_s_ltharv real(kind=4) :: sl_felling_s_ltharv diff --git a/ED/src/memory/ed_max_dims.F90 b/ED/src/memory/ed_max_dims.F90 index 2996c71ca..9e581ab26 100644 --- a/ED/src/memory/ed_max_dims.F90 +++ b/ED/src/memory/ed_max_dims.F90 @@ -245,25 +245,32 @@ module ed_max_dims ! For restart runs, this is the maximum number of certain variables that can be ! ! read. ! ! HUGE_POLYGON - maximum number of input polygons. ! + ! HUGE_SITE - maximum number of input sites. ! ! HUGE_PATCH - maximum number of input patches. ! ! HUGE_COHORT - maximum number of input cohorts. ! ! MAX_WATER - maximum number of soil water levels (not assigned to polygons). ! !---------------------------------------------------------------------------------------! integer, parameter :: huge_polygon = nxpmax * nypmax + integer, parameter :: huge_site = ed_nstyp #if defined(MAC_OS_X) integer, parameter :: huge_patch = 200 - integer, parameter :: huge_cohort = 8000 + integer, parameter :: huge_cohort = 20000 + integer, parameter :: max_water = 5 #else - integer, parameter :: huge_patch = 10000 - integer, parameter :: huge_cohort = 250000 -#endif + integer, parameter :: huge_patch = 20000 + integer, parameter :: huge_cohort = 800000 integer, parameter :: max_water = 100 +#endif !---------------------------------------------------------------------------------------! !----- Maximum number of land use polygons that can be read by filelist. ---------------! +#if defined(MAC_OS_X) + integer, parameter :: huge_lu = 999 +#else integer, parameter :: huge_lu = 99999 +#endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ed_mem_alloc.f90 b/ED/src/memory/ed_mem_alloc.f90 index 5efba6ce5..e4370265c 100644 --- a/ED/src/memory/ed_mem_alloc.f90 +++ b/ED/src/memory/ed_mem_alloc.f90 @@ -72,15 +72,15 @@ subroutine ed_memory_allocation(proc_type) call ed_nullify_work(work_e(ng)) call ed_alloc_work(work_e(ng),nmxp(ng),nmyp(ng),maxsite) end do - + !---------------------------------------------------------------------------------------! ! Allocate the top most hierachical memory structures for the ED2 LSM. We changed the ! ! the way the standalone deals with different regions ans sites of interest. Now it ! - ! allocates each region and each poi in a different grid. This is done to ease the way ! - ! the parallel code is implemented, to take full advantage of MPI. By doing this, we ! - ! can split the polygons among the different nodes for the regional run, and split the ! - ! patches and cohorts in different nodes in the POI grids --- the latter is yet to be ! - ! implemented. ! + ! allocates each region and each point in a different grid. This is done to ease the ! + ! way the parallel code is implemented, to take full advantage of MPI. By doing this, ! + ! we can split the polygons among the different nodes for the regional run, and split ! + ! the patches and cohorts in different nodes in the POI grids --- the latter is yet to ! + ! be implemented. ! !---------------------------------------------------------------------------------------! write (unit=*,fmt='(a,i5,a)') ' + Polygon array allocation, node ',mynum,';' @@ -90,7 +90,7 @@ subroutine ed_memory_allocation(proc_type) call allocate_edtype(edgrid_g(ng),gdpy(mynum,ng)) end do - write (unit=*,fmt='(a,i5,a)') ' + Memory successfully allocated on none ',mynum,';' + write (unit=*,fmt='(a,i5,a)') ' + Memory successfully allocated on node ',mynum,';' return end subroutine ed_memory_allocation !---------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ed_misc_coms.f90 b/ED/src/memory/ed_misc_coms.f90 index 79968322d..f6e496671 100644 --- a/ED/src/memory/ed_misc_coms.f90 +++ b/ED/src/memory/ed_misc_coms.f90 @@ -8,6 +8,11 @@ module ed_misc_coms implicit none + + !----- String for the output format of the restore file. -------------------------------! + character(len=26), parameter :: fmtrest = '(i4.4,2(1x,i2.2),1x,2i2.2)' + !---------------------------------------------------------------------------------------! + type simtime integer :: year integer :: month @@ -260,17 +265,40 @@ module ed_misc_coms !----- Namelist option for allometry scheme. -------------------------------------------! - integer :: iallom ! 0 -- Original ED-2.1 allometry - ! 1 -- DBH -> AGB Tree allometry based on Baker et al. (2004) - ! keep original ED-2.1 Bl/Bd ratio - ! 2 -- DBH -> AGB Tree allometry based on Baker et al. (2004) - ! keep original ED-2.1 Bl - ! 3 -- Updated allometric and trait-based parameters for tropical - ! PFTs. When available, parameters came from regional data - ! sets and regional studies, or from local studies when regional - ! ones were not found. Check ed_params.f90 for details and - ! references. - !---------------------------------------------------------------------------------------! + integer :: iallom ! 0 -- (Legacy) Original ED-1.0, included for back compatibility. + ! 1 -- (Legacy) ED-2.1 allometry, included for back compatibility. + ! a. The coefficients for structural biomass are set so the + ! total AGB is similar to Baker et al. (2004, Glob. Change + ! Biol.), equation 2. + ! b. Experimental root depth that makes canopy trees to have + ! root depths of 5m and grasses/seedlings at 0.5 to have root + ! depth of 0.5 m. + ! c. Crown area defined as in Poorter et al. (2006, Ecology), + ! imposing maximum crown area. + ! 2 -- (ED-2.2 default) Similar to 1, but with a few extra changes. + ! a. Height -> DBH allometry as in Poorter et al. (2006) + ! b. Balive is retuned, using a few leaf biomass allometric + ! equations for a few genera in Costa Rica. References: + ! Cole and Ewel (2006, Forest Ecol. Manag.), and + ! Calvo-Alvarado et al. (2008, Tree Physiol.). + ! 3 -- (Beta) Revised tropical PFT allometric (Longo et al. 2020, + ! J. Geophys. Res.-Biogeosci.). + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the + ! Sustainable Landscapes Dataset (Longo et al. 2016, Glob. + ! Biogeochem. Cycles). DBH-Height takes a simpler log-linear + ! form fitted using SMA so it can be inverted (useful for + ! airborne lidar initialisation). + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change + ! Biol.) + ! c. DBH^2*H -> Leaf area based on the BAAD data base: + ! Falster et al. (2015, Ecology). + ! 4 -- (Under Development) Similar to 3 but (a) leaf and height + ! allometric equations depend on wood density; (b) use + ! height-based root allometry from Smith-Martin et al. (2020, + ! New Phyt.). + ! 5 -- (Under Development) Similar to IALLOM = 3 but using the + ! rooting allometry from IALLOM = 4. + !---------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ed_state_vars.F90 b/ED/src/memory/ed_state_vars.F90 index d72654bec..6451fbb71 100644 --- a/ED/src/memory/ed_state_vars.F90 +++ b/ED/src/memory/ed_state_vars.F90 @@ -633,6 +633,8 @@ module ed_state_vars real, pointer, dimension(:) :: wflux_wl ! mindbh_harvest) in patches with tree felling. + + real , pointer, dimension(:,:) :: felling_s_ltharv + !< Survivorship of small trees (DBH < mindbh_harvest) in patches with tree felling. + + real , pointer, dimension(:,:) :: skid_dbh_thresh + !< DBH threshold for survivorship to logging collateral damage (skid trails and + !< roads). Typically skid/road damage affect small trees more than large trees. + + real , pointer, dimension(:,:) :: skid_s_gtharv + !< Survivorship of large trees (DBH > skid_dbh_thresh) to logging collateral damage. + + real , pointer, dimension(:,:) :: skid_s_ltharv + !< Survivorship of small trees (DBH < skid_dbh_thresh) to logging collateral damage. - !----------------------------------- - ! FORESTRY - !----------------------------------- integer,pointer,dimension(:) :: plantation ! MINDBH_HARVEST' & + ,'[0-1]','(n_pft,isite)') + end if + + if (associated(cpoly%felling_s_ltharv)) then + nvar=nvar+1 + call vtable_edio_r(npts,cpoly%felling_s_ltharv & + ,nvar,igr,init,cpoly%siglob_id,var_len,var_len_global,max_ptrs & + ,'FELLING_S_LTHARV :24:hist') + call metadata_edio(nvar,igr & + ,'Survivorship to felling for trees with DBH < MINDBH_HARVEST' & + ,'[0-1]','(n_pft,isite)') + end if + + if (associated(cpoly%skid_dbh_thresh)) then + nvar=nvar+1 + call vtable_edio_r(npts,cpoly%skid_dbh_thresh & + ,nvar,igr,init,cpoly%siglob_id,var_len,var_len_global,max_ptrs & + ,'SKID_DBH_THRESH :24:hist') + call metadata_edio(nvar,igr & + ,'DBH threshold for collateral logging damage survivorship' & + ,'[cm]','(n_pft,isite)') + end if + + if (associated(cpoly%skid_s_gtharv)) then + nvar=nvar+1 + call vtable_edio_r(npts,cpoly%skid_s_gtharv & + ,nvar,igr,init,cpoly%siglob_id,var_len,var_len_global,max_ptrs & + ,'SKID_S_GTHARV :24:hist') + call metadata_edio(nvar,igr & + ,'Survivorship to collateral logging damage (DBH > SKID_DBH_THRESH)' & + ,'[0-1]','(n_pft,isite)') + end if + + if (associated(cpoly%skid_s_ltharv)) then + nvar=nvar+1 + call vtable_edio_r(npts,cpoly%skid_s_ltharv & + ,nvar,igr,init,cpoly%siglob_id,var_len,var_len_global,max_ptrs & + ,'SKID_S_LTHARV :24:hist') + call metadata_edio(nvar,igr & + ,'Survivorship to collateral logging damage (DBH < SKID_DBH_THRESH)' & + ,'[0-1]','(n_pft,isite)') + end if !------------------------------------------------------------------------------------! return @@ -22910,10 +23118,10 @@ subroutine filltab_polygontype_p29(cpoly,igr,init,var_len,var_len_global,max_ptr call metadata_edio(nvar,igr,'No metadata available','[NA]','NA') end if - if (associated(cpoly%avg_monthly_pcpg)) then + if (associated(cpoly%avg_monthly_accp)) then nvar=nvar+1 - call vtable_edio_r(npts,cpoly%avg_monthly_pcpg,nvar,igr,init,cpoly%siglob_id & - ,var_len,var_len_global,max_ptrs,'AVG_MONTHLY_PCPG :29:hist') + call vtable_edio_r(npts,cpoly%avg_monthly_accp,nvar,igr,init,cpoly%siglob_id & + ,var_len,var_len_global,max_ptrs,'AVG_MONTHLY_ACCP :29:hist') call metadata_edio(nvar,igr,'No metadata available','[NA]','NA') end if @@ -25133,6 +25341,15 @@ subroutine filltab_sitetype_p31fmean(csite,igr,init,var_len,var_len_global,max_p ,'Sub-daily mean - Liquid fraction - temporary water layer' & ,'[ --]','(ipatch)' ) end if + if (associated(csite%fmean_snowfac )) then + nvar = nvar+1 + call vtable_edio_r(npts,csite%fmean_snowfac & + ,nvar,igr,init,csite%paglob_id,var_len,var_len_global,max_ptrs & + ,'FMEAN_SNOWFAC_PA :31:'//trim(fast_keys) ) + call metadata_edio(nvar,igr & + ,'Sub-daily mean - Snow/flood cover fraction' & + ,'[ --]','(ipatch)' ) + end if if (associated(csite%fmean_rshort_gnd )) then nvar = nvar+1 call vtable_edio_r(npts,csite%fmean_rshort_gnd & @@ -25791,6 +26008,15 @@ subroutine filltab_sitetype_p31dmean(csite,igr,init,var_len,var_len_global,max_p ,'Daily mean - Liquid fraction - temporary water layer' & ,'[ --]','(ipatch)' ) end if + if (associated(csite%dmean_snowfac )) then + nvar = nvar+1 + call vtable_edio_r(npts,csite%dmean_snowfac & + ,nvar,igr,init,csite%paglob_id,var_len,var_len_global,max_ptrs & + ,'DMEAN_SNOWFAC_PA :31:'//trim(dail_keys) ) + call metadata_edio(nvar,igr & + ,'Daily mean - Snow/flood cover fraction' & + ,'[ --]','(ipatch)' ) + end if if (associated(csite%dmean_rshort_gnd )) then nvar = nvar+1 call vtable_edio_r(npts,csite%dmean_rshort_gnd & @@ -26381,6 +26607,15 @@ subroutine filltab_sitetype_p31mmean(csite,igr,init,var_len,var_len_global,max_p ,'Monthly mean - Liquid fraction - temporary water layer' & ,'[ --]','(ipatch)' ) end if + if (associated(csite%mmean_snowfac )) then + nvar = nvar+1 + call vtable_edio_r(npts,csite%mmean_snowfac & + ,nvar,igr,init,csite%paglob_id,var_len,var_len_global,max_ptrs & + ,'MMEAN_SNOWFAC_PA :31:'//trim(eorq_keys)) + call metadata_edio(nvar,igr & + ,'Monthly mean - Snow/flood cover fraction' & + ,'[ --]','(ipatch)' ) + end if if (associated(csite%mmean_rshort_gnd )) then nvar = nvar+1 call vtable_edio_r(npts,csite%mmean_rshort_gnd & @@ -27399,6 +27634,15 @@ subroutine filltab_sitetype_m31(csite,igr,init,var_len,var_len_global,max_ptrs,n ,'Mean diel - Liquid fraction - temporary water layer' & ,'[ --]','(ndcycle,ipatch)' ) end if + if (associated(csite%qmean_snowfac )) then + nvar = nvar+1 + call vtable_edio_r(npts,csite%qmean_snowfac & + ,nvar,igr,init,csite%paglob_id,var_len,var_len_global,max_ptrs & + ,'QMEAN_SNOWFAC_PA :-31:'//trim(eorq_keys) ) + call metadata_edio(nvar,igr & + ,'Mean diel - Snow/flood cover fraction' & + ,'[ --]','(ndcycle,ipatch)' ) + end if if (associated(csite%qmean_rshort_gnd )) then nvar = nvar+1 call vtable_edio_r(npts,csite%qmean_rshort_gnd & @@ -32484,7 +32728,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPLEAF_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - Leaf' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppfroot )) then nvar = nvar+1 @@ -32493,7 +32737,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPFROOT_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - Fine root' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppsapwood )) then nvar = nvar+1 @@ -32502,7 +32746,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPSAPWOOD_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - Sap wood' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppbark )) then nvar = nvar+1 @@ -32511,7 +32755,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPBARK_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - Bark' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppcroot )) then nvar = nvar+1 @@ -32520,7 +32764,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPCROOT_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - Coarse root' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppseeds )) then nvar = nvar+1 @@ -32529,7 +32773,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPSEEDS_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - seeds' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppwood )) then nvar = nvar+1 @@ -32538,7 +32782,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPWOOD_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - heart wood' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_nppdaily )) then nvar = nvar+1 @@ -32547,7 +32791,7 @@ subroutine filltab_patchtype_p41mmean(cpatch,igr,init,var_len,var_len_global,max ,'MMEAN_NPPDAILY_CO :41:'//trim(eorq_keys)) call metadata_edio(nvar,igr & ,'Monthly mean - Net primary productivity - total' & - ,'[ kgC/m2/yr]','(icohort)' ) + ,'[ kgC/pl/yr]','(icohort)' ) end if if (associated(cpatch%mmean_dmax_leaf_psi )) then @@ -33621,6 +33865,14 @@ subroutine filltab_patchtype_p42(cpatch,igr,init,var_len,var_len_global,max_ptrs !------------------------------------------------------------------------------------! npts = cpatch%ncohorts * nzg + if (associated(cpatch%root_frac)) then + nvar=nvar+1 + call vtable_edio_r(npts,cpatch%root_frac & + ,nvar,igr,init,cpatch%coglob_id,var_len,var_len_global,max_ptrs & + ,'ROOT_FRAC :42:hist') + call metadata_edio(nvar,igr,'Fraction of roots by layer','[--]','(nzg,icohort)') + end if + if (associated(cpatch%wflux_gw_layer)) then nvar=nvar+1 call vtable_edio_r(npts,cpatch%wflux_gw_layer & diff --git a/ED/src/memory/ed_var_tables.f90 b/ED/src/memory/ed_var_tables.f90 index 9b98449ea..0e3aaff0e 100644 --- a/ED/src/memory/ed_var_tables.f90 +++ b/ED/src/memory/ed_var_tables.f90 @@ -74,6 +74,8 @@ ! ! 91 : rank 0 : real scalar ! ! ! ! 92 : rank 1 : real, s-layer ! ! ! ! 96 : rank 1 : real, height class ! ! +! ! 98 : rank 1 : real, ed_nstyp ! ! +! ! 980 : rank 1 : integer, ed_nstyp ! ! ! !-----------------------------------------------------! ! ! ! !------------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ename_coms.f90 b/ED/src/memory/ename_coms.f90 index d838efbd3..cf6cb0a45 100644 --- a/ED/src/memory/ename_coms.f90 +++ b/ED/src/memory/ename_coms.f90 @@ -224,6 +224,7 @@ module ename_coms real , dimension(n_pft) :: sl_mindbh_harvest real :: sl_biomass_harvest real :: sl_skid_rel_area + real :: sl_skid_dbh_thresh real :: sl_skid_s_gtharv real :: sl_skid_s_ltharv real :: sl_felling_s_ltharv @@ -528,6 +529,7 @@ subroutine init_ename_vars(enl) enl%sl_mindbh_harvest = (/(undef_real ,i=1,n_pft)/) enl%sl_biomass_harvest = undef_real enl%sl_skid_rel_area = undef_real + enl%sl_skid_dbh_thresh = undef_real enl%sl_skid_s_gtharv = undef_real enl%sl_skid_s_ltharv = undef_real enl%sl_felling_s_ltharv = undef_real diff --git a/ED/src/memory/pft_coms.f90 b/ED/src/memory/pft_coms.f90 index 7bfe02049..dfc73bf22 100644 --- a/ED/src/memory/pft_coms.f90 +++ b/ED/src/memory/pft_coms.f90 @@ -250,6 +250,9 @@ module pft_coms !----- Specifies photosynthetic pathway. 3 corresponds to C3, 4 corresponds to C4. ----! integer, dimension(n_pft) :: photosyn_pathway + + !----- Flag to identify whether or not to use allometric equations based on D*D*H. -----! + logical, dimension(n_pft) :: ddh_allom !=======================================================================================! !=======================================================================================! diff --git a/ED/src/memory/phenology_coms.f90 b/ED/src/memory/phenology_coms.f90 index 08844c07d..64f1816e7 100644 --- a/ED/src/memory/phenology_coms.f90 +++ b/ED/src/memory/phenology_coms.f90 @@ -22,40 +22,55 @@ module phenology_coms integer :: iphen_scheme !---------------------------------------------------------------------------------------! - !< IPHEN_SCHEME -- It controls the phenology scheme. Even within each scheme, the \n - !< actual phenology will be different depending on the PFT. \n + != 0.0) then + soil(s)%soilld = soil(s)%soilwp & + + thetacrit * (soil(s)%slmsts-soil(s)%soilwp) + soil(s)%slpotld = matric_potential(s,soil(s)%soilld) + else + soil(s)%slpotld = thetacrit * 1.e6 / (grav * wdns) + soil(s)%soilld = soil_moisture(s,soil(s)%slpotld) + end if + !----- Fire. ------------------------------------------------------------------! + if (sm_fire >= 0.0) then + soil(s)%soilfr = soil(s)%soilcp + sm_fire * (soil(s)%slmsts-soil(s)%soilcp) + soil(s)%slpotfr = matric_potential(s,soil(s)%soilfr) + else + soil(s)%slpotfr = sm_fire * 1.e6 / (grav * wdns) + soil(s)%soilfr = soil_moisture(s,soil(s)%slpotfr) + end if + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Define hydraulic parameter decay, similar to TOPMODEL. We currently use ! + ! the default value of 2.0, following N05's SIMTOP model. ! + ! ! + ! Niu GY, Yang ZL, Dickinson RE , Gulden LE. 2005. A simple TOPMODEL-based ! + ! runoff parameterization (SIMTOP) for use in global climate models. ! + ! J. Geophys. Res.-Atmos., 110: D21106. doi:10.1029/2005JD006111 (N05). ! + !------------------------------------------------------------------------------! + soil(s)%fhydraul = 2.0 + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Heat capacity (J/m3/K). Here we take the volume average amongst silt, ! + ! clay, and sand, and consider the contribution of air sitting in. In order to ! + ! keep it simple, we assume that the air fraction won't change, although in ! + ! reality its contribution should be a function of soil moisture. Here we use ! + ! the amount of air in case the soil moisture was halfway between dry air and ! + ! saturated, so the error is not too biased. ! + !---------------------------------------------------------------------------------! + soil(s)%slcpd = (1. - soil(s)%slmsts) & + * ( soil(s)%xsand * sand_hcapv + soil(s)%xsilt * silt_hcapv & + + soil(s)%xclay * clay_hcapv ) & + + 0.5 * ( soil(s)%slmsts - soil(s)%soilcp ) * air_hcapv + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Thermal conductivity is the weighted average of thermal conductivities of ! + ! all materials, although a further weighting factor due to thermal gradient of ! + ! different materials. We use the de Vries model described at: ! + ! ! + ! Camillo, P., T.J. Schmugge, 1981: A computer program for the simulation of heat ! + ! and moisture flow in soils, NASA-TM-82121, Greenbelt, MD, United States. ! + ! ! + ! Parlange, M.B., et al., 1998: Review of heat and water movement in field soils, ! + ! Soil Till. Res., 47(1-2), 5-10. ! + ! ! + !---------------------------------------------------------------------------------! + !---- The k-factors, assuming spherical particles. -------------------------------! + ksand = 3. * h2o_thcond / ( 2. * h2o_thcond + sand_thcond ) + ksilt = 3. * h2o_thcond / ( 2. * h2o_thcond + silt_thcond ) + kclay = 3. * h2o_thcond / ( 2. * h2o_thcond + clay_thcond ) + kair = 3. * h2o_thcond / ( 2. * h2o_thcond + air_thcond ) + !---- The conductivity coefficients. ---------------------------------------------! + soil(s)%thcond0 = (1. - soil(s)%slmsts ) & + * ( ksand * soil(s)%xsand * sand_thcond & + + ksilt * soil(s)%xsilt * silt_thcond & + + kclay * soil(s)%xclay * clay_thcond ) & + + soil(s)%slmsts * kair * air_thcond + soil(s)%thcond1 = h2o_thcond - kair * air_thcond + soil(s)%thcond2 = (1. - soil(s)%slmsts ) & + * ( ksand * soil(s)%xsand + ksilt * soil(s)%xsilt & + + kclay * soil(s)%xclay ) & + + soil(s)%slmsts * kair + soil(s)%thcond3 = 1. - kair + !---------------------------------------------------------------------------------! + + end do + !------------------------------------------------------------------------------------! + + + + !----- Here we fill soil8, which will be used in Runge-Kutta (double precision). ----! + do s=1,ed_nstyp + soil8(s)%key = soil(s)%key + soil8(s)%method = soil(s)%method + soil8(s)%xsand = dble(soil(s)%xsand ) + soil8(s)%xsilt = dble(soil(s)%xsilt ) + soil8(s)%xclay = dble(soil(s)%xclay ) + soil8(s)%slsoc = dble(soil(s)%slsoc ) + soil8(s)%slph = dble(soil(s)%slph ) + soil8(s)%slcec = dble(soil(s)%slcec ) + soil8(s)%sldbd = dble(soil(s)%sldbd ) + soil8(s)%soilre = dble(soil(s)%soilre ) + soil8(s)%soilcp = dble(soil(s)%soilcp ) + soil8(s)%soilwp = dble(soil(s)%soilwp ) + soil8(s)%soilfr = dble(soil(s)%soilfr ) + soil8(s)%soilld = dble(soil(s)%soilld ) + soil8(s)%sfldcap = dble(soil(s)%sfldcap ) + soil8(s)%soilbp = dble(soil(s)%soilbp ) + soil8(s)%slmsts = dble(soil(s)%slmsts ) + soil8(s)%soilpo = dble(soil(s)%soilpo ) + soil8(s)%slpotcp = dble(soil(s)%slpotcp ) + soil8(s)%slpotwp = dble(soil(s)%slpotwp ) + soil8(s)%slpotfr = dble(soil(s)%slpotfr ) + soil8(s)%slpotld = dble(soil(s)%slpotld ) + soil8(s)%slpotfc = dble(soil(s)%slpotfc ) + soil8(s)%slpotbp = dble(soil(s)%slpotbp ) + soil8(s)%slpots = dble(soil(s)%slpots ) + soil8(s)%slpotpo = dble(soil(s)%slpotpo ) + soil8(s)%sltt = dble(soil(s)%sltt ) + soil8(s)%slnm = dble(soil(s)%slnm ) + soil8(s)%slbs = dble(soil(s)%slbs ) + soil8(s)%slmm = dble(soil(s)%slmm ) + soil8(s)%slmu = dble(soil(s)%slmu ) + soil8(s)%malpha = dble(soil(s)%malpha ) + soil8(s)%slcons = dble(soil(s)%slcons ) + soil8(s)%fhydraul = dble(soil(s)%fhydraul) + soil8(s)%slcpd = dble(soil(s)%slcpd ) + soil8(s)%thcond0 = dble(soil(s)%thcond0 ) + soil8(s)%thcond1 = dble(soil(s)%thcond1 ) + soil8(s)%thcond2 = dble(soil(s)%thcond2 ) + soil8(s)%thcond3 = dble(soil(s)%thcond3 ) + end do + !------------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------------! + ! Decide whether to write the table with the soil properties. ! + !------------------------------------------------------------------------------------! + print_soil_table = btest(idetailed,5) + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Print the parameters in case the user wants it. ! + !------------------------------------------------------------------------------------! + if (print_soil_table) then + !----- Open and write header. ----------------------------------------------------! + open (unit=26,file=trim(soil_table_fn),status='replace',action='write') + write(unit=26,fmt='(38(a,1x))') 'ISOIL', ' KEY', 'TYPE' & + ,' XSAND',' XSILT',' XCLAY' & + ,' SLSOC',' SLPH',' SLCEC' & + ,' SLDBD',' SOILRE',' SOILCP' & + ,' SOILWP',' SOILFR',' SOILLD' & + ,' SOILFC',' SOILBP',' SOILPO' & + ,' SLPOTCP',' SLPOTWP',' SLPOTFR' & + ,' SLPOTLD',' SLPOTFC',' SLPOTBP' & + ,' SLPOTPO',' SLTT',' SLNM' & + ,' SLBS',' SLMM',' SLMU' & + ,' MALPHA',' SLCONS_MMHR',' FHYDRAUL' & + ,' SLCPD_MJm3K',' THCOND0',' THCOND1' & + ,' THCOND2',' THCOND3' + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Loop over soil texture types. ! + !---------------------------------------------------------------------------------! + do s=1,ed_nstyp + !----- For some variables, we use different units to make them more legible. --! + slcons_mmhr = soil(s)%slcons*1000.*hr_sec + slcpd_mjm3k = soil(s)%slcpd*0.001 + !------------------------------------------------------------------------------! + + !----- Add soil characteristics. ----------------------------------------------! + write(unit=26,fmt='(i5,1x,2(a4,1x),35(f12.5,1x))') & + s,adjustr(soil(s)%key),adjustr(soil(s)%method) & + ,soil(s)%xsand ,soil(s)%xsilt ,soil(s)%xclay & + ,soil(s)%slsoc ,soil(s)%slph ,soil(s)%slcec & + ,soil(s)%sldbd ,soil(s)%soilre ,soil(s)%soilcp & + ,soil(s)%soilwp ,soil(s)%soilfr ,soil(s)%soilld & + ,soil(s)%sfldcap ,soil(s)%soilbp ,soil(s)%slmsts & + ,soil(s)%slpotcp ,soil(s)%slpotwp ,soil(s)%slpotfr & + ,soil(s)%slpotld ,soil(s)%slpotfc ,soil(s)%slpotbp & + ,soil(s)%slpots ,soil(s)%sltt ,soil(s)%slnm & + ,soil(s)%slbs ,soil(s)%slmm ,soil(s)%slmu & + ,soil(s)%malpha ,slcons_mmhr ,soil(s)%fhydraul & + ,slcpd_mjm3k ,soil(s)%thcond0 ,soil(s)%thcond1 & + ,soil(s)%thcond2 ,soil(s)%thcond3 + !------------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------------! + + + !----- Close table. --------------------------------------------------------------! + close(unit=26,status='keep') + !---------------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------------! + + + return + end subroutine ed_gen_soil_table + !=======================================================================================! + !=======================================================================================! + + + + + + !=======================================================================================! !=======================================================================================! ! This function determines the soil class based on the fraction of sand, clay, and ! diff --git a/ED/src/mpi/ed_mpass_init.F90 b/ED/src/mpi/ed_mpass_init.F90 index 2aebbf93b..39536635b 100644 --- a/ED/src/mpi/ed_mpass_init.F90 +++ b/ED/src/mpi/ed_mpass_init.F90 @@ -16,6 +16,7 @@ subroutine ed_masterput_processid(nproc,headnode_num,masterworks,par_run) , recvnum & ! intent(out) , master_num & ! intent(out) , machs ! ! intent(out) + use mpi #else use ed_para_coms, only : nmachs & ! intent(in) , machsize & ! intent(in) @@ -38,7 +39,6 @@ subroutine ed_masterput_processid(nproc,headnode_num,masterworks,par_run) integer :: nm #if defined(RAMS_MPI) integer :: ierr - include 'mpif.h' !---------------------------------------------------------------------------------------! #endif @@ -101,6 +101,7 @@ end subroutine ed_masterput_processid !------------------------------------------------------------------------------------------! subroutine ed_masterput_nl(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) use ed_max_dims , only : str_len & ! intent(in) , max_poi & ! intent(in) @@ -325,6 +326,7 @@ subroutine ed_masterput_nl(par_run) , sl_mindbh_harvest & ! intent(in) , sl_biomass_harvest & ! intent(in) , sl_skid_rel_area & ! intent(in) + , sl_skid_dbh_thresh & ! intent(in) , sl_skid_s_gtharv & ! intent(in) , sl_skid_s_ltharv & ! intent(in) , sl_felling_s_ltharv & ! intent(in) @@ -368,8 +370,6 @@ subroutine ed_masterput_nl(par_run) !----- Local variables. ----------------------------------------------------------------! integer :: ierr integer :: n - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -585,6 +585,7 @@ subroutine ed_masterput_nl(par_run) call MPI_Bcast(sl_mindbh_harvest ,n_pft,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_biomass_harvest , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_rel_area , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) + call MPI_Bcast(sl_skid_dbh_thresh , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_gtharv , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_ltharv , 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_felling_s_ltharv, 1,MPI_REAL ,mainnum,MPI_COMM_WORLD,ierr) @@ -706,6 +707,7 @@ end subroutine ed_masterput_nl !------------------------------------------------------------------------------------------! subroutine ed_masterput_met_header(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) use ed_max_dims , only : max_met_vars & ! intent(in) , str_len ! ! intent(in) @@ -736,8 +738,6 @@ subroutine ed_masterput_met_header(par_run) integer :: nsize integer :: f integer :: v - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' !---------------------------------------------------------------------------------------! #endif @@ -802,6 +802,7 @@ end subroutine ed_masterput_met_header !==========================================================================================! subroutine ed_masterput_poly_dims(par_run,masterworks) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) #endif use ed_para_coms , only : nmachs & ! intent(in) @@ -838,7 +839,6 @@ subroutine ed_masterput_poly_dims(par_run,masterworks) real :: totalwork #if defined(RAMS_MPI) integer :: ierr - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -1107,6 +1107,7 @@ end subroutine ed_masterput_poly_dims !------------------------------------------------------------------------------------------! subroutine ed_masterput_worklist_info(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : machnum ! ! intent(in) #endif use ed_max_dims , only : maxmach @@ -1139,8 +1140,6 @@ subroutine ed_masterput_worklist_info(par_run) integer :: mpiid integer , dimension(:), allocatable :: iscratch real , dimension(:), allocatable :: rscratch - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -1300,6 +1299,7 @@ end subroutine ed_masterput_worklist_info !------------------------------------------------------------------------------------------! subroutine ed_nodeget_processid(init) #if defined(RAMS_MPI) + use mpi use ed_node_coms, only : master_num & ! intent(out) , mchnum & ! intent(out) , mynum & ! intent(out) @@ -1316,7 +1316,6 @@ subroutine ed_nodeget_processid(init) integer, intent(in) :: init !----- Local variables. ----------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' integer, dimension(MPI_STATUS_SIZE) :: status #endif integer :: ierr @@ -1361,6 +1360,7 @@ end subroutine ed_nodeget_processid !------------------------------------------------------------------------------------------! subroutine ed_nodeget_nl #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : master_num ! ! intent(in) use ed_max_dims , only : str_len & ! intent(in) , max_poi & ! intent(in) @@ -1585,6 +1585,7 @@ subroutine ed_nodeget_nl , sl_mindbh_harvest & ! intent(out) , sl_biomass_harvest & ! intent(out) , sl_skid_rel_area & ! intent(out) + , sl_skid_dbh_thresh & ! intent(out) , sl_skid_s_gtharv & ! intent(out) , sl_skid_s_ltharv & ! intent(out) , sl_felling_s_ltharv & ! intent(out) @@ -1622,7 +1623,6 @@ subroutine ed_nodeget_nl #endif implicit none #if defined(RAMS_MPI) - include 'mpif.h' !----- Local variables. ----------------------------------------------------------------! integer :: n #endif @@ -1848,6 +1848,7 @@ subroutine ed_nodeget_nl call MPI_Bcast(sl_mindbh_harvest ,n_pft,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_biomass_harvest , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_rel_area , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) + call MPI_Bcast(sl_skid_dbh_thresh , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_gtharv , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_skid_s_ltharv , 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) call MPI_Bcast(sl_felling_s_ltharv, 1,MPI_REAL ,master_num,MPI_COMM_WORLD,ierr) @@ -1975,6 +1976,7 @@ end subroutine ed_nodeget_nl !------------------------------------------------------------------------------------------! subroutine ed_nodeget_met_header() #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : master_num ! ! intent(in) use ed_max_dims , only : max_met_vars & ! intent(in) , str_len ! ! intent(in) @@ -1998,7 +2000,6 @@ subroutine ed_nodeget_met_header() implicit none #if defined(RAMS_MPI) - include 'mpif.h' !---- Local variables. -----------------------------------------------------------------! integer :: ierr integer :: nsize @@ -2077,6 +2078,7 @@ end subroutine ed_nodeget_met_header !==========================================================================================! subroutine ed_nodeget_poly_dims #if defined(RAMS_MPI) + use mpi use ed_state_vars, only : gdpy & ! intent(out) , py_off ! ! intent(out) use ed_node_coms , only : master_num & ! intent(in) @@ -2091,8 +2093,6 @@ subroutine ed_nodeget_poly_dims integer :: ierr integer :: ifm integer :: nm - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' !---------------------------------------------------------------------------------------! do ifm=1,ngrids do nm=1,nmachs @@ -2127,15 +2127,12 @@ subroutine ed_nodeget_worklist_info use mem_polygons , only : maxsite ! ! intent(in) use ed_node_coms , only : mynum ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_max_dims , only : maxmach ! ! intent(in) use ed_node_coms , only : master_num ! ! intent(in) #endif implicit none -#if defined(RAMS_MPI) - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' -#endif !------ Local variables. ---------------------------------------------------------------! integer :: npolygons integer :: ifm diff --git a/ED/src/mpi/ed_para_init.f90 b/ED/src/mpi/ed_para_init.f90 index b34a0f3dd..2037f5714 100644 --- a/ED/src/mpi/ed_para_init.f90 +++ b/ED/src/mpi/ed_para_init.f90 @@ -517,7 +517,6 @@ subroutine ed_parvec_work(ifm,nxp,nyp) , npolys_run & ! intent(out) , ed_alloc_work_vec & ! subroutine , ed_nullify_work_vec ! ! subroutine - use soil_coms , only : ed_nstyp ! ! intent(in) use mem_polygons , only : maxsite ! ! intent(in) implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -659,7 +658,8 @@ subroutine ed_load_work_from_history() real , external :: dist_gc !---------------------------------------------------------------------------------------! - + write (unit=*,fmt='(a)') ' Welcome to ed_load_work_from_history!' + !---------------------------------------------------------------------------------------! ! Here we decide whether this is a history or an ED-2.1 restart run. In case none ! diff --git a/ED/src/utils/allometry.f90 b/ED/src/utils/allometry.f90 index 1be867ce1..ab95f50d4 100644 --- a/ED/src/utils/allometry.f90 +++ b/ED/src/utils/allometry.f90 @@ -142,10 +142,8 @@ real function size2bd(dbh,hite,ipft) , b1Bs_large & ! intent(in) , b2Bs_large & ! intent(in) , is_grass & ! intent(in) - , is_tropical & ! intent(in) - , is_liana ! ! intent(in) - use ed_misc_coms, only : igrass & ! intent(in) - , iallom ! ! intent(in) + , ddh_allom ! ! intent(in) + use ed_misc_coms, only : igrass ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -164,8 +162,7 @@ real function size2bd(dbh,hite,ipft) size2bd = 0.0 else !----- Depending on the allometry, size means DBH or DBH^2 * Height. -------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = dbh * dbh * hite else size = dbh @@ -305,10 +302,9 @@ real function size2bl(dbh,hite,sla_in,ipft) , b2Bl & ! intent(in) , is_liana & ! intent(in) , is_grass & ! intent(in) - , is_tropical & ! intent(in) + , ddh_allom & ! intent(in) , liana_dbh_crit ! ! intent(in) - use ed_misc_coms , only : igrass & ! intent(in) - , iallom ! ! intent(in) + use ed_misc_coms , only : igrass ! ! intent(in) use ed_state_vars, only : patchtype ! ! structure implicit none @@ -341,8 +337,7 @@ real function size2bl(dbh,hite,sla_in,ipft) ! Find leaf biomass depending on the allometry. The new allometry uses dbh and ! ! height, whereas the old allometry uses dbh only. ! !------------------------------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * hite else size = mdbh @@ -352,10 +347,10 @@ real function size2bl(dbh,hite,sla_in,ipft) !------------------------------------------------------------------------------------! - ! For iallom == 4 (tropical trees), b1Bl and b2Bl represents leaf area based ! - ! allometry, we need to convert it to biomass using cohort-level SLA. ! + ! Currently, b1Bl/b2Bl are parameters for individual leaf area (as opposed to ! + ! individual leaf biomass) when using the D*D*H-based allometry. ! !------------------------------------------------------------------------------------! - if (iallom == 4 .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then !----- Use specific form (notice that C2B was cancelled out. ---------------------! size2bl = b1Bl(ipft) / sla_in * size ** b2Bl(ipft) !---------------------------------------------------------------------------------! @@ -452,10 +447,10 @@ end function ba2h ! DBH has no real meaning for grasses with the new allometry. ! !---------------------------------------------------------------------------------------! real function bl2dbh(bleaf,sla_in,ipft) - use pft_coms , only : dbh_crit & ! intent(in) + use pft_coms , only : ddh_allom & ! intent(in) + , dbh_crit & ! intent(in) , l1DBH & ! intent(in) , l2DBH ! ! intent(in) - use ed_misc_coms, only : iallom ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -468,17 +463,15 @@ real function bl2dbh(bleaf,sla_in,ipft) !------------------------------------------------------------------------------------! - ! The inverse function works for both DBH- and DBH^2*Hgt-based allometric ! - ! equations, because l1DBH and l2DBH already account for the different allometric ! - ! functions. However, for leaf-area-based allometry (IALLOM = 4), we need to multiply! - ! bleaf with sla_in to get leaf area because l1DBH and l2DBH are based on leaf area ! + ! The functional for is similar, but when using the D*D*H-allometry, we must ! + ! multiply leaf biomass with SLA, because b1Bl and b2Bl are coefficients for leaf ! + ! area, instead of leaf biomass. ! !------------------------------------------------------------------------------------! - select case (iallom) - case (4) + if (ddh_allom(ipft)) then mdbh = l1DBH(ipft) * (bleaf * sla_in) ** l2DBH(ipft) - case default + else mdbh = l1DBH(ipft) * bleaf ** l2DBH(ipft) - end select + end if !------------------------------------------------------------------------------------! @@ -539,7 +532,7 @@ real function size2ca(dbh,hite,sla,ipft,cap_crit) , hgt_max & ! intent(in) , is_grass & ! intent(in) , is_liana & ! intent(in) - , is_tropical & ! intent(in) + , ddh_allom & ! intent(in) , b1Ca & ! intent(in) , b2Ca & ! intent(in) , liana_dbh_crit ! ! intent(in) @@ -608,8 +601,7 @@ real function size2ca(dbh,hite,sla,ipft,cap_crit) !----- Find the nominal crown area. ----------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * hite else size = mdbh @@ -889,13 +881,6 @@ real function size2prd(hite,dbh,ipft) !------------------------------------------------------------------------------! size = dbh * dbh * hite !------------------------------------------------------------------------------! - case (1,2,4) - !------------------------------------------------------------------------------! - ! This is just a test allometry, that imposes root depth to be 0.5 m for ! - ! plants that are 0.15-m tall, and 5.0 m for plants that are 35-m tall. ! - !------------------------------------------------------------------------------! - size = hite - !------------------------------------------------------------------------------! case (3) !------------------------------------------------------------------------------! ! Test allometry, similar to 2, but based on D*D*H. The curve loosely fits ! @@ -920,6 +905,12 @@ real function size2prd(hite,dbh,ipft) size = hite end if !------------------------------------------------------------------------------! + case default + !------------------------------------------------------------------------------! + ! Size is always height, regardless of the PFT. ! + !------------------------------------------------------------------------------! + size = hite + !------------------------------------------------------------------------------! end select !---------------------------------------------------------------------------------! @@ -1401,14 +1392,13 @@ subroutine area_indices(cpatch, ico) use ed_state_vars, only : patchtype ! ! Structure use pft_coms , only : dbh_crit & ! intent(in) , is_liana & ! intent(in) - , is_tropical & ! intent(in) , is_grass & ! intent(in) + , ddh_allom & ! intent(in) , b1WAI & ! intent(in) , b2WAI & ! intent(in) , liana_dbh_crit ! ! intent(in) use rk4_coms , only : ibranch_thermo ! ! intent(in) - use ed_misc_coms , only : igrass & ! intent(in) - , iallom ! ! intent(in) + use ed_misc_coms , only : igrass ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -1422,7 +1412,9 @@ subroutine area_indices(cpatch, ico) !------------------------------------------------------------------------------------! + !----- Useful aliases. --------------------------------------------------------------! ipft = cpatch%pft(ico) + !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! @@ -1466,8 +1458,7 @@ subroutine area_indices(cpatch, ico) !-----Find WAI. ------------------------------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * cpatch%hite(ico) else size = mdbh @@ -1481,6 +1472,87 @@ subroutine area_indices(cpatch, ico) end subroutine area_indices !=======================================================================================! !=======================================================================================! + + + + + + + !=======================================================================================! + !=======================================================================================! + ! This function defines the vertical root distribution. ! + !---------------------------------------------------------------------------------------! + subroutine distrib_root(kroot,ipft,root_frac) + use grid_coms , only : nzg ! ! intent(in) + use soil_coms , only : slz ! ! intent(in) + use pft_coms , only : root_beta ! ! intent(in) + use physiology_coms, only : plant_hydro_scheme ! ! intent(in) + implicit none + !----- Arguments. -------------------------------------------------------------------! + integer , intent(in) :: kroot + integer , intent(in) :: ipft + real , dimension(nzg) , intent(out) :: root_frac + !----- Local variables. -------------------------------------------------------------! + integer :: k + real :: slzboti + real :: sbetai + real , dimension(nzg+1) :: root_cumul + !------------------------------------------------------------------------------------! + + + + !----- Useful short names. ----------------------------------------------------------! + slzboti = 1. / slz(kroot) + sbetai = 1. / (1. - root_beta(ipft)) + !------------------------------------------------------------------------------------! + + + + !----- Initialise the fractions. ----------------------------------------------------! + root_cumul(:) = 1. + root_frac (:) = 0. + root_cumul(nzg+1) = 0. + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Decide how to split root fraction. Currently this is bound to plant hydro- ! + ! dynamics, but in the future we could make this a flag on its own, for testing ! + ! different hypotheses. ! + !------------------------------------------------------------------------------------! + select case (plant_hydro_scheme) + case (0) + !---------------------------------------------------------------------------------! + ! Default ED-2. Roots evenly distributed across depth. Currently this is ! + ! a diagnostic variable and not used anywhere in the code. ! + !---------------------------------------------------------------------------------! + do k=kroot+1,nzg + root_cumul(k) = slz(k) * slzboti + end do + !---------------------------------------------------------------------------------! + case default + !------ Plant hydrodynamics, assume a power decay. -------------------------------! + do k=kroot+1,nzg + root_cumul(k) = sbetai * ( 1. - root_beta(ipft) ** (slz(k) * slzboti) ) + end do + !---------------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! The rooting fraction is the difference in cumulative rooting density. ! + !------------------------------------------------------------------------------------! + do k=kroot,nzg + root_frac(k) = root_cumul(k) - root_cumul(k+1) + end do + !------------------------------------------------------------------------------------! + + + return + end subroutine distrib_root + !=======================================================================================! + !=======================================================================================! end module allometry !==========================================================================================! !==========================================================================================! diff --git a/ED/src/utils/ed_filelist.F90 b/ED/src/utils/ed_filelist.F90 index 88dd482bc..e4f81745a 100644 --- a/ED/src/utils/ed_filelist.F90 +++ b/ED/src/utils/ed_filelist.F90 @@ -198,10 +198,19 @@ subroutine ed1_fileinfo(text,nfiles,full_list,ntype,type_list,tlon_list,tlat_lis select case(text) case ('.site') okdot = 4 - case ('.pss','.css','.txt') + case ('.sss','.pss','.css','.txt') okdot = 3 case ('.lu') okdot = 2 + case default + write (unit=*,fmt='(a)' ) '----------------------------------------------' + write (unit=*,fmt='(a)' ) ' Unrecognised extension for ED1 file style! ' + write (unit=*,fmt='(a)' ) '----------------------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' TEXT = ',trim(text) + write (unit=*,fmt='(a,1x,i12)') ' NFILES = ',nfiles + write (unit=*,fmt='(a,1x,a)' ) ' FULL_LIST(1st) = ',trim(full_list(1)) + write (unit=*,fmt='(a)' ) '----------------------------------------------' + call fatal_error('Invalid file extension','ed1_fileinfo','ed_filelist.F90') end select diff --git a/ED/src/utils/fatal_error.F90 b/ED/src/utils/fatal_error.F90 index 18bf18a8c..e54335c03 100644 --- a/ED/src/utils/fatal_error.F90 +++ b/ED/src/utils/fatal_error.F90 @@ -8,6 +8,9 @@ subroutine fatal_error(reason,subr,file) use ed_node_coms , only : nnodetot & ! intent(in) , mynum ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! character(len=*), intent(in) :: reason @@ -18,9 +21,6 @@ subroutine fatal_error(reason,subr,file) logical :: slavenode !---------------------------------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! ! Check which type of end we should use. For the main program, this should never ! diff --git a/ED/src/utils/fuse_fiss_utils.f90 b/ED/src/utils/fuse_fiss_utils.f90 index 213f00572..caff9a989 100644 --- a/ED/src/utils/fuse_fiss_utils.f90 +++ b/ED/src/utils/fuse_fiss_utils.f90 @@ -1995,7 +1995,8 @@ subroutine fuse_2_cohorts(cpatch,donc,recc,can_prss,can_shv,lsl,fuse_initial) , bl2h & ! function , dbh2h & ! function , size2xb & ! function - , ed_balive ! ! function + , ed_balive & ! function + , distrib_root ! ! subroutine use ed_max_dims , only : n_mort ! ! intent(in) use ed_misc_coms , only : writing_long & ! intent(in) , writing_eorq & ! intent(in) @@ -2198,6 +2199,12 @@ subroutine fuse_2_cohorts(cpatch,donc,recc,can_prss,can_shv,lsl,fuse_initial) + !----- Update the vertical distribution of roots. -----------------------------------! + call distrib_root(cpatch%krdepth(recc),cpatch%pft(recc),cpatch%root_frac(:,recc)) + !------------------------------------------------------------------------------------! + + + !----- Maintenance costs. -----------------------------------------------------------! cpatch%leaf_maintenance (recc) = cpatch%leaf_maintenance (recc) * rnplant & @@ -7578,6 +7585,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%fmean_sfcw_mass (recp) * rawgt csite%fmean_sfcw_mass (recp) = csite%fmean_sfcw_mass (donp) * dawgt & + csite%fmean_sfcw_mass (recp) * rawgt + csite%fmean_snowfac (recp) = csite%fmean_snowfac (donp) * dawgt & + + csite%fmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ------------------------------! if (csite%fmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%fmean_sfcw_energy (recp) = csite%fmean_sfcw_energy (recp) & @@ -7775,6 +7784,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%dmean_sfcw_mass (recp) * rawgt csite%dmean_sfcw_mass (recp) = csite%dmean_sfcw_mass (donp) * dawgt & + csite%dmean_sfcw_mass (recp) * rawgt + csite%dmean_snowfac (recp) = csite%dmean_snowfac (donp) * dawgt & + + csite%dmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ---------------------------! if (csite%dmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%dmean_sfcw_energy (recp) = csite%dmean_sfcw_energy (recp) & @@ -8169,6 +8180,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%mmean_sfcw_mass (recp) * rawgt csite%mmean_sfcw_mass (recp) = csite%mmean_sfcw_mass (donp) * dawgt & + csite%mmean_sfcw_mass (recp) * rawgt + csite%mmean_snowfac (recp) = csite%mmean_snowfac (donp) * dawgt & + + csite%mmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ---------------------------! if (csite%mmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%mmean_sfcw_energy (recp) = csite%mmean_sfcw_energy (recp) & @@ -8520,6 +8533,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%qmean_sfcw_mass (t,recp) * rawgt csite%qmean_sfcw_mass (t,recp) = csite%qmean_sfcw_mass (t,donp) * dawgt & + csite%qmean_sfcw_mass (t,recp) * rawgt + csite%qmean_snowfac (t,recp) = csite%qmean_snowfac (t,donp) * dawgt & + + csite%qmean_snowfac (t,recp) * rawgt !----- Check whether there is enough surface water. ------------------------! if (csite%qmean_sfcw_mass(t,recp) > tiny_sfcwater_mass) then csite%qmean_sfcw_energy (t,recp) = csite%qmean_sfcw_energy(t,recp) & diff --git a/ED/src/utils/numutils.f90 b/ED/src/utils/numutils.f90 index 5207f9b50..e8930d092 100644 --- a/ED/src/utils/numutils.f90 +++ b/ED/src/utils/numutils.f90 @@ -431,11 +431,12 @@ end subroutine cumsum !==========================================================================================! ! This subroutine is the double precision version of the linear system solver above. ! ! It will solve the linear system AA . X = Y for given AA and Y, using the Gaussian ! -! elimination method with partial pivoting and back-substitution. This subroutine is ! -! based on: ! +! elimination method with partial pivoting and back-substitution. This subroutine builds ! +! on the algorithm described in P92, but adopting a vector-based approach compatible with ! +! modern Fortran. ! ! ! ! Press, W. H., S. A. Teukolsky, W. T. Vetterling, B. P. Flannery: 1992. Numerical recipes ! -! in Fortran 77. Cambridge University Press. ! +! in Fortran 77. Cambridge University Press (P92). ! !------------------------------------------------------------------------------------------! subroutine lisys_solver8(nsiz,AA,Y,X,sing) implicit none @@ -536,6 +537,8 @@ end subroutine lisys_solver8 + + !==========================================================================================! !==========================================================================================! ! EIFUN8 -- This function computes the exponential integral function, defined by ! @@ -544,35 +547,49 @@ end subroutine lisys_solver8 ! | exp(t) ! ! Ei(x) = | -------- dt ! ! _| t ! -! 0 ! +! -Inf ! ! ! -! This function is based on: ! +! This function checks for two approaches: series expansion, which typically works ! +! best when x is small, and the asymptotic expansion, which typically works best when x is ! +! large. The approach selects the smallest result (in absolute numbers) as the most ! +! accurate method. Both the series expansion and the asymptotic expansion are provided in ! +! AS72. This approach also checks for some other edge cases, and ignores the results when ! +! the value is very negative. ! ! ! -! Press, W. H., S. A. Teukolsky, W. T. Vetterling, B. P. Flannery: 1992. Numerical recipes ! -! in Fortran 77. Cambridge University Press, section 6.3 p. 215-219. ! +! Reference: ! +! ! +! Abramowitz, M., and I. A. Stegun, Eds., 1972: Handbook of mathematical functions with ! +! formulas, graphs, and mathematical tables. 10th ed., No. 55, Applied Mathematics ! +! Series, National Bureau of Standards, Washington, DC, USA (AS72). ! ! ! -! with the difference that we also solve for negative numbers. Zero cannot be solved, so ! -! if this happens, or if the sought number would lead to infinity, we stop the model. ! !------------------------------------------------------------------------------------------! real(kind=8) function eifun8(x) - use consts_coms, only : euler_gam8 & ! intent(in) - , lnexp_min8 & ! intent(in) - , lnexp_max8 & ! intent(in) - , tiny_num8 ! ! intent(in) + use consts_coms, only : euler_gam8 & ! intent(in) + , lnexp_min8 & ! intent(in) + , lnexp_max8 & ! intent(in) + , tiny_num8 & ! intent(in) + , almost_zero8 ! ! intent(in) implicit none !----- Arguments. ----------------------------------------------------------------------! real(kind=8), intent(in) :: x !----- Local variables. ----------------------------------------------------------------! - real(kind=8) :: sum - real(kind=8) :: term - real(kind=8) :: fact - real(kind=8) :: prev - real(kind=8) :: diter - integer :: iter + real(kind=8) :: usum + real(kind=8) :: uxk + real(kind=8) :: uxkm1 + real(kind=8) :: vsum + real(kind=8) :: vxkm1 + real(kind=8) :: vxk + real(kind=8) :: ei_series + real(kind=8) :: ei_asymptote + integer :: k !----- Local constants. ----------------------------------------------------------------! - real(kind=8), parameter :: powerlim = 1.5d+01 - real(kind=8), parameter :: converge = 1.0d-7 - integer , parameter :: maxiter = 100 + real(kind=8), parameter :: discard8 = 1.0d+36 + integer , parameter :: maxiter = 100 + !----- Polynomial coefficients. --------------------------------------------------------! + real(kind=8), dimension(4), parameter :: apoly = (/ 8.5733287401d+00, 1.8059015973d+01 & + , 8.6347608925d+00, 2.6777373430d-01 /) + real(kind=8), dimension(4), parameter :: bpoly = (/ 9.5733223454d+00, 2.5632956149d+01 & + , 2.1099653083d+01, 3.9584969228d+00 /) !---------------------------------------------------------------------------------------! @@ -582,63 +599,157 @@ real(kind=8) function eifun8(x) if (x == 0.d0) then !------------------------------------------------------------------------------------! ! Zero. This is a singularity and the user should never call it in this case. ! - ! That's sad, but we ought to quit this run and tell the user why the run crashed. ! - !------------------------------------------------------------------------------------! - call fatal_error('Exponential integral cannot be solved for x = 0.' & - ,'eifun8','numutils.f90') - elseif (x >= lnexp_max8) then - !----- Huge value, crash because this is iminent over-flow. -------------------------! - write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x - write(unit=*,fmt='(a,1x,es12.5)') 'Maximum acceptable X =',lnexp_max8 - call fatal_error('Exponential integral cannot be solved for x = 0.' & - ,'eifun8','numutils.f90') - elseif (abs(x) <= lnexp_min8) then - !----- Huge negative number, the result can be rounded to zero. ---------------------! + !------------------------------------------------------------------------------------! + stop 'Exponential integral cannot be solved for x = 0.' + !------------------------------------------------------------------------------------! + elseif (x <= lnexp_min8) then + !------------------------------------------------------------------------------------! + ! Huge negative value, the result can be set to zero. ! + !------------------------------------------------------------------------------------! eifun8 = 0.d0 - elseif (abs(x) <= tiny_num8) then - !----- The number is too close to zero, bypass iterative methods. -------------------! - eifun8 = euler_gam8 + log(abs(x)) - elseif (abs(x) <= powerlim) then - !------------------------------------------------------------------------------------! - ! Input x is small, so we use the power method. ! - !------------------------------------------------------------------------------------! - fact = 1.d0 - sum = 0.d0 - powerloop: do iter=1,maxiter - diter = dble(iter) - fact = fact * x / diter - term = fact / diter - sum = sum + term - !----- If the term is tiny, we have reached convergence, quit the loop. ----------! - if (abs(term) < converge * abs(sum)) exit powerloop - end do powerloop - eifun8 = euler_gam8 + log(abs(x)) + sum + !------------------------------------------------------------------------------------! + elseif (x <= -1.d0) then + !------------------------------------------------------------------------------------! + ! For negative values less than -1.0, we use the polynomial approximation ! + ! (Equation 5.1.56 of AS72), by taking that Ei(x) = - E1(-x). ! + !------------------------------------------------------------------------------------! + eifun8 = exp(x)/x & + * ( x * ( x * ( x * ( x - apoly(1) ) + apoly(2) ) - apoly(3) ) + apoly(4) ) & + / ( x * ( x * ( x * ( x - bpoly(1) ) + bpoly(2) ) - bpoly(3) ) + bpoly(4) ) + !------------------------------------------------------------------------------------! else !------------------------------------------------------------------------------------! - ! Input x is large, so we use the asymptotic approximation. ! - !------------------------------------------------------------------------------------! - sum = 0.d0 - term = 1.d0 - asymploop: do iter=1,maxiter - diter = dble(iter) - prev = term - term = term * diter / x - if (abs(term) < converge) then - !----- The term is tiny, we have reached convergence, quit the loop. ----------! - exit asymploop - elseif (abs(term) >= abs(prev)) then - !------------------------------------------------------------------------------! - ! Series is diverging, we are probably reaching round-off errors, we better ! - ! stop now. ! - !------------------------------------------------------------------------------! - sum = sum - prev - exit asymploop + ! Find both the series expansion and the asymptotic expansion, and pick the one ! + ! with the lowest absolute value. ! + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Series expansion: Equation 5.1.11 of AS72, by taking that Ei(x) = - E1(-x). ! + ! ! + ! Inf ! + ! Ei(x) = gamma + ln(x) + SUM u(x,k), ! + ! k=1 ! + ! ! + ! where u(x,k) = [ (-1)^k * (-x)^k / (k * k!) ] ! + ! ! + ! To efficiently compute the terms inside the summation, we use that: ! + ! ! + ! u(x,k) = x * (k -1) / k^2 * u(x,k-1), for k >= 2. ! + !------------------------------------------------------------------------------------! + uxk = x + usum = uxk + do_expansion: do k = 2, maxiter + !----- Update the current summation term. ----------------------------------------! + uxkm1 = uxk + uxk = x * dble( k - 1 ) / dble( k * k ) * uxkm1 + !----- Check for degenerate or very large estimate. ------------------------------! + if ( abs(uxk) > discard8 .or. abs(usum) > discard8) then + usum = sign(discard8,usum) + exit do_expansion + end if + !----- Check for convergence. ----------------------------------------------------! + if ( any(abs(uxk) <= [ almost_zero8 * abs(usum), tiny_num8] ) ) exit do_expansion + !----- Update summation. ---------------------------------------------------------! + usum = usum + uxk + !---------------------------------------------------------------------------------! + end do do_expansion + !----- Find the series solution. ----------------------------------------------------! + if ( abs(usum) == discard8) then + ei_series = sign(discard8,usum) + else + ei_series = euler_gam8 + log(abs(x)) + usum + end if + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Asymptote expansion: Equation 5.1.51 of AS72 by taking AS72's n=1 and ! + ! Ei(x) = -E1(-x)). ! + ! ! + ! Inf ! + ! Ei(x) = exp(x) / x * SUM v(x,k), ! + ! k=0 ! + ! ! + ! where v(x,k) = k! / x^k ! + ! ! + ! To efficiently compute the terms inside the summation, we use that: ! + ! ! + ! v(x,k) = k / x * v(x,n -1), for k >= 1. ! + !------------------------------------------------------------------------------------! + vxk = 1.d0 + vsum = vxk + do_asymptote: do k=1,maxiter + !----- Update the current summation term. ----------------------------------------! + vxkm1 = vxk + vxk = vxkm1 * dble(k) / x + !---------------------------------------------------------------------------------! + ! This method can become degenerate for low x or lead to exceedinly large ! + ! values, in these cases, halt evaluation. ! + !---------------------------------------------------------------------------------! + if ( abs(vxkm1) < abs(vxk) .or. abs(vsum) > discard8) then + vsum = sign(discard8,vsum) + exit do_asymptote + end if + !----- Check for convergence. ----------------------------------------------------! + if ( any(abs(vxk) <= [ almost_zero8 * abs(vsum), tiny_num8] ) ) exit do_asymptote + !----- Update summation. ---------------------------------------------------------! + vsum = vsum + vxk + !---------------------------------------------------------------------------------! + end do do_asymptote + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! If the solution became degenerate, skip value. ! + !------------------------------------------------------------------------------------! + if (abs(vsum) == discard8) then + ei_asymptote = sign(discard8,vsum) + else + ei_asymptote = exp(x) * vsum / x + end if + !------------------------------------------------------------------------------------! + + + + + + !------------------------------------------------------------------------------------! + ! Pick the lowest absolute value as long as the sign is reasonable. ! + !------------------------------------------------------------------------------------! + if (all(abs([ei_series,ei_asymptote]) == discard8)) then + !----- Huge value, crash because this is iminent over-flow. ----------------------! + write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x + stop 'Exponential integral cannot be solved for large absolute x.' + !---------------------------------------------------------------------------------! + elseif (x < 0.d0) then + !---------------------------------------------------------------------------------! + ! Exponential integral is negative when x is negative, however, for some ! + ! values between -15 < x < -14, the solutions become numerically unstable. Check ! + ! for the most reasonable estimate. ! + !---------------------------------------------------------------------------------! + if (ei_series > 0.d0 .and. ei_asymptote > 0.d0) then + write(unit=*,fmt='(a,1x,es12.5)') 'Attempted X = ',x + write(unit=*,fmt='(a,1x,es12.5)') 'Series expansion estimate = ',ei_series + write(unit=*,fmt='(a,1x,es12.5)') 'Asymptote expansion estimate = ',ei_asymptote + stop 'Exponential integral failed solving, another method might be needed.' + elseif (ei_series > 0.d0) then + eifun8 = ei_asymptote + elseif (ei_asymptote > 0.d0) then + eifun8 = ei_series + elseif (abs(ei_series) < abs(ei_asymptote)) then + eifun8 = ei_series else - sum = sum + term + eifun8 = ei_asymptote end if - end do asymploop - eifun8 = exp(x) * (1.d0 + sum) / x + !---------------------------------------------------------------------------------! + elseif (abs(ei_series) < abs(ei_asymptote)) then + eifun8 = ei_series + else + eifun8 = ei_asymptote + end if + !------------------------------------------------------------------------------------! end if + !---------------------------------------------------------------------------------------! return end function eifun8 @@ -651,8 +762,17 @@ end function eifun8 !==========================================================================================! !==========================================================================================! -! Heapsort is a robust and efficient sorting algorithm. For more details, check ! -! The Numerical Recipes Book (chapter 8). ! +! Heapsort is a robust and efficient sorting algorithm introduced by W64. The algorithm ! +! implemented here is built from the Wikipedia heapsort pseudocode, which is in turn based ! +! on K97. ! +! ! +! Williams, JWJ (1964). Algorithm 232 - Heapsort, Commun. ACM 7, 347-348. ! +! doi:10.1145/512274.512284 (W64). ! +! ! +! Knuth, D (1997). The Art of Computer Programming - volume 3: sort and searching. ! +! section 5.2.3. Sorting by selection (p. 144-155). ISBN 978-0-201-89685-5 (K97). ! +! ! +! Wikipedia link: https://en.wikipedia.org/wiki/Heapsort ! !------------------------------------------------------------------------------------------! subroutine heapsort(nx,xi,increase,xo) implicit none @@ -662,11 +782,12 @@ subroutine heapsort(nx,xi,increase,xo) logical , intent(in) :: increase ! Sort from small to large? real , dimension(nx), intent(out) :: xo ! Output vector !----- Local variables. ----------------------------------------------------------------! - integer :: i ! Counter - integer :: ir ! Index of selected data - integer :: j ! Index of selected data - integer :: l ! Index of selected data - real :: aux ! Placeholder + integer :: i ! Counter (inner loop) + integer :: ilwr ! Lower index (inner loop) + integer :: iupr ! Upper index (inner loop) + integer :: olwr ! Lower index (outer loop) + integer :: oupr ! Upper index (outer loop) + real :: aux ! Placeholder for element swapping !---------------------------------------------------------------------------------------! @@ -685,13 +806,13 @@ subroutine heapsort(nx,xi,increase,xo) !---------------------------------------------------------------------------------------! - ! The index l will be decremented from its initial value down to 1 during the ! - ! "hiring" (heap creation) phase. Once it reaches 1, the index ir will be decremented ! - ! from its initial value down to 1 during the "retirement-and-promotion" (heap ! - ! selection) phase. ! + ! Set initial guess of lower index ilwr to half the size of the vector and iupr to ! + ! the size of the vector. During the heap setting stage, ilwr will be reduced until it ! + ! becomes 0, and then we start decreasing iupr until it becomes 1, at which point the ! + ! vector becomes sorted. ! !---------------------------------------------------------------------------------------! - l = nx/2 + 1 - ir = nx + olwr = nx/2 + 1 + oupr = nx+1 !---------------------------------------------------------------------------------------! @@ -700,79 +821,74 @@ subroutine heapsort(nx,xi,increase,xo) !---------------------------------------------------------------------------------------! outer_loop: do !------------------------------------------------------------------------------------! - ! Check whether we are in the hiring phase or in the retirement-and-promotion ! + ! Exit outer loop if we reach the upper bound has already reached 1. ! + !------------------------------------------------------------------------------------! + if (oupr == 2) exit outer_loop + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! + ! Check whether we are in the heap setting phase or in the retirement-and-promotion ! ! phase. ! !------------------------------------------------------------------------------------! - if (l > 1) then - !---------------------------------------------------------------------------------! - ! Still in hiring phase. ! - !---------------------------------------------------------------------------------! - l = l - 1 - aux = xo(l) + if (olwr > 1) then + !----- Heap construction. --------------------------------------------------------! + olwr = olwr - 1 !---------------------------------------------------------------------------------! else !---------------------------------------------------------------------------------! - ! In the retirement-and-promotion phase. ! + ! Heap extraction. ! !---------------------------------------------------------------------------------! - !----- Clear a space at end of array. --------------------------------------------! - aux = xo(ir) - !----- Retire the top of the heap into it. ---------------------------------------! - xo(ir) = xo(1) - !----- Decrease the size of the corporation. -------------------------------------! - ir = ir -1 - !----- Check how we are doing with promotions. -----------------------------------! - if (ir == 1) then - !----- Done with the last promotion. The least competent worker of all! ------! - xo(1) = aux - !------------------------------------------------------------------------------! - - !------------------------------------------------------------------------------! - ! Time to leave the loop (and the sub-routine). ! - !------------------------------------------------------------------------------! - exit outer_loop - !------------------------------------------------------------------------------! - end if + !----- Shift upper side down one step. -------------------------------------------! + oupr = oupr -1 + !----- Swap indices. -------------------------------------------------------------! + aux = xo(oupr) + xo(oupr) = xo(1) + xo(1) = aux !---------------------------------------------------------------------------------! end if !------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! - ! Whether in hiring phase or promotion phase, we here set up to sift down element ! - ! aux to its proper level. ! + ! Sift down step. ! !------------------------------------------------------------------------------------! - i = l - j = l+1 + i = olwr inner_loop: do - if (j > ir) exit inner_loop + !----- Find the lower and right elements. ----------------------------------------! + ilwr = 2 * i + iupr = ilwr + 1 + !---------------------------------------------------------------------------------! + + !----- Make sure we do not exceed the heap size. ---------------------------------! + if (iupr > oupr) exit inner_loop + !---------------------------------------------------------------------------------! - !----- Compare to the better underling. ------------------------------------------! - if (j < ir) then - if(xo(j) < xo(j+1)) j = j + 1 + + !---------------------------------------------------------------------------------! + ! Test whether there is an upper element that is larger, and swap the order. ! + ! Make sure that the elements are bounded before testing vector elements, to ! + ! avoid segmentation violation. ! + !---------------------------------------------------------------------------------! + if (iupr < oupr) then + if (xo(ilwr) < xo(ilwr+1)) ilwr = ilwr + 1 end if !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Check whether to demote aux or not. ! + ! Test whether or not to swap elements. ! !---------------------------------------------------------------------------------! - if (aux < xo(j)) then - !----- Demote aux. ------------------------------------------------------------! - xo(i) = xo(j) - i = j - j = j + j - !------------------------------------------------------------------------------! + if (xo(i) < xo(ilwr)) then + aux = xo(i) + xo(i) = xo(ilwr) + xo(ilwr) = aux + i = ilwr else - !----- This is aux's level. Set j to terminate the sift-down. ----------------! - j = ir + 1 - !------------------------------------------------------------------------------! + exit inner_loop end if !---------------------------------------------------------------------------------! end do inner_loop !------------------------------------------------------------------------------------! - - !----- Put aux into its slot. -------------------------------------------------------! - xo(i) = aux - !------------------------------------------------------------------------------------! end do outer_loop !---------------------------------------------------------------------------------------! @@ -913,11 +1029,17 @@ end function fquant_mask !==========================================================================================! !==========================================================================================! ! Sub-routine that solves the quadratic equation ( a * x**2 + b * x + c = 0). ! -! This is an extension of the Numeric Recipes in Fortran 90 to account for the trivial ! -! cases and for checking when the discriminant is negative. ! +! We test whether or not this is a trivial case that does not require solving the full ! +! equation. For the full equation, we use the approach by H02 to avoid floating point ! +! issues when solving roots. We further check whether or not the discriminant is negative. ! +! ! ! The subroutine also requires a "undef" flag to be passed, which will flag cases ! ! in which one or both solutions are not valid. This is an argument so the solver can be ! ! used when either the largest or the smallest root is sought. ! +! ! +! Higham, N. J., 2002: Accuracy and Stability of Numerical Algorithms. 2nd ed., Society ! +! for Industrial and Applied Mathematics, Philadelphia, PA, United States, ! +! doi:10.1137/1.9780898718027 (H02). ! !------------------------------------------------------------------------------------------! subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) use consts_coms, only : tiny_num @@ -931,7 +1053,6 @@ subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) real(kind=4), intent(out) :: root2 !----- Internal variables. -------------------------------------------------------------! real(kind=4) :: discr - real(kind=4) :: qfact logical :: a_offzero logical :: b_offzero logical :: c_offzero @@ -966,13 +1087,13 @@ subroutine solve_quadratic(aquad,bquad,cquad,undef,root1,root2) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Find the q factor as in the numerical recipes, which allows for a more ! - ! robust solution. This is safe whenever b or c are non-zero, as q cannot be ! - ! zero in these cases. + ! Follow H02's approach to find the largest root (absolute value) from the ! + ! traditional quadratic equation, then derive the second root from the first one. ! + ! This is safe whenever b or c are non-zero. ! + !---------------------------------------------------------------------------------! + root1 = - (bquad + sign(sqrt(discr),bquad)) / ( 2. * aquad ) + root2 = cquad / ( aquad * root1 ) !---------------------------------------------------------------------------------! - qfact = - 0.5 * (bquad + sign(sqrt(discr),bquad)) - root1 = qfact / aquad - root2 = cquad / qfact else !----- Negative discriminant, return invalid roots. ------------------------------! root1 = undef @@ -1024,11 +1145,17 @@ end subroutine solve_quadratic !==========================================================================================! !==========================================================================================! ! Sub-routine that solves the quadratic equation ( a * x**2 + b * x + c = 0). ! -! This is an extension of the Numeric Recipes in Fortran 90 to account for the trivial ! -! cases and for checking when the discriminant is negative. ! +! We test whether or not this is a trivial case that does not require solving the full ! +! equation. For the full equation, we use the approach by H02 to avoid floating point ! +! issues when solving roots. We further check whether or not the discriminant is negative. ! +! ! ! The subroutine also requires a "undef" flag to be passed, which will flag cases ! ! in which one or both solutions are not valid. This is an argument so the solver can be ! ! used when either the largest or the smallest root is sought. ! +! ! +! Higham, N. J., 2002: Accuracy and Stability of Numerical Algorithms. 2nd ed., Society ! +! for Industrial and Applied Mathematics, Philadelphia, PA, United States, ! +! doi:10.1137/1.9780898718027 (H02). ! !------------------------------------------------------------------------------------------! subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) use consts_coms, only : tiny_num8 @@ -1042,7 +1169,6 @@ subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) real(kind=8), intent(out) :: root2 !----- Internal variables. -------------------------------------------------------------! real(kind=8) :: discr - real(kind=8) :: qfact logical :: a_offzero logical :: b_offzero logical :: c_offzero @@ -1077,13 +1203,13 @@ subroutine solve_quadratic8(aquad,bquad,cquad,undef,root1,root2) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! - ! Find the q factor as in the numerical recipes, which allows for a more ! - ! robust solution. This is safe whenever b or c are non-zero, as q cannot be ! - ! zero in these cases. + ! Follow H02's approach to find the largest root (absolute value) from the ! + ! traditional quadratic equation, then derive the second root from the first one. ! + ! This is safe whenever b or c are non-zero. ! + !---------------------------------------------------------------------------------! + root1 = - (bquad + sign(sqrt(discr),bquad)) / ( 2.d0 * aquad ) + root2 = cquad / ( aquad * root1 ) !---------------------------------------------------------------------------------! - qfact = - 5.d-1 * (bquad + sign(sqrt(discr),bquad)) - root1 = qfact / aquad - root2 = cquad / qfact else !----- Negative discriminant, return invalid roots. ------------------------------! root1 = undef diff --git a/ED/src/utils/random_utils.F90 b/ED/src/utils/random_utils.F90 index 77b1044b7..13aaf4089 100644 --- a/ED/src/utils/random_utils.F90 +++ b/ED/src/utils/random_utils.F90 @@ -31,7 +31,7 @@ subroutine init_random_seed() ! case you create a new name, please be creative so it doesn't conflict with other ! ! user's choice. ! !------------------------------------------------------------------------------------! -#if defined(ODYSSEY) || defined(SUNHPC) || defined(PC_INTEL) +#if defined(ODYSSEY) || defined(SUNHPC) || defined(PC_INTEL) || defined(DOCKER_INTEL) use ifport, only : getpid #endif !------------------------------------------------------------------------------------! diff --git a/ED/src/utils/rsys.F90 b/ED/src/utils/rsys.F90 index ca3ba998f..ff3b45567 100644 --- a/ED/src/utils/rsys.F90 +++ b/ED/src/utils/rsys.F90 @@ -117,7 +117,7 @@ logical function isnan_real(x) !---------------------------------------------------------------------------------------! #if defined(PGI) - isnan_real = x == x + isnan_real = x /= x #else isnan_real = isnan(x) #endif @@ -131,6 +131,31 @@ end function isnan_real +!==========================================================================================! +!==========================================================================================! +! Function that checks whether a number is NaN. This works with PGI, Intel, and GNU. ! +!------------------------------------------------------------------------------------------! +logical function isnan_dble(x) + implicit none + !------ Arguments. ---------------------------------------------------------------------! + real(kind=8), intent(in) :: x + !---------------------------------------------------------------------------------------! + +#if defined(PGI) + isnan_dble = x /= x +#else + isnan_dble = isnan(x) +#endif + + return +end function isnan_dble +!==========================================================================================! +!==========================================================================================! + + + + + !==========================================================================================! !==========================================================================================! ! Function that waits for a few seconds before moving on. This may be useful for OMP ! diff --git a/ED/src/utils/therm_lib.f90 b/ED/src/utils/therm_lib.f90 index b3d23b991..a42cb0849 100644 --- a/ED/src/utils/therm_lib.f90 +++ b/ED/src/utils/therm_lib.f90 @@ -115,6 +115,17 @@ module therm_lib !=======================================================================================! + + + !=======================================================================================! + !=======================================================================================! + ! Weighting factor for atmospheric ThetaV (as opposed to canopy air space ThetaV). ! + !---------------------------------------------------------------------------------------! + real(kind=4), parameter :: fthva_rp = 0.5 + !=======================================================================================! + !=======================================================================================! + + contains @@ -2497,22 +2508,27 @@ real(kind=4) function reducedpress(pres,thetaref,shvref,zref,thetacan,shvcan,zca implicit none !----- Arguments --------------------------------------------------------------------! real(kind=4), intent(in) :: pres ! Pressure [ Pa] - real(kind=4), intent(in) :: thetaref ! Potential temperature [ K] - real(kind=4), intent(in) :: shvref ! Vapour specific mass [ kg/kg] + real(kind=4), intent(in) :: thetaref ! Ref. Potential temperature [ K] + real(kind=4), intent(in) :: shvref ! Ref. Vapour specific mass [ kg/kg] real(kind=4), intent(in) :: zref ! Height at reference level [ m] - real(kind=4), intent(in) :: thetacan ! Potential temperature [ K] - real(kind=4), intent(in) :: shvcan ! Vapour specific mass [ kg/kg] + real(kind=4), intent(in) :: thetacan ! CAS Potential temperature [ K] + real(kind=4), intent(in) :: shvcan ! CAS Vapour specific mass [ kg/kg] real(kind=4), intent(in) :: zcan ! Height at canopy level [ m] !------Local variables. -------------------------------------------------------------! real(kind=4) :: pinc ! Pressure increment [ Pa^R/cp] + real(kind=4) :: thvref ! Reference virtual pot. temperature [ K] + real(kind=4) :: thvcan ! CAS virtual pot. temperature [ K] real(kind=4) :: thvbar ! Average virtual pot. temperature [ K] !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! ! First we compute the average virtual potential temperature between the canopy ! - ! top and the reference level. ! + ! top and the reference level. Because of the equation below, we average the ! + ! inverse of the potential temperature. ! !------------------------------------------------------------------------------------! - thvbar = 0.5 * (thetaref * (1. + epim1 * shvref) + thetacan * (1. + epim1 * shvcan)) + thvref = thetaref * (1.0 + epim1 * shvref) + thvcan = thetacan * (1.0 + epim1 * shvcan) + thvbar = thvref * thvcan / ( ( 1.0 - fthva_rp ) * thvref + fthva_rp * thvcan ) !------------------------------------------------------------------------------------! diff --git a/ED/src/utils/therm_lib8.f90 b/ED/src/utils/therm_lib8.f90 index 5af2e6062..8a9e2896e 100644 --- a/ED/src/utils/therm_lib8.f90 +++ b/ED/src/utils/therm_lib8.f90 @@ -19,7 +19,8 @@ module therm_lib8 , level4 => level & ! intent(in) , vapour_on4 => vapour_on & ! intent(in) , cloud_on4 => cloud_on & ! intent(in) - , bulk_on4 => bulk_on ! ! intent(in) + , bulk_on4 => bulk_on & ! intent(in) + , fthva_rp4 => fthva_rp ! ! intent(in) !---------------------------------------------------------------------------------------! ! Relative tolerance for iterative methods. The smaller the value, the more ! @@ -126,6 +127,17 @@ module therm_lib8 !=======================================================================================! + + + !=======================================================================================! + !=======================================================================================! + ! Weighting factor for atmospheric ThetaV (as opposed to canopy air space ThetaV). ! + !---------------------------------------------------------------------------------------! + real(kind=4), parameter :: fthva_rp8 = dble(fthva_rp4) + !=======================================================================================! + !=======================================================================================! + + contains @@ -2510,20 +2522,25 @@ real(kind=8) function reducedpress8(pres,thetaref,shvref,zref,thetacan,shvcan,zc real(kind=8), intent(in) :: thetaref ! Potential temperature [ K] real(kind=8), intent(in) :: shvref ! Vapour specific mass [ kg/kg] real(kind=8), intent(in) :: zref ! Height at reference level [ m] - real(kind=8), intent(in) :: thetacan ! Potential temperature [ K] - real(kind=8), intent(in) :: shvcan ! Vapour specific mass [ kg/kg] + real(kind=8), intent(in) :: thetacan ! CAS Potential temperature [ K] + real(kind=8), intent(in) :: shvcan ! CAS Vapour specific mass [ kg/kg] real(kind=8), intent(in) :: zcan ! Height at canopy level [ m] !------Local variables. -------------------------------------------------------------! real(kind=8) :: pinc ! Pressure increment [ Pa^R/cp] + real(kind=8) :: thvref ! Reference virtual pot. temperature [ K] + real(kind=8) :: thvcan ! CAS virtual pot. temperature [ K] real(kind=8) :: thvbar ! Average virtual pot. temperature [ K] !------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! ! First we compute the average virtual potential temperature between the canopy ! - ! top and the reference level. ! + ! top and the reference level. Because of the equation below, we average the ! + ! inverse of the potential temperature. ! !------------------------------------------------------------------------------------! - thvbar = 5.d-1 * ( thetaref * (1.d0 + epim18 * shvref) & - + thetacan * (1.d0 + epim18 * shvcan) ) + thvref = thetaref * (1.d0 + epim18 * shvref) + thvcan = thetacan * (1.d0 + epim18 * shvcan) + thvbar = thvref * thvcan / ( ( 1.d0 - fthva_rp8 ) * thvref + fthva_rp8 * thvcan ) !------------------------------------------------------------------------------------! diff --git a/ED/src/utils/update_derived_utils.f90 b/ED/src/utils/update_derived_utils.f90 index 7ab3c2752..d465fdc88 100644 --- a/ED/src/utils/update_derived_utils.f90 +++ b/ED/src/utils/update_derived_utils.f90 @@ -65,7 +65,8 @@ subroutine update_cohort_derived_props(cpatch,ico,lsl,new_year,llspan_toc , size2xb & ! function , ed_balive & ! function , ed_biomass & ! function - , area_indices ! ! subroutine + , area_indices & ! sub-routine + , distrib_root ! ! sub-routine use physiology_coms, only : trait_plasticity_scheme ! ! intent(in) use consts_coms , only : pio4 ! ! intent(in) use ed_misc_coms , only : igrass & ! intent(in) @@ -193,6 +194,13 @@ subroutine update_cohort_derived_props(cpatch,ico,lsl,new_year,llspan_toc !----- Update rooting depth ---------------------------------------------------------! cpatch%krdepth(ico) = size2krdepth(cpatch%hite(ico),cpatch%dbh(ico),ipft,lsl) !if new root depth is smaller keep the old one + !------------------------------------------------------------------------------------! + + + !----- Update the vertical distribution of roots. -----------------------------------! + call distrib_root(cpatch%krdepth(ico),ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------------! + return end subroutine update_cohort_derived_props !=======================================================================================! @@ -390,27 +398,45 @@ subroutine update_cohort_plastic_trait(cpatch,ico,is_instant cpatch%sla (ico) = new_sla cpatch%psi_open (ico) = cpatch%psi_open (ico) * sla_scaler cpatch%psi_closed(ico) = cpatch%psi_closed(ico) * sla_scaler + !------------------------------------------------------------------------------------! - ! Since SLA is changed, we might need to adjust leaf biomass if leaf area based - ! allometry is used + + + !------------------------------------------------------------------------------------! + ! 6. SLA may have changed, therefore we must adjust leaf biomass if we are using ! + ! the leaf-area based allometry. ! + !------------------------------------------------------------------------------------! select case (iallom) - case (4) - bl_max = size2bl(cpatch%dbh(ico),cpatch%hite(ico),cpatch%sla(ico),cpatch%pft(ico)) + case (3,4,5) + !---- Maximum leaf biomass. ------------------------------------------------------! + bl_max = size2bl(cpatch%dbh(ico),cpatch%hite(ico),cpatch%sla(ico),cpatch%pft(ico)) + !---------------------------------------------------------------------------------! - if (cpatch%bleaf(ico) > bl_max) then - ! if the new bl_max is smaller than current bleaf, we need to dump - ! the extra carbon into bstorage and change phenology_status - cpatch%bstorage(ico) = cpatch%bstorage(ico) & - + (cpatch%bleaf(ico) - bl_max) - ! Water content will be updated later in structural_growth + + !---------------------------------------------------------------------------------! + ! Check that plasticity doesn't violate allometry. ! + !---------------------------------------------------------------------------------! + if (cpatch%bleaf(ico) > bl_max) then + !------------------------------------------------------------------------------! + ! If the new bl_max is smaller than current bleaf, we need to dump the ! + ! extra carbon into bstorage and change phenology_status. ! + !------------------------------------------------------------------------------! + cpatch%bstorage(ico) = cpatch%bstorage(ico) + (cpatch%bleaf(ico) - bl_max) + + !----- Water content will be updated later in structural_growth. --------------! cpatch%bleaf(ico) = bl_max + !------------------------------------------------------------------------------! - ! we also update balive since bleaf changed + !----- We also update balive since bleaf changed. -----------------------------! cpatch%balive(ico) = ed_balive(cpatch,ico) + !------------------------------------------------------------------------------! + !----- Leaves are at maximum elongation, update phenology flag accordingly. ---! cpatch%phenology_status(ico) = 0 - endif + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! end select !------------------------------------------------------------------------------------! @@ -794,7 +820,7 @@ end subroutine update_patch_derived_props !=======================================================================================! ! This subroutine will take care of some diagnostic thermodynamic properties. ! !---------------------------------------------------------------------------------------! - subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) + subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,lsl,ntext_soil) use ed_state_vars, only : sitetype ! ! structure use therm_lib , only : idealdenssh & ! function @@ -815,6 +841,7 @@ subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) integer , intent(in) :: ipaz integer , intent(in) :: mzg integer , intent(in) :: mzs + integer , intent(in) :: lsl integer , dimension(mzg), intent(in) :: ntext_soil !----- Local variables. -------------------------------------------------------------! integer :: ipa @@ -841,7 +868,7 @@ subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) !----- Update soil temperature and liquid water fraction. ------------------------! - do k = 1, mzg + do k = lsl, mzg nsoil = ntext_soil(k) soilhcap = soil(nsoil)%slcpd call uextcm2tl(csite%soil_energy(k,ipa),csite%soil_water(k,ipa)*wdns,soilhcap & @@ -890,7 +917,7 @@ end subroutine update_patch_thermo_props ! This subroutine will update the fast mean properties, similarly to the routine ! ! above. ! !---------------------------------------------------------------------------------------! - subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) + subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,lsl,ntext_soil) use ed_state_vars, only : sitetype ! ! structure use therm_lib , only : idealdenssh & ! function @@ -911,6 +938,7 @@ subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) integer , intent(in) :: ipaa integer , intent(in) :: ipaz integer , intent(in) :: mzg + integer , intent(in) :: lsl integer , dimension(mzg), intent(in) :: ntext_soil !----- Local variables. -------------------------------------------------------------! integer :: ipa @@ -937,7 +965,7 @@ subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) !----- Update soil temperature and liquid water fraction. ------------------------! - do k = 1, mzg + do k = lsl, mzg nsoil = ntext_soil(k) soilhcap = soil(nsoil)%slcpd call uextcm2tl( csite%fmean_soil_energy(k,ipa) & diff --git a/EDR/src/driver/ed_1st.F90 b/EDR/src/driver/ed_1st.F90 index 571477f54..9ac94dcaa 100644 --- a/EDR/src/driver/ed_1st.F90 +++ b/EDR/src/driver/ed_1st.F90 @@ -22,13 +22,12 @@ subroutine ed_1st_master (ipara, nnodestotal,nslaves, headnode_num, max_threads, use ed_misc_coms , only : runtype ! ! intent(inout) use ed_state_vars, only : allocate_edglobals & ! subroutine , filltab_alltypes ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: ipara ! 0 if sequential run; 1 if parallel run integer , intent(in) :: nnodestotal ! total number of nodes on any run @@ -170,10 +169,10 @@ end subroutine ed_1st_master !------------------------------------------------------------------------------------------! subroutine ed_1st_node() use ed_mem_alloc, only : ed_memory_allocation ! ! subroutine - implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi +#endif + implicit none !----- Local variable (MPI only). ------------------------------------------------------! integer :: ierr #endif diff --git a/EDR/src/driver/ed_driver.F90 b/EDR/src/driver/ed_driver.F90 index b9fc14731..58a8759a5 100644 --- a/EDR/src/driver/ed_driver.F90 +++ b/EDR/src/driver/ed_driver.F90 @@ -30,11 +30,10 @@ subroutine ed_driver() use detailed_coms , only : idetailed & ! intent(in) , patch_keep ! ! intent(in) use phenology_aux , only : first_phenology ! ! subroutine - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' ! MPI commons + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! character(len=12) :: c0 character(len=12) :: c1 diff --git a/EDR/src/driver/ed_model.F90 b/EDR/src/driver/ed_model.F90 index fe00a6003..aa23d598e 100644 --- a/EDR/src/driver/ed_model.F90 +++ b/EDR/src/driver/ed_model.F90 @@ -85,11 +85,10 @@ subroutine ed_model() , zero_ed_fmean_vars & ! sub-routine , integrate_ed_fmean_met_vars & ! sub-routine , zero_ed_yearly_vars ! ! sub-routine - implicit none - !----- Common blocks. ------------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! character(len=28) :: fmthead character(len=32) :: fmtcntr diff --git a/EDR/src/driver/edmain.F90 b/EDR/src/driver/edmain.F90 index f5b8c1f44..33614086d 100644 --- a/EDR/src/driver/edmain.F90 +++ b/EDR/src/driver/edmain.F90 @@ -14,6 +14,9 @@ !------------------------------------------------------------------------------------------! program main !$ use omp_lib +#if defined(RAMS_MPI) + use mpi +#endif implicit none !---------------------------------------------------------------------------------------! @@ -46,10 +49,6 @@ program main integer, dimension(64) :: thread_use integer, dimension(64) :: cpu_use integer, external :: findmycpu - !------ MPI interface. -----------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-TEST b/EDTS/Templates/ED2IN-TEST index 64f489146..80a203cd0 100644 --- a/EDTS/Templates/ED2IN-TEST +++ b/EDTS/Templates/ED2IN-TEST @@ -887,13 +887,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 3 !---------------------------------------------------------------------------------------! @@ -964,10 +970,25 @@ $ED_NL ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! @@ -1540,6 +1561,7 @@ $ED_NL ! The following variables are used when IANTH_DISTURB is 1 or 2. ! ! ! ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! diff --git a/EDTS/Templates/ED2IN-tonzi b/EDTS/Templates/ED2IN-tonzi index 06ed7ff22..8fa702d03 100644 --- a/EDTS/Templates/ED2IN-tonzi +++ b/EDTS/Templates/ED2IN-tonzi @@ -788,27 +788,36 @@ $ED_NL !---------------------------------------------------------------------------------------! - ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs. Temperate PFTs ! - ! will use the new root allometry and the maximum crown area if IALLOM is set ! - ! to 1 or 2). ! - ! 0. Original ED-2.1 ! - ! 1. a. The coefficients for structural biomass are set so the total AGB ! - ! is similar to Baker et al. (2004), equation 2. Balive is the ! - ! default ED-2.1; ! + ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs). Temperate PFTs ! + ! will use the new root allometry and the maximum crown area unless IALLOM is ! + ! set to 0). ! + ! 0. (Legacy) Original ED-1.0, included for back compatibility. ! + ! 1. (Legacy) ! + ! a. The coefficients for structural biomass are set so the total AGB ! + ! is similar to Baker et al. (2004, Glob. Change Biol.), equation 2. ! ! b. Experimental root depth that makes canopy trees to have root depths ! ! of 5m and grasses/seedlings at 0.5 to have root depth of 0.5 m. ! - ! c. Crown area defined as in Poorter et al. (2006), imposing maximum ! - ! crown area ! - ! 2. Similar to 1, but with a few extra changes. ! + ! c. Crown area defined as in Poorter et al. (2006, Ecology), imposing ! + ! maximum crown area. ! + ! 2. (ED-2.2 default) Similar to 1, but with a few extra changes. ! ! a. Height -> DBH allometry as in Poorter et al. (2006) ! ! b. Balive is retuned, using a few leaf biomass allometric equations for ! - ! a few genuses in Costa Rica. References: ! - ! Cole and Ewel (2006), and Calvo Alvarado et al. (2008). ! - ! 3. Similar to 2, except that tropical leaf biomass is estimated from ! - ! Lescure et al. (1983), and PFT differences on bleaf are based on SLA ! - ! instead of wood density. Also, the leaf allometry is split into ! - ! small classes ("saplings") and large classes ("trees"), like in Cole ! - ! and Ewel (2006). ! + ! a few genera in Costa Rica. References: ! + ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! + ! (2008, Tree Physiol.). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 2 !---------------------------------------------------------------------------------------! @@ -848,37 +857,52 @@ $ED_NL ! IPHEN_SCHEME -- It controls the phenology scheme. Even within each scheme, the ! ! actual phenology will be different depending on the PFT. ! ! ! - ! -1: grasses - evergreen; ! + ! -1: (ED-2.2 default for evergreen tropical). ! + ! grasses - evergreen; ! ! tropical - evergreen; ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous (Botta et al.); ! ! ! - ! 0: grasses - drought-deciduous (old scheme); ! + ! 0: (Deprecated). ! + ! grasses - drought-deciduous (old scheme); ! ! tropical - drought-deciduous (old scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 1: prescribed phenology ! + ! 1: (ED-2.2 default for prescribed phenology; deprecated for tropical PFTs). ! + ! phenology is prescribed for cold-deciduous broadleaf trees. ! ! ! - ! 2: grasses - drought-deciduous (new scheme); ! + ! 2: (ED-2.2 default). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (new scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 3: grasses - drought-deciduous (new scheme); ! + ! 3: (Beta). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 4: grasses - drought-deciduous (plant hydraulics); ! - ! tropical - drought-deciduous (plant hydraulics; ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! @@ -1324,10 +1348,67 @@ $ED_NL !---------------------------------------------------------------------------------------! ! IANTH_DISTURB -- This flag controls whether to include anthropogenic disturbances ! ! such as land clearing, abandonment, and logging. ! - ! 0. no anthropogenic disturbance. ! - ! 1. use anthropogenic disturbance dataset. ! - !---------------------------------------------------------------------------------------! - NL%IANTH_DISTURB = 0 + ! 0. No anthropogenic disturbance. ! + ! 1. Use anthropogenic disturbance dataset (ED-2.2 default when ! + ! anthropogenic disturbance is sought). ! + ! 2. Site-specific forest plantation or selective logging cycle. ! + ! (Longo et al., in prep.) (Beta) ! + ! ! + ! The following variables are used only when IANTH_DISTURB is 2. ! + ! ! + ! SL_SCALE -- This flag assumes whether the simulation scale is local or ! + ! landscape. This controls the recurrence of logging. ! + ! 0. Local. The simulation represents one logging unit. Apply ! + ! logging only once every SL_NYRS ! + ! 1. Landscape. The simulation represents a landscape. Logging ! + ! occurs every year but it is restricted to patches with age ! + ! greater than or equal to SL_NYRS ! + ! SL_YR_FIRST -- The first year to apply logging. In case IANTH_DISTURB is 2 it ! + ! must be a simulation year (i.e. between IYEARA and IYEARZ). ! + ! SL_NYRS -- This variable defines the logging cycle, in years (see variable ! + ! SL_SCALE above) ! + ! SL_PFT -- PFTs that can be harvested. ! + ! SL_PROB_HARVEST -- Logging intensity (one value for each PFT provided in SL_PFT). ! + ! Values should be between 0.0 and 1.0, with 0 meaning no ! + ! removal, and 1 removal of all trees needed to meet demands. ! + ! SL_MINDBH_HARVEST -- Minimum DBH for logging (one value for each PFT provided in ! + ! SL_PFT). ! + ! SL_BIOMASS_HARVEST -- Target biomass to be harvested in each cycle, in kgC/m2. If ! + ! zero, then all trees that meet the minimum DBH and minimum ! + ! patch age will be logged. In case you don't want logging to ! + ! occur, don't set this value to zero! Instead, set IANTH_DISTURB ! + ! to zero. ! + ! ! + ! The following variables are used when IANTH_DISTURB is 1 or 2. ! + ! ! + ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! + ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! + ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! + ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! + ! ! + ! Cropland variables, used when IANTH_DISTURB is 1 or 2. ! + ! ! + ! CL_FSEEDS_HARVEST -- fraction of seeds that is harvested. ! + ! CL_FSTORAGE_HARVEST -- fraction of non-structural carbon that is harvested. ! + ! CL_FLEAF_HARVEST -- fraction of leaves that is harvested in croplands. ! + !---------------------------------------------------------------------------------------! + NL%IANTH_DISTURB = 0 + NL%SL_SCALE = 1 + NL%SL_YR_FIRST = 1992 + NL%SL_NYRS = 50 + NL%SL_PFT = 2,3,4 + NL%SL_PROB_HARVEST = 1.0,1.0,1.0 + NL%SL_MINDBH_HARVEST = 50.,50.,50. + NL%SL_BIOMASS_HARVEST = 0 + NL%SL_SKID_REL_AREA = 1 + NL%SL_SKID_DBH_THRESH = 30. + NL%SL_SKID_S_GTHARV = 1 + NL%SL_SKID_S_LTHARV = 0.6 + NL%SL_FELLING_S_LTHARV = 0.35 + NL%CL_FSEEDS_HARVEST = 0.75 + NL%CL_FSTORAGE_HARVEST = 0.00 + NL%CL_FLEAF_HARVEST = 0.00 !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-tonzi.harvest b/EDTS/Templates/ED2IN-tonzi.harvest index fed665436..1f3aca18a 100644 --- a/EDTS/Templates/ED2IN-tonzi.harvest +++ b/EDTS/Templates/ED2IN-tonzi.harvest @@ -788,27 +788,36 @@ $ED_NL !---------------------------------------------------------------------------------------! - ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs. Temperate PFTs ! - ! will use the new root allometry and the maximum crown area if IALLOM is set ! - ! to 1 or 2). ! - ! 0. Original ED-2.1 ! - ! 1. a. The coefficients for structural biomass are set so the total AGB ! - ! is similar to Baker et al. (2004), equation 2. Balive is the ! - ! default ED-2.1; ! + ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs). Temperate PFTs ! + ! will use the new root allometry and the maximum crown area unless IALLOM is ! + ! set to 0). ! + ! 0. (Legacy) Original ED-1.0, included for back compatibility. ! + ! 1. (Legacy) ! + ! a. The coefficients for structural biomass are set so the total AGB ! + ! is similar to Baker et al. (2004, Glob. Change Biol.), equation 2. ! ! b. Experimental root depth that makes canopy trees to have root depths ! ! of 5m and grasses/seedlings at 0.5 to have root depth of 0.5 m. ! - ! c. Crown area defined as in Poorter et al. (2006), imposing maximum ! - ! crown area ! - ! 2. Similar to 1, but with a few extra changes. ! + ! c. Crown area defined as in Poorter et al. (2006, Ecology), imposing ! + ! maximum crown area. ! + ! 2. (ED-2.2 default) Similar to 1, but with a few extra changes. ! ! a. Height -> DBH allometry as in Poorter et al. (2006) ! ! b. Balive is retuned, using a few leaf biomass allometric equations for ! - ! a few genuses in Costa Rica. References: ! - ! Cole and Ewel (2006), and Calvo Alvarado et al. (2008). ! - ! 3. Similar to 2, except that tropical leaf biomass is estimated from ! - ! Lescure et al. (1983), and PFT differences on bleaf are based on SLA ! - ! instead of wood density. Also, the leaf allometry is split into ! - ! small classes ("saplings") and large classes ("trees"), like in Cole ! - ! and Ewel (2006). ! + ! a few genera in Costa Rica. References: ! + ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! + ! (2008, Tree Physiol.). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 2 !---------------------------------------------------------------------------------------! @@ -848,37 +857,52 @@ $ED_NL ! IPHEN_SCHEME -- It controls the phenology scheme. Even within each scheme, the ! ! actual phenology will be different depending on the PFT. ! ! ! - ! -1: grasses - evergreen; ! + ! -1: (ED-2.2 default for evergreen tropical). ! + ! grasses - evergreen; ! ! tropical - evergreen; ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous (Botta et al.); ! ! ! - ! 0: grasses - drought-deciduous (old scheme); ! + ! 0: (Deprecated). ! + ! grasses - drought-deciduous (old scheme); ! ! tropical - drought-deciduous (old scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 1: prescribed phenology ! + ! 1: (ED-2.2 default for prescribed phenology; deprecated for tropical PFTs). ! + ! phenology is prescribed for cold-deciduous broadleaf trees. ! ! ! - ! 2: grasses - drought-deciduous (new scheme); ! + ! 2: (ED-2.2 default). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (new scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 3: grasses - drought-deciduous (new scheme); ! + ! 3: (Beta). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 4: grasses - drought-deciduous (plant hydraulics); ! - ! tropical - drought-deciduous (plant hydraulics; ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! @@ -1324,10 +1348,67 @@ $ED_NL !---------------------------------------------------------------------------------------! ! IANTH_DISTURB -- This flag controls whether to include anthropogenic disturbances ! ! such as land clearing, abandonment, and logging. ! - ! 0. no anthropogenic disturbance. ! - ! 1. use anthropogenic disturbance dataset. ! - !---------------------------------------------------------------------------------------! - NL%IANTH_DISTURB = 0 + ! 0. No anthropogenic disturbance. ! + ! 1. Use anthropogenic disturbance dataset (ED-2.2 default when ! + ! anthropogenic disturbance is sought). ! + ! 2. Site-specific forest plantation or selective logging cycle. ! + ! (Longo et al., in prep.) (Beta) ! + ! ! + ! The following variables are used only when IANTH_DISTURB is 2. ! + ! ! + ! SL_SCALE -- This flag assumes whether the simulation scale is local or ! + ! landscape. This controls the recurrence of logging. ! + ! 0. Local. The simulation represents one logging unit. Apply ! + ! logging only once every SL_NYRS ! + ! 1. Landscape. The simulation represents a landscape. Logging ! + ! occurs every year but it is restricted to patches with age ! + ! greater than or equal to SL_NYRS ! + ! SL_YR_FIRST -- The first year to apply logging. In case IANTH_DISTURB is 2 it ! + ! must be a simulation year (i.e. between IYEARA and IYEARZ). ! + ! SL_NYRS -- This variable defines the logging cycle, in years (see variable ! + ! SL_SCALE above) ! + ! SL_PFT -- PFTs that can be harvested. ! + ! SL_PROB_HARVEST -- Logging intensity (one value for each PFT provided in SL_PFT). ! + ! Values should be between 0.0 and 1.0, with 0 meaning no ! + ! removal, and 1 removal of all trees needed to meet demands. ! + ! SL_MINDBH_HARVEST -- Minimum DBH for logging (one value for each PFT provided in ! + ! SL_PFT). ! + ! SL_BIOMASS_HARVEST -- Target biomass to be harvested in each cycle, in kgC/m2. If ! + ! zero, then all trees that meet the minimum DBH and minimum ! + ! patch age will be logged. In case you don't want logging to ! + ! occur, don't set this value to zero! Instead, set IANTH_DISTURB ! + ! to zero. ! + ! ! + ! The following variables are used when IANTH_DISTURB is 1 or 2. ! + ! ! + ! SL_SKID_REL_AREA -- area damaged by skid trails (relative to felled area). ! + ! SL_SKID_DBH_THRESH -- DBH threshold for damage caused in skid trails. ! + ! SL_SKID_S_GTHARV -- survivorship of trees with DBH > MINDBH in skid trails. ! + ! SL_SKID_S_LTHARV -- survivorship of trees with DBH < MINDBH in skid trails. ! + ! SL_FELLING_S_LTHARV -- survivorship of trees with DBH < MINDBH in felling gaps. ! + ! ! + ! Cropland variables, used when IANTH_DISTURB is 1 or 2. ! + ! ! + ! CL_FSEEDS_HARVEST -- fraction of seeds that is harvested. ! + ! CL_FSTORAGE_HARVEST -- fraction of non-structural carbon that is harvested. ! + ! CL_FLEAF_HARVEST -- fraction of leaves that is harvested in croplands. ! + !---------------------------------------------------------------------------------------! + NL%IANTH_DISTURB = 0 + NL%SL_SCALE = 1 + NL%SL_YR_FIRST = 1992 + NL%SL_NYRS = 50 + NL%SL_PFT = 2,3,4 + NL%SL_PROB_HARVEST = 1.0,1.0,1.0 + NL%SL_MINDBH_HARVEST = 50.,50.,50. + NL%SL_BIOMASS_HARVEST = 0 + NL%SL_SKID_REL_AREA = 1 + NL%SL_SKID_DBH_THRESH = 30. + NL%SL_SKID_S_GTHARV = 1 + NL%SL_SKID_S_LTHARV = 0.6 + NL%SL_FELLING_S_LTHARV = 0.35 + NL%CL_FSEEDS_HARVEST = 0.75 + NL%CL_FSTORAGE_HARVEST = 0.00 + NL%CL_FLEAF_HARVEST = 0.00 !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-umbs.bg b/EDTS/Templates/ED2IN-umbs.bg index 0d928cfae..50ec0b65d 100644 --- a/EDTS/Templates/ED2IN-umbs.bg +++ b/EDTS/Templates/ED2IN-umbs.bg @@ -181,9 +181,10 @@ $ED_NL NL%SL_PROB_HARVEST = 1.0,1.0,1.0 NL%SL_MINDBH_HARVEST = 50.,50.,50. NL%SL_BIOMASS_HARVEST = 0 - NL%SL_SKID_REL_AREA = 1 - NL%SL_SKID_S_GTHARV = 1 - NL%SL_SKID_S_LTHARV = 0.6 + NL%SL_SKID_REL_AREA = 1 + NL%SL_SKID_DBH_THRESH = 30. + NL%SL_SKID_S_GTHARV = 1 + NL%SL_SKID_S_LTHARV = 0.6 NL%SL_FELLING_S_LTHARV = 0.35 NL%CL_FSEEDS_HARVEST = 0.75 NL%CL_FSTORAGE_HARVEST = 0.00 diff --git a/R-utils/Ft.ustar.r b/R-utils/Ft.ustar.r index e63c53fc9..1374e08d9 100644 --- a/R-utils/Ft.ustar.r +++ b/R-utils/Ft.ustar.r @@ -19,7 +19,18 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ #---------------------------------------------------------------------------------------# - #----- Delete data that is missing. ----------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case storage is always NA, it means storage was not measured. In this case, we # + # assume zero storage whenever the CO2 flux is not missing. # + #---------------------------------------------------------------------------------------# + if ( all(! is.finite(cflxst)) && any(is.finite(cflxca)) ){ + cflxst = ifelse( test = is.finite(cflxca), yes = 0., no = NA_real_ ) + }#end if ( all(! is.finite(cflxst)) && any(is.finite(cflxca)) ) + #---------------------------------------------------------------------------------------# + + + + #----- Delete missing data. ------------------------------------------------------------# keep = is.finite(ustar) & is.finite(cflxca) & is.finite(cflxst) & nighttime keep = ifelse(is.na(keep),FALSE,keep) ustar = ustar [keep] @@ -80,7 +91,7 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ while (iterate){ b = b + 1 ttt = t.test(x=sp.cflxca[[b]],y=sp.cflxst[[b]],alternative="greater") - iterate = b < nbins && ttt$p.value %>=% 0.01 + iterate = b < nbins && ttt$p.value %ge% 0.01 }#end for #---------------------------------------------------------------------------------------# @@ -129,8 +140,8 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ #---- Check whether the p.value is sufficiently large. ------------------------------# - success = ( ( p.ft %<=% p.lm && p.lm %>=% 0.10 && p.ft %>=% 0.10 ) - || ( p.ft %>=% 0.50 && p.lm %>=% 0.50 ) ) + success = ( ( p.ft %le% p.lm && p.lm %ge% 0.10 && p.ft %ge% 0.10 ) + || ( p.ft %ge% 0.50 && p.lm %ge% 0.50 ) ) iterate = ( ! success ) && (b < (nbins - 2)) cat(" u* = ",ustar.breaks[b],"; p.lm = ",sprintf("%.2f",p.lm) ,"; p.ft = ",sprintf("%.2f",p.ft) diff --git a/R-utils/allometry.r b/R-utils/allometry.r index ea350baec..13e98f355 100644 --- a/R-utils/allometry.r +++ b/R-utils/allometry.r @@ -8,7 +8,7 @@ h2dbh <<- function(h,ipft){ zpft = ipft }#end if - tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4) + tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4,5) tropn = pft$tropical[zpft] & iallom %in% c(2) tempe = ! pft$tropical[zpft] @@ -54,7 +54,7 @@ dbh2h <<- function(dbh,ipft,use.crit=TRUE){ dbhuse = dbh }#end if (use.crit) - tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4) + tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4,5) tropn = pft$tropical[zpft] & iallom %in% c(2) tempe = ! pft$tropical[zpft] @@ -102,7 +102,7 @@ size2bl <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -113,7 +113,7 @@ size2bl <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ # For iallom == 4 (tropical trees), b1Bl and b2Bl represents leaf area based # # allometry, we need to convert it to biomass using cohort-level SLA. # #---------------------------------------------------------------------------------------# - bleaf = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(4)) + bleaf = ifelse( test = pft$ddh.allom[zpft] , yes = pft$b1Bl[zpft] / sla * size ^ pft$b2Bl[zpft] , no = pft$b1Bl[zpft] / C2B * size ^ pft$b2Bl[zpft] )#end ifelse @@ -182,7 +182,7 @@ size2bd <<- function(dbh,hgt,ipft){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbh * dbh * dbh2h(dbh,ipft=zpft) , no = dbh )#end ifelse @@ -191,7 +191,7 @@ size2bd <<- function(dbh,hgt,ipft){ #----- Select allometric parameters based on the size. ---------------------------------# - bdead = ifelse( test = dbh %<% pft$dbh.crit[zpft] + bdead = ifelse( test = dbh %lt% pft$dbh.crit[zpft] , yes = pft$b1Bs.small[zpft] / C2B * size ^ pft$b2Bs.small[zpft] , no = pft$b1Bs.large[zpft] / C2B * size ^ pft$b2Bs.large[zpft] )#end ifelse @@ -249,8 +249,8 @@ size2de <<- function(dbh,hgt,ipft,dbh.by=0.1,...){ #----- Identify cohorts with size that outside resolvable height range. ----------------# - large = (dbh*dbh*hgt) %>=% (pft$dbh.crit[zpft]*pft$dbh.crit[zpft]*pft$hgt.max[zpft]) - small = (dbh*dbh*hgt) %<=% (pft$dbh.min [zpft]*pft$dbh.min [zpft]*pft$hgt.min[zpft]) + large = (dbh*dbh*hgt) %ge% (pft$dbh.crit[zpft]*pft$dbh.crit[zpft]*pft$hgt.max[zpft]) + small = (dbh*dbh*hgt) %le% (pft$dbh.min [zpft]*pft$dbh.min [zpft]*pft$hgt.min[zpft]) heq = ifelse( test = large , yes = pft$hgt.max[zpft] , no = ifelse(test = small,yes=pft$hgt.min[zpft],no=NA_real_) @@ -321,7 +321,7 @@ size2ca <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -368,7 +368,7 @@ size2wai <<- function(dbh,hgt,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -505,7 +505,7 @@ size2rd <<- function(hgt,dbh,ipft){ #------------------------------------------------------------------------------------# vol = size2vol(hgt=hgt,dbh=dbh,ipft=zpft) rd = pft$b1Rd[zpft] * (hgt * dbh * dbh) ^ pft$b2Rd[zpft] - }else if (iallom %in% c(1,2,4)){ + }else if (iallom %in% c(1,2,4,5)){ #------------------------------------------------------------------------------------# # This is just a test allometry, that imposes root depth to be 0.5 m for # # plants that are 0.15-m tall, and 5.0 m for plants that are 35-m tall. # diff --git a/R-utils/amzbr_poi.csv b/R-utils/amzbr_poi.csv new file mode 100644 index 000000000..92c63a1a2 --- /dev/null +++ b/R-utils/amzbr_poi.csv @@ -0,0 +1,351 @@ +short,iata,longname,lon,lat,alt,wmo,isoilflg,istext,sand,clay,slsoc,slph,slcec,sldbd,depth,isoilbc,sldrain,scolour,met.driver,yeara,yearz,iphen,iage +AMZBR_0001,a0001,Amazon Polygon 0001,-61.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0002,a0002,Amazon Polygon 0002,-60.5,-13.5,NA,NA,2,3,0.614,0.173,0.0179,5.2,0.099,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0003,a0003,Amazon Polygon 0003,-63.5,-12.5,NA,NA,2,6,0.495,0.262,0.016,5,0.086,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0004,a0004,Amazon Polygon 0004,-62.5,-12.5,NA,NA,2,6,0.532827158181877,0.223343203931085,0.0151842159320799,4.81890525820088,0.0924997073894,1223.15593565532,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0005,a0005,Amazon Polygon 0005,-61.5,-12.5,NA,NA,2,6,0.450731520182141,0.306403635818869,0.0183703078468289,4.88934097681909,0.0847669342966816,1220.75569914233,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0006,a0006,Amazon Polygon 0006,-60.5,-12.5,NA,NA,2,6,0.558696336870935,0.25565491270113,0.0175133858267717,5.01828141047586,0.0786268401232455,1228.952413557,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0007,a0007,Amazon Polygon 0007,-57.5,-12.5,NA,NA,2,3,0.709133718829057,0.193535598120708,0.0181794000722805,4.42490061438381,0.117891217925551,1208.67003975425,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0008,a0008,Amazon Polygon 0008,-56.5,-12.5,NA,NA,2,3,0.606,0.148,0.0193,4.8,0.119,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0009,a0009,Amazon Polygon 0009,-55.5,-12.5,NA,NA,2,3,0.589,0.157,0.0202,4.9,0.103,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0010,a0010,Amazon Polygon 0010,-54.5,-12.5,NA,NA,2,6,0.588931216931217,0.262272927689594,0.0225351851851852,4.77416225749559,0.0949766313932981,1217.7557319224,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0011,a0011,Amazon Polygon 0011,-53.5,-12.5,NA,NA,2,6,0.599319673617407,0.255952493200363,0.0254086854034451,4.85642792384406,0.0997787851314597,1223.12420670898,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0012,a0012,Amazon Polygon 0012,-52.5,-12.5,NA,NA,2,6,0.612817371143214,0.240545211342964,0.0232944533618691,4.87788478687355,0.0945580524344569,1232.01533797039,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0013,a0013,Amazon Polygon 0013,-64.5,-11.5,NA,NA,2,6,0.479828543080773,0.284419945311968,0.0166047393115583,4.81936043008105,0.100291496056211,1195.82545471844,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0014,a0014,Amazon Polygon 0014,-63.5,-11.5,NA,NA,2,6,0.485,0.257,0.0158,4.9,0.106,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0015,a0015,Amazon Polygon 0015,-62.5,-11.5,NA,NA,2,6,0.501,0.249,0.0156,4.8,0.097,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0016,a0016,Amazon Polygon 0016,-61.5,-11.5,NA,NA,2,6,0.523848657024793,0.226321280991736,0.0169982954545455,4.49927685950413,0.124055785123967,1184.70041322314,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0017,a0017,Amazon Polygon 0017,-60.5,-11.5,NA,NA,2,6,0.497783881692461,0.240416956240693,0.0196677284365722,4.45150152401207,0.126352349579395,1200.16621915694,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0018,a0018,Amazon Polygon 0018,-58.5,-11.5,NA,NA,2,3,0.693155778355077,0.173519040956307,0.0190220585730911,4.49683832001874,0.093880134066002,1204.17132873688,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0019,a0019,Amazon Polygon 0019,-57.5,-11.5,NA,NA,2,6,0.63242030075188,0.211000751879699,0.018783984962406,4.40165413533835,0.118276315789474,1200.62781954887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0020,a0020,Amazon Polygon 0020,-56.5,-11.5,NA,NA,2,6,0.57516957605985,0.227517278232989,0.018230067687923,4.47965799786249,0.108535447096544,1183.00320627004,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0021,a0021,Amazon Polygon 0021,-55.5,-11.5,NA,NA,2,6,0.510825076502976,0.257880298023357,0.0184726919460603,4.49994209822324,0.0874274582138211,1220.57710949869,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0022,a0022,Amazon Polygon 0022,-54.5,-11.5,NA,NA,2,6,0.487881694188864,0.278034703205448,0.0195147338426058,4.46274694902791,0.0922889434748252,1212.0752010889,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0023,a0023,Amazon Polygon 0023,-53.5,-11.5,NA,NA,2,6,0.555425406611463,0.24867891830051,0.0224132015084607,4.54773858860616,0.10696034121807,1202.62595041515,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0024,a0024,Amazon Polygon 0024,-52.5,-11.5,NA,NA,2,6,0.590901915708812,0.240373946360153,0.0237653256704981,4.7,0.0953348659003831,1219.11111111111,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0025,a0025,Amazon Polygon 0025,-51.5,-11.5,NA,NA,2,6,0.570771587743732,0.269424592120971,0.0249384003183446,4.80632709908476,0.0955849582172702,1250.71627536809,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0026,a0026,Amazon Polygon 0026,-70.5,-10.5,NA,NA,2,5,0.268586573884568,0.273290216946377,0.0155534588620549,5.11150225133033,0.137365534179288,1232.50511665984,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0027,a0027,Amazon Polygon 0027,-69.5,-10.5,NA,NA,2,5,0.255309546902415,0.270967242632211,0.0138333107995789,4.98478570186679,0.108638683442099,1228.99132282708,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0028,a0028,Amazon Polygon 0028,-68.5,-10.5,NA,NA,2,5,0.375535984392639,0.257547019074892,0.014790658312192,4.94065469673704,0.0907140872889422,1197.26259706581,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0029,a0029,Amazon Polygon 0029,-67.5,-10.5,NA,NA,2,8,0.35,0.376,0.01775,4.9,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0030,a0030,Amazon Polygon 0030,-64.5,-10.5,NA,NA,2,6,0.529973709369025,0.283845602294455,0.0171866156787763,4.35984703632887,0.100737571701721,1192.34703632887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0031,a0031,Amazon Polygon 0031,-63.5,-10.5,NA,NA,2,8,0.432643394648829,0.299053929765886,0.0166405936454849,4.67403846153846,0.112194816053512,1210.72324414716,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0032,a0032,Amazon Polygon 0032,-62.5,-10.5,NA,NA,2,6,0.494,0.243,0.016,4.7,0.105,1260,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0033,a0033,Amazon Polygon 0033,-61.5,-10.5,NA,NA,2,6,0.49244186594181,0.238797371096574,0.014983443469425,4.43026238832619,0.111291163568836,1186.34065867886,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0034,a0034,Amazon Polygon 0034,-60.5,-10.5,NA,NA,2,6,0.491073476702509,0.23670394265233,0.01958,4.50075268817204,0.163920788530466,1192.56630824373,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0035,a0035,Amazon Polygon 0035,-59.5,-10.5,NA,NA,2,5,0.461174165897482,0.210466248712498,0.0178801675803811,4.24772576654593,0.127716360263101,1188.02454954436,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0036,a0036,Amazon Polygon 0036,-58.5,-10.5,NA,NA,2,6,0.514599857223987,0.252289045767123,0.0188627956798313,4.21694322049529,0.13539388654222,1190.54806387158,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0037,a0037,Amazon Polygon 0037,-57.5,-10.5,NA,NA,2,6,0.465125610607118,0.267740753663643,0.0236287508722959,4.52194696441033,0.153891835310537,1182.19818562456,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0038,a0038,Amazon Polygon 0038,-56.5,-10.5,NA,NA,2,5,0.464903981264637,0.250442232630757,0.0205060109289617,4.61795472287276,0.125676034348165,1156.95940671351,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0039,a0039,Amazon Polygon 0039,-55.5,-10.5,NA,NA,2,6,0.505,0.253,0.0235,4.7,0.103,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0040,a0040,Amazon Polygon 0040,-54.5,-10.5,NA,NA,2,5,0.393729058561898,0.264852853965901,0.0252414751667902,4.57464788732394,0.121721645663454,1179.52928094885,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0041,a0041,Amazon Polygon 0041,-53.5,-10.5,NA,NA,2,5,0.401815985879695,0.245247932799796,0.0253594807000572,4.60263405422378,0.150477803500267,1194.09328244205,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0042,a0042,Amazon Polygon 0042,-52.5,-10.5,NA,NA,2,5,0.399637471243974,0.242709380581886,0.0238326686745709,4.72583446003614,0.150625690337864,1210.92894080837,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0043,a0043,Amazon Polygon 0043,-51.5,-10.5,NA,NA,2,6,0.618858166616901,0.205634219169901,0.0287937593311436,4.66846819946253,0.107021200358316,1230.14034040012,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0044,a0044,Amazon Polygon 0044,-71.5,-9.5,NA,NA,2,5,0.2943,0.259934782608696,0.0158695652173913,4.95608695652174,0.112786956521739,1235.52173913043,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0045,a0045,Amazon Polygon 0045,-70.5,-9.5,NA,NA,2,5,0.305387091805691,0.261167482153038,0.0162427374391191,5.02855481083927,0.136660936118321,1231.51185619382,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0046,a0046,Amazon Polygon 0046,-69.5,-9.5,NA,NA,2,7,0.179644132168629,0.313389669578428,0.0173817698442841,4.66532472464869,0.112062666160273,1175.17280668439,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0047,a0047,Amazon Polygon 0047,-68.5,-9.5,NA,NA,2,8,0.212696200292891,0.282547400081515,0.015953183856051,4.48167131689039,0.0964868885524467,1194.66360484659,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0048,a0048,Amazon Polygon 0048,-67.5,-9.5,NA,NA,2,17,0.294,0.401,0.016,4.4,0.103,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0049,a0049,Amazon Polygon 0049,-66.5,-9.5,NA,NA,2,8,0.390965537390559,0.326264148863619,0.0155160579886473,4.10831258032794,0.110196527696416,1181.08181612982,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0050,a0050,Amazon Polygon 0050,-65.5,-9.5,NA,NA,2,6,0.502480310179564,0.292924625920026,0.0149670508436175,4.08581239331415,0.0987440934990041,1196.04507161374,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0051,a0051,Amazon Polygon 0051,-64.5,-9.5,NA,NA,2,6,0.494187799505387,0.312813945287714,0.0149187115745389,4.11208667279386,0.106490502680508,1191.6781646651,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0052,a0052,Amazon Polygon 0052,-63.5,-9.5,NA,NA,2,5,0.422,0.228,0.0154,4.2,0.112,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0053,a0053,Amazon Polygon 0053,-62.5,-9.5,NA,NA,2,6,0.526723673792557,0.304761678543151,0.0146926365795724,4.13927157561362,0.135636579572447,1158.82026920032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0054,a0054,Amazon Polygon 0054,-61.5,-9.5,NA,NA,2,6,0.475837709065701,0.29394519942737,0.015715992691971,4.3700175457831,0.116479974835913,1164.29444036872,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0055,a0055,Amazon Polygon 0055,-60.5,-9.5,NA,NA,2,5,0.447614974910265,0.253068502357162,0.01506097630202,4.41817571496863,0.118908089626355,1188.45530971388,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0056,a0056,Amazon Polygon 0056,-59.5,-9.5,NA,NA,2,8,0.436,0.293,0.0156,4.4,0.119,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0057,a0057,Amazon Polygon 0057,-58.5,-9.5,NA,NA,2,8,0.373190780945213,0.311429482796364,0.0175689428738517,4.2942220707985,0.0995860169035956,1174.96904734837,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0058,a0058,Amazon Polygon 0058,-57.5,-9.5,NA,NA,2,8,0.307440996390111,0.317666280594289,0.0225546361273277,4.21207162666504,0.119468748654608,1167.99140995435,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0059,a0059,Amazon Polygon 0059,-56.5,-9.5,NA,NA,2,6,0.506473550552617,0.24092955085447,0.0195003808627664,4.56988751127002,0.117750887984349,1147.19256543143,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0060,a0060,Amazon Polygon 0060,-55.5,-9.5,NA,NA,2,8,0.361656974459725,0.309918271119843,0.0260042043222004,4.72495088408644,0.127231827111984,1144.39685658153,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0061,a0061,Amazon Polygon 0061,-54.5,-9.5,NA,NA,2,8,0.349,0.362,0.025,4.7,0.11,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0062,a0062,Amazon Polygon 0062,-53.5,-9.5,NA,NA,2,5,0.349855406244037,0.264574030049878,0.0247361279049624,4.79534808484788,0.114095044355591,1180.68561139773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0063,a0063,Amazon Polygon 0063,-52.5,-9.5,NA,NA,2,5,0.33865035510691,0.261535925271796,0.0256825678221337,4.87961449338954,0.129706389892549,1199.54266478572,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0064,a0064,Amazon Polygon 0064,-51.5,-9.5,NA,NA,2,6,0.498,0.268,0.0245,4.9,0.104,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0065,a0065,Amazon Polygon 0065,-50.5,-9.5,NA,NA,2,6,0.525777332900562,0.208962055089023,0.0241504218658141,4.83680823227603,0.101601278318499,1216.26059760822,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0066,a0066,Amazon Polygon 0066,-72.5,-8.5,NA,NA,2,8,0.308196101665935,0.278748366544917,0.0183815152392838,4.86620001626734,0.134061153724777,1229.3862292831,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0067,a0067,Amazon Polygon 0067,-71.5,-8.5,NA,NA,2,8,0.264883241943049,0.300300623375535,0.0162334923811684,5.03047408913002,0.119286187412714,1219.72116159341,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0068,a0068,Amazon Polygon 0068,-70.5,-8.5,NA,NA,2,5,0.234465406275141,0.272731697506034,0.0144447304907482,4.65398230088496,0.125496781979083,1213.52373290426,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0069,a0069,Amazon Polygon 0069,-69.5,-8.5,NA,NA,2,17,0.195,0.475,0.0187,4.5,0.129,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0070,a0070,Amazon Polygon 0070,-68.5,-8.5,NA,NA,2,8,0.284172835164074,0.310147088504925,0.0167848071918792,4.19720324027838,0.125654576915696,1182.77061513042,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0071,a0071,Amazon Polygon 0071,-67.5,-8.5,NA,NA,2,8,0.292415094339623,0.280952830188679,0.0174801886792453,4.00471698113208,0.128358490566038,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0072,a0072,Amazon Polygon 0072,-66.5,-8.5,NA,NA,2,5,0.333994414551417,0.273713230915524,0.0166014804391806,4.00638898330226,0.124824917685918,1182.2743102262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0073,a0073,Amazon Polygon 0073,-65.5,-8.5,NA,NA,2,5,0.391689886228156,0.270636335410864,0.016295352637965,4.07896382826861,0.126661592497729,1179.22209455998,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0074,a0074,Amazon Polygon 0074,-64.5,-8.5,NA,NA,2,8,0.275761382799325,0.305858347386172,0.0152971753794266,4.03537099494098,0.131158094435076,1168.42327150084,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0075,a0075,Amazon Polygon 0075,-63.5,-8.5,NA,NA,2,5,0.446589841795909,0.230337786650386,0.0158791607766828,4.09768862141198,0.136847354038952,1157.19072304322,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0076,a0076,Amazon Polygon 0076,-62.5,-8.5,NA,NA,2,6,0.485391852708602,0.303511448010119,0.0159982613780063,4.07286673656322,0.142600464137334,1155.32594619365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0077,a0077,Amazon Polygon 0077,-61.5,-8.5,NA,NA,2,8,0.39032962633452,0.345288256227758,0.0164452846975089,4.03171708185053,0.159075622775801,1152.02846975089,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0078,a0078,Amazon Polygon 0078,-60.5,-8.5,NA,NA,2,8,0.449616911764706,0.296716911764706,0.0162023897058824,4.20419117647059,0.125605882352941,1148.41544117647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0079,a0079,Amazon Polygon 0079,-59.5,-8.5,NA,NA,2,8,0.430033564013841,0.302976124567474,0.0164828719723183,4.30847750865052,0.119707958477509,1179.83737024221,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0080,a0080,Amazon Polygon 0080,-58.5,-8.5,NA,NA,2,8,0.394577675922117,0.296017847845743,0.0219717984785969,4.16831558112525,0.111375879436032,1158.48458933164,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0081,a0081,Amazon Polygon 0081,-57.5,-8.5,NA,NA,2,8,0.315638539518452,0.296398497272827,0.0217040873252256,4.25230282100439,0.125653331708667,1186.68046425431,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0082,a0082,Amazon Polygon 0082,-56.5,-8.5,NA,NA,2,6,0.483814907575956,0.273005780648467,0.020767937415412,4.37064210130148,0.124972786107768,1144.58596627468,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0083,a0083,Amazon Polygon 0083,-55.5,-8.5,NA,NA,2,8,0.421587032842893,0.290319392737938,0.0241565207003981,4.52127644933888,0.126940318506445,1121.21486336916,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0084,a0084,Amazon Polygon 0084,-54.5,-8.5,NA,NA,2,5,0.458282146473169,0.246636854539318,0.0201726628417145,4.65366182922713,0.111901788727641,1171.96085048937,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0085,a0085,Amazon Polygon 0085,-53.5,-8.5,NA,NA,2,5,0.431616948300138,0.244417809042943,0.0215428077825752,4.86602068162482,0.112193635844849,1174.86039365359,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0086,a0086,Amazon Polygon 0086,-52.5,-8.5,NA,NA,2,8,0.308990110529378,0.277067481093659,0.0239304828388598,4.89464805119255,0.109695753344968,1182.61780104712,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0087,a0087,Amazon Polygon 0087,-51.5,-8.5,NA,NA,2,8,0.406,0.338,0.0222,4.9,0.108,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0088,a0088,Amazon Polygon 0088,-50.5,-8.5,NA,NA,2,6,0.4685,0.295,0.0185,4.9,0.1,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0089,a0089,Amazon Polygon 0089,-49.5,-8.5,NA,NA,2,8,0.431,0.339,0.0169,5,0.092,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0090,a0090,Amazon Polygon 0090,-73.5,-7.5,NA,NA,2,8,0.391,0.324,0.0224,4.5,0.136,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0091,a0091,Amazon Polygon 0091,-72.5,-7.5,NA,NA,2,5,0.444441610513001,0.204659918732888,0.0266572703059183,4.3666707129805,0.118013108343385,1215.66088118286,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0092,a0092,Amazon Polygon 0092,-71.5,-7.5,NA,NA,2,5,0.386658737850952,0.272557957864953,0.0199268460635044,4.31066929344001,0.124357484483654,1219.21429426263,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0093,a0093,Amazon Polygon 0093,-70.5,-7.5,NA,NA,2,5,0.366125589077417,0.253766524780332,0.0181243697535265,4.48917334601188,0.136852753442216,1221.44094531756,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0094,a0094,Amazon Polygon 0094,-69.5,-7.5,NA,NA,2,8,0.253972444637277,0.312403365737154,0.0178998208380468,4.34265742362901,0.136120903769662,1182.20953369047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0095,a0095,Amazon Polygon 0095,-68.5,-7.5,NA,NA,2,8,0.200743368179314,0.301632325090516,0.0172303795472488,4.22280023851364,0.137691803984821,1181.03801223613,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0096,a0096,Amazon Polygon 0096,-67.5,-7.5,NA,NA,2,5,0.381922800638101,0.255151761226465,0.0196085375387342,4.09823179411313,0.135412690661849,1175.34945814459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0097,a0097,Amazon Polygon 0097,-66.5,-7.5,NA,NA,2,5,0.348184485006519,0.23294035202086,0.024803520208605,4.04439374185137,0.191614732724902,1177.87157757497,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0098,a0098,Amazon Polygon 0098,-65.5,-7.5,NA,NA,2,8,0.308420070011669,0.321481135744846,0.0307659665499806,3.96472189809413,0.169152080902373,1180.05056398289,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0099,a0099,Amazon Polygon 0099,-64.5,-7.5,NA,NA,2,5,0.351106795659845,0.254051741535766,0.0203675119637823,4.07047266919123,0.136158306477854,1174.39542714777,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0100,a0100,Amazon Polygon 0100,-63.5,-7.5,NA,NA,2,5,0.348967213114754,0.26909079445145,0.0190341740226986,4.06746532156368,0.141581336696091,1157.49054224464,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0101,a0101,Amazon Polygon 0101,-62.5,-7.5,NA,NA,2,5,0.378444493006993,0.260364073426573,0.0191657342657343,3.94291958041958,0.134450174825175,1164.74213286713,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0102,a0102,Amazon Polygon 0102,-61.5,-7.5,NA,NA,2,6,0.453149367351377,0.28299968276548,0.0227161959982204,3.88057940082181,0.151093734890761,1143.15157711345,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0103,a0103,Amazon Polygon 0103,-60.5,-7.5,NA,NA,2,8,0.373584675406836,0.329590782847593,0.0207403994178037,3.96982038909162,0.145212434772781,1148.79399666279,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0104,a0104,Amazon Polygon 0104,-59.5,-7.5,NA,NA,2,8,0.405411632262946,0.327696254382808,0.018126229491516,4.09238941624413,0.110656700148928,1151.25093690372,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0105,a0105,Amazon Polygon 0105,-58.5,-7.5,NA,NA,2,8,0.428718387571201,0.29752014655824,0.0203812926641996,4.06013174998406,0.114318209045183,1142.86488831388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0106,a0106,Amazon Polygon 0106,-57.5,-7.5,NA,NA,2,6,0.472673811569476,0.27488861900762,0.0187833172623552,4.1798953546306,0.11831492959481,1142.06634486178,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0107,a0107,Amazon Polygon 0107,-56.5,-7.5,NA,NA,2,6,0.500921888020872,0.288057685256937,0.0208270270845811,4.2068280147721,0.12062062271103,1146.91242218899,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0108,a0108,Amazon Polygon 0108,-55.5,-7.5,NA,NA,2,6,0.502766601941748,0.260951067961165,0.0187345242718447,4.44784466019418,0.126612815533981,1148.86990291262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0109,a0109,Amazon Polygon 0109,-54.5,-7.5,NA,NA,2,8,0.448037156462829,0.279485268453837,0.0204603661946344,4.58734200570774,0.123710238224751,1141.20139248498,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0110,a0110,Amazon Polygon 0110,-53.5,-7.5,NA,NA,2,5,0.405870414394448,0.272369805154135,0.023213342243383,4.74567721897063,0.121075053077005,1161.26218937101,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0111,a0111,Amazon Polygon 0111,-52.5,-7.5,NA,NA,2,5,0.423161031407032,0.260672216314762,0.0215711442273108,4.91259080863187,0.123516537823892,1174.36324277597,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0112,a0112,Amazon Polygon 0112,-51.5,-7.5,NA,NA,2,5,0.41030231838826,0.239494717325198,0.0220526448879972,4.92635660676482,0.126257567676888,1171.95394064303,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0113,a0113,Amazon Polygon 0113,-50.5,-7.5,NA,NA,2,5,0.412344678552134,0.26009508373852,0.0203463533225284,4.9,0.116281469475959,1174.65694219341,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0114,a0114,Amazon Polygon 0114,-49.5,-7.5,NA,NA,2,8,0.419,0.312,0.0186,5,0.091,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0115,a0115,Amazon Polygon 0115,-72.5,-6.5,NA,NA,2,8,0.345939206079485,0.303633795622216,0.0243704137723336,4.17603294844803,0.150050279166451,1196.53872861361,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0116,a0116,Amazon Polygon 0116,-71.5,-6.5,NA,NA,2,8,0.365716493645615,0.300526175467609,0.0226478336799038,4.22261301260796,0.147174307282635,1182.35775502717,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0117,a0117,Amazon Polygon 0117,-70.5,-6.5,NA,NA,2,8,0.305412541254125,0.315392326732673,0.0216017326732673,4.21839933993399,0.150901402640264,1205.20627062706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0118,a0118,Amazon Polygon 0118,-69.5,-6.5,NA,NA,2,8,0.34921965818152,0.289604052229818,0.0203178301890008,4.18135129314014,0.145573370106932,1184.21751984388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0119,a0119,Amazon Polygon 0119,-68.5,-6.5,NA,NA,2,5,0.348604688763137,0.253696038803557,0.0206685529506871,4.08164915117219,0.167421180274859,1176.0064672595,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0120,a0120,Amazon Polygon 0120,-67.5,-6.5,NA,NA,2,5,0.365728348805189,0.260591566985573,0.0227778287695533,4.02753760229251,0.14967491544859,1183.13628939597,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0121,a0121,Amazon Polygon 0121,-66.5,-6.5,NA,NA,2,8,0.363994422005904,0.287466842724147,0.0256279680184059,4.03136513463336,0.162374574213007,1172.78109534152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0122,a0122,Amazon Polygon 0122,-65.5,-6.5,NA,NA,2,8,0.289125427594071,0.328168757126568,0.0314795515013303,3.91022424933485,0.261543139490688,1155.68985176739,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0123,a0123,Amazon Polygon 0123,-64.5,-6.5,NA,NA,2,8,0.249266584145497,0.284162360328903,0.020971189741879,4.08993166317843,0.14584038391267,1174.72197515196,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0124,a0124,Amazon Polygon 0124,-63.5,-6.5,NA,NA,2,7,0.196579547290917,0.275370295899876,0.0199282736771132,4.11996596514939,0.150321114510502,1171.63357395483,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0125,a0125,Amazon Polygon 0125,-62.5,-6.5,NA,NA,2,5,0.244662535410765,0.274032577903683,0.0191499291784703,4.13445467422096,0.117794971671388,1159.95042492918,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0126,a0126,Amazon Polygon 0126,-61.5,-6.5,NA,NA,2,3,0.560114285714286,0.1922,0.0275228571428571,3.88285714285714,0.1474,1111.71428571429,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0127,a0127,Amazon Polygon 0127,-60.5,-6.5,NA,NA,2,8,0.388485111813259,0.358129854186806,0.0245543343694118,3.92201855126991,0.129592882908742,1138.78255735462,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0128,a0128,Amazon Polygon 0128,-59.5,-6.5,NA,NA,2,8,0.329346531302876,0.337793570219966,0.0191165143824027,4.04602368866328,0.109199323181049,1143.87140439932,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0129,a0129,Amazon Polygon 0129,-58.5,-6.5,NA,NA,2,8,0.401046897022193,0.331684073736919,0.0208013602676036,4.02297069725274,0.107369580881748,1162.37055629501,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0130,a0130,Amazon Polygon 0130,-57.5,-6.5,NA,NA,2,8,0.402082448308531,0.329085118646906,0.0205117771282756,4.05679704007993,0.120642426752595,1147.70319656278,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0131,a0131,Amazon Polygon 0131,-56.5,-6.5,NA,NA,2,8,0.403477622136805,0.311749766298696,0.0207805693787863,4.07391789389225,0.135365797214032,1141.82167733301,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0132,a0132,Amazon Polygon 0132,-55.5,-6.5,NA,NA,2,8,0.315060023085802,0.307880723355137,0.021293420546364,4.02181608310889,0.15152558676414,1134.78260869565,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0133,a0133,Amazon Polygon 0133,-54.5,-6.5,NA,NA,2,5,0.472456509042975,0.232519024079735,0.0184966023346652,4.39294157816014,0.120887602741927,1139.14116702345,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0134,a0134,Amazon Polygon 0134,-53.5,-6.5,NA,NA,2,5,0.433865380282771,0.260146140656473,0.020582968267837,4.68518820884446,0.114179586990585,1161.35344960581,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0135,a0135,Amazon Polygon 0135,-52.5,-6.5,NA,NA,2,8,0.398,0.302,0.0219,4.7,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0136,a0136,Amazon Polygon 0136,-51.5,-6.5,NA,NA,2,8,0.399,0.3,0.0223,4.7,0.11,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0137,a0137,Amazon Polygon 0137,-50.5,-6.5,NA,NA,2,8,0.375477076859613,0.293679840673366,0.0243680114404698,4.8353155320134,0.117020456632055,1162.96801551463,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0138,a0138,Amazon Polygon 0138,-49.5,-6.5,NA,NA,2,8,0.41,0.305,0.0195,4.9,0.102,1240,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0139,a0139,Amazon Polygon 0139,-48.5,-6.5,NA,NA,2,8,0.438,0.295,0.0163,5,0.084,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0140,a0140,Amazon Polygon 0140,-72.5,-5.5,NA,NA,2,8,0.316631318267378,0.293731070052168,0.0212564050324336,4.03435012014072,0.133540200221238,1204.23283989838,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0141,a0141,Amazon Polygon 0141,-71.5,-5.5,NA,NA,2,8,0.261831067264059,0.331674853274107,0.0242969500923943,4.13961911542858,0.144168750466063,1175.89916503948,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0142,a0142,Amazon Polygon 0142,-70.5,-5.5,NA,NA,2,8,0.343382487520799,0.321202787021631,0.0223361064891847,4.14968801996672,0.135537853577371,1182.25457570715,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0143,a0143,Amazon Polygon 0143,-69.5,-5.5,NA,NA,2,8,0.274067385416902,0.372217615069417,0.0230286438385721,4.12630420864217,0.1318701219462,1184.8735444809,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0144,a0144,Amazon Polygon 0144,-68.5,-5.5,NA,NA,2,8,0.376389945078158,0.339515842839037,0.0280085762568652,4.00566117448247,0.167994930291508,1190.59146599071,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0145,a0145,Amazon Polygon 0145,-67.5,-5.5,NA,NA,2,8,0.356222727272727,0.306647159090909,0.0269543181818182,4.03232954545455,0.150550568181818,1144.60227272727,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0146,a0146,Amazon Polygon 0146,-66.5,-5.5,NA,NA,2,8,0.371920323009405,0.315239792837457,0.0268064244874011,4.08748153937897,0.153513564625017,1163.25080116365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0147,a0147,Amazon Polygon 0147,-65.5,-5.5,NA,NA,2,8,0.320175685557587,0.328858500914077,0.0264373126142596,4.2209689213894,0.152609140767825,1175.46252285192,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0148,a0148,Amazon Polygon 0148,-64.5,-5.5,NA,NA,2,17,0.19,0.501,0.0244,4.1,0.15,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0149,a0149,Amazon Polygon 0149,-63.5,-5.5,NA,NA,2,17,0.151,0.531,0.021,4.2,0.148,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0150,a0150,Amazon Polygon 0150,-62.5,-5.5,NA,NA,2,7,0.162319696146734,0.283881096617385,0.02113330578884,4.10775040297384,0.137642820829614,1171.37074442068,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0151,a0151,Amazon Polygon 0151,-61.5,-5.5,NA,NA,2,17,0.231,0.456,0.0193,4,0.114,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0152,a0152,Amazon Polygon 0152,-60.5,-5.5,NA,NA,2,8,0.341970195896916,0.374434081407434,0.020952469499411,3.94210630242548,0.116940004238079,1151.01613736737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0153,a0153,Amazon Polygon 0153,-59.5,-5.5,NA,NA,2,8,0.232390243902439,0.348792682926829,0.0172573170731707,4.04268292682927,0.110219512195122,1142.19512195122,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0154,a0154,Amazon Polygon 0154,-58.5,-5.5,NA,NA,2,8,0.367328599477271,0.346718543401378,0.0163035298076339,4.16878166280633,0.105175781723714,1141.87391642773,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0155,a0155,Amazon Polygon 0155,-57.5,-5.5,NA,NA,2,8,0.357098701250047,0.3620339573164,0.0193660672959784,4.19626448101776,0.112960418923554,1149.06354993779,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0156,a0156,Amazon Polygon 0156,-56.5,-5.5,NA,NA,2,8,0.34612741653184,0.3127191263931,0.0202685715388804,4.02263168324212,0.137436727117829,1138.13882752506,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0157,a0157,Amazon Polygon 0157,-55.5,-5.5,NA,NA,2,8,0.278051742100947,0.33339098713427,0.0196052091300199,4.09188828089866,0.140839386752368,1140.87748074938,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0158,a0158,Amazon Polygon 0158,-54.5,-5.5,NA,NA,2,8,0.39464608371322,0.283622461665976,0.0203793203481144,4.24243680066308,0.117186904268545,1158.15167840862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0159,a0159,Amazon Polygon 0159,-53.5,-5.5,NA,NA,2,8,0.394302088079942,0.287042205311682,0.0185841949886112,4.44558374069444,0.104233757115698,1159.35239376196,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0160,a0160,Amazon Polygon 0160,-52.5,-5.5,NA,NA,2,8,0.398610950414417,0.285193127551434,0.0168288526619137,4.49620860509732,0.0943560255317985,1160.68634924208,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0161,a0161,Amazon Polygon 0161,-51.5,-5.5,NA,NA,2,8,0.422262532563853,0.301807108592407,0.0167985824585007,4.4886403343559,0.0944742243282384,1159.71514316469,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0162,a0162,Amazon Polygon 0162,-50.5,-5.5,NA,NA,2,8,0.370207576953433,0.318092344119968,0.0235119968429361,4.78003157063931,0.117884767166535,1167.6637726914,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0163,a0163,Amazon Polygon 0163,-49.5,-5.5,NA,NA,2,8,0.428,0.3,0.0182,4.7,0.096,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0164,a0164,Amazon Polygon 0164,-48.5,-5.5,NA,NA,2,8,0.449983009708738,0.306681692094313,0.018595665742025,4.73065187239945,0.0946463245492372,1188.93203883495,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0165,a0165,Amazon Polygon 0165,-71.5,-4.5,NA,NA,2,17,0.172,0.46,0.0438,4.2,0.119,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0166,a0166,Amazon Polygon 0166,-70.5,-4.5,NA,NA,2,7,0.180844339539162,0.326875672395628,0.0378916021208374,4.25120446069311,0.119021785409909,1183.58017266654,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0167,a0167,Amazon Polygon 0167,-69.5,-4.5,NA,NA,2,8,0.273516734693877,0.343818775510204,0.0231362448979592,4.19681632653061,0.121054285714286,1186.53469387755,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0168,a0168,Amazon Polygon 0168,-68.5,-4.5,NA,NA,2,8,0.342060798209623,0.358166728832525,0.0194925400969787,4.27907497202536,0.12147034688549,1193.32711674748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0169,a0169,Amazon Polygon 0169,-67.5,-4.5,NA,NA,2,8,0.348771046735434,0.306365616648273,0.0239883688631256,4.10847593744122,0.141212122899216,1154.67484644238,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0170,a0170,Amazon Polygon 0170,-66.5,-4.5,NA,NA,2,8,0.324960698490132,0.3012612351484,0.0265792256374342,4.20402743720121,0.142542745427422,1141.99287086459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0171,a0171,Amazon Polygon 0171,-65.5,-4.5,NA,NA,2,8,0.282513583441138,0.297124838292367,0.0212324062095731,3.95873221216041,0.128265847347995,1179.42432082794,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0172,a0172,Amazon Polygon 0172,-64.5,-4.5,NA,NA,2,7,0.19746709470305,0.290691813804173,0.01776886035313,3.97512038523274,0.137132423756019,1192.31942215088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0173,a0173,Amazon Polygon 0173,-63.5,-4.5,NA,NA,2,7,0.126954475308642,0.292680941358025,0.0181841820987654,3.78769290123457,0.126659722222222,1189.32098765432,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0174,a0174,Amazon Polygon 0174,-62.5,-4.5,NA,NA,2,4,0.163475716064757,0.273605230386052,0.0177661270236613,4.15230386052304,0.136013698630137,1161.02117061021,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0175,a0175,Amazon Polygon 0175,-61.5,-4.5,NA,NA,2,7,0.13280727212721,0.302809712941324,0.0262820949943889,3.94619143567497,0.113322670499445,1165.89946168109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0176,a0176,Amazon Polygon 0176,-60.5,-4.5,NA,NA,2,7,0.179919421487603,0.312974690082645,0.0183882747933884,4.09395661157025,0.127867768595041,1160.86260330579,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0177,a0177,Amazon Polygon 0177,-59.5,-4.5,NA,NA,2,8,0.336,0.318,0.0166,4.1,0.105,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0178,a0178,Amazon Polygon 0178,-58.5,-4.5,NA,NA,2,8,0.321262204059056,0.375463295514598,0.0144652699143677,4.09469339482078,0.104014310235251,1156.80443887106,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0179,a0179,Amazon Polygon 0179,-57.5,-4.5,NA,NA,2,8,0.415331305303557,0.366601371168554,0.0171815995710085,4.11656375020538,0.104339695117783,1157.63684320586,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0180,a0180,Amazon Polygon 0180,-56.5,-4.5,NA,NA,2,8,0.355593315895006,0.393720972354411,0.0162704985607786,4.19262089454544,0.105047794626876,1155.94914097185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0181,a0181,Amazon Polygon 0181,-55.5,-4.5,NA,NA,2,8,0.333254551700447,0.356485056681553,0.0200386808656819,4.18979732050842,0.100683613878392,1147.5334936448,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0182,a0182,Amazon Polygon 0182,-54.5,-4.5,NA,NA,2,8,0.36203836952556,0.363111520041128,0.0200708210486965,4.38380479003491,0.0977894594579951,1168.20588858607,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0183,a0183,Amazon Polygon 0183,-53.5,-4.5,NA,NA,2,8,0.412961517904864,0.307752004275788,0.0185749331908071,4.39567076429717,0.0942057723142704,1164.0994120791,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0184,a0184,Amazon Polygon 0184,-52.5,-4.5,NA,NA,2,8,0.411855537435268,0.337758914280448,0.0158014482785004,4.33425209540328,0.10255163071051,1179.34930849609,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0185,a0185,Amazon Polygon 0185,-51.5,-4.5,NA,NA,2,8,0.407422168172342,0.365154968728284,0.016791000694927,4.45868658790827,0.101891938846421,1185.28492008339,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0186,a0186,Amazon Polygon 0186,-50.5,-4.5,NA,NA,2,8,0.441613636363636,0.297163961038961,0.0201332792207792,4.79350649350649,0.102337662337662,1174.59415584416,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0187,a0187,Amazon Polygon 0187,-49.5,-4.5,NA,NA,2,8,0.444267904509284,0.319212201591512,0.0194294429708223,4.61007957559682,0.0989336870026525,1171.29973474801,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0188,a0188,Amazon Polygon 0188,-48.5,-4.5,NA,NA,2,6,0.472237000640531,0.301920428836852,0.0192040664945198,4.53387164472268,0.081042653742603,1191.18135010809,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0189,a0189,Amazon Polygon 0189,-47.5,-4.5,NA,NA,2,5,0.382,0.245,0.0164,4.9,0.075,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0190,a0190,Amazon Polygon 0190,-46.5,-4.5,NA,NA,2,8,0.439428484011334,0.358171322892075,0.0173332375996905,4.93920405875888,0.0900584877584942,1245.42093411732,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0191,a0191,Amazon Polygon 0191,-45.5,-4.5,NA,NA,2,5,0.448,0.259,0.0159,5.2,0.081,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0192,a0192,Amazon Polygon 0192,-69.5,-3.5,NA,NA,2,5,0.318452568295237,0.27335013367275,0.0429284412195275,4.30292278054564,0.131592159120715,1180.0924575863,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0193,a0193,Amazon Polygon 0193,-68.5,-3.5,NA,NA,2,8,0.289615166039776,0.302296043277158,0.0243809465206284,4.28969269797309,0.112370333047237,1179.8274509834,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0194,a0194,Amazon Polygon 0194,-67.5,-3.5,NA,NA,2,8,0.2700686321647,0.311963459336089,0.0251306205205177,4.14459388065387,0.133479905527406,1150.91269511748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0195,a0195,Amazon Polygon 0195,-66.5,-3.5,NA,NA,2,8,0.302732084799917,0.317106665959767,0.0257642142408992,4.19155826315183,0.137826048525465,1135.74955305385,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0196,a0196,Amazon Polygon 0196,-65.5,-3.5,NA,NA,2,8,0.258101936799185,0.303352701325178,0.0245166666666667,4.09964322120285,0.127257900101937,1130.76962283384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0197,a0197,Amazon Polygon 0197,-64.5,-3.5,NA,NA,2,8,0.277105975197294,0.314315670800451,0.024867305524239,4.07733934611048,0.104762495302518,1133.91206313416,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0198,a0198,Amazon Polygon 0198,-63.5,-3.5,NA,NA,2,7,0.173980475688053,0.284462404732551,0.0183109889017527,4.06681640015756,0.112112878079992,1197.74383952955,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0199,a0199,Amazon Polygon 0199,-62.5,-3.5,NA,NA,2,8,0.205569367108256,0.279964966850437,0.0228394088267051,4.11279350923955,0.113313215921889,1169.96765862445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0200,a0200,Amazon Polygon 0200,-61.5,-3.5,NA,NA,2,8,0.207130391278045,0.297064415803823,0.0195096321133073,4.07966417615082,0.105054381826692,1165.84000418523,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0201,a0201,Amazon Polygon 0201,-60.5,-3.5,NA,NA,2,7,0.174480848187578,0.33643972382086,0.0177493920338391,4.14915719674249,0.0951833241015492,1161.88606016416,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0202,a0202,Amazon Polygon 0202,-59.5,-3.5,NA,NA,2,17,0.206,0.445,0.0185,4.2,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0203,a0203,Amazon Polygon 0203,-58.5,-3.5,NA,NA,2,8,0.324809022354477,0.397831643474228,0.0147858549279727,4.12196836513106,0.103717253738994,1167.54251025312,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0204,a0204,Amazon Polygon 0204,-57.5,-3.5,NA,NA,2,16,0.360496891737772,0.400771151258777,0.0195854962555674,4.21449828935962,0.113981802402827,1182.22045084109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0205,a0205,Amazon Polygon 0205,-56.5,-3.5,NA,NA,2,9,0.466265704196725,0.359033669562661,0.0156241671891566,4.09684359417543,0.0942319636252154,1176.10157498244,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0206,a0206,Amazon Polygon 0206,-55.5,-3.5,NA,NA,2,6,0.48989805511363,0.342665064851515,0.014674402617952,4.11786563803893,0.097472504212456,1188.98461685856,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0207,a0207,Amazon Polygon 0207,-54.5,-3.5,NA,NA,2,6,0.450073758865248,0.343052482269504,0.0156248226950355,4.2090780141844,0.0934992907801418,1177.39007092199,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0208,a0208,Amazon Polygon 0208,-53.5,-3.5,NA,NA,2,16,0.370784294070405,0.401918467590509,0.0164540809953716,4.49237763605096,0.106611387152024,1179.96542957844,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0209,a0209,Amazon Polygon 0209,-52.5,-3.5,NA,NA,2,16,0.411803245436105,0.406446653144016,0.0191922515212982,4.45204868154158,0.0970085192697769,1165.39553752535,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0210,a0210,Amazon Polygon 0210,-51.5,-3.5,NA,NA,2,5,0.439,0.205,0.0184,4.6,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0211,a0211,Amazon Polygon 0211,-50.5,-3.5,NA,NA,2,8,0.444111894273128,0.336293392070485,0.0183740528634361,4.54718061674009,0.0998828193832599,1169.46696035242,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0212,a0212,Amazon Polygon 0212,-49.5,-3.5,NA,NA,2,6,0.479633160621762,0.308116062176166,0.0217348186528497,4.69139896373057,0.104853367875648,1165,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0213,a0213,Amazon Polygon 0213,-48.5,-3.5,NA,NA,2,6,0.468818388864697,0.311223015158725,0.0176027987542047,4.44463898577152,0.0863382558718974,1190.26577691576,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0214,a0214,Amazon Polygon 0214,-47.5,-3.5,NA,NA,2,5,0.467,0.207,0.0157,4.8,0.071,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0215,a0215,Amazon Polygon 0215,-46.5,-3.5,NA,NA,2,6,0.45541505595117,0.345739572736521,0.016979518480841,4.61631061376738,0.0877416073245168,1190.91217361818,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0216,a0216,Amazon Polygon 0216,-45.5,-3.5,NA,NA,2,8,0.376,0.314,0.014,5.1,0.091,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0217,a0217,Amazon Polygon 0217,-69.5,-2.5,NA,NA,2,5,0.501084205518554,0.186823977164605,0.039562226450999,4.30428163653663,0.152717411988582,1153.55851569933,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0218,a0218,Amazon Polygon 0218,-68.5,-2.5,NA,NA,2,5,0.474578107885745,0.225788409727348,0.0350460210800488,4.24778382175107,0.157631583701463,1120.71969737027,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0219,a0219,Amazon Polygon 0219,-67.5,-2.5,NA,NA,2,7,0.196220794392523,0.317254672897196,0.0251533878504673,4.2,0.134580607476636,1137.23130841121,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0220,a0220,Amazon Polygon 0220,-66.5,-2.5,NA,NA,2,8,0.226691168376192,0.320084291935551,0.030027757405747,4.18836586183917,0.142762258213817,1132.93145452059,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0221,a0221,Amazon Polygon 0221,-65.5,-2.5,NA,NA,2,7,0.185346839867306,0.290991858339675,0.0266765038387251,4.2015748646035,0.14271704441742,1105.73817449625,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0222,a0222,Amazon Polygon 0222,-64.5,-2.5,NA,NA,2,17,0.22,0.477,0.0261,4.1,0.136,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0223,a0223,Amazon Polygon 0223,-63.5,-2.5,NA,NA,2,8,0.238802126881665,0.28627569123884,0.0242921620325804,4.12534833508294,0.121304591884166,1157.52515713517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0224,a0224,Amazon Polygon 0224,-62.5,-2.5,NA,NA,2,8,0.303226557975135,0.323876468990194,0.0221805349432241,4.32238435161985,0.102009606543295,1175.28861746452,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0225,a0225,Amazon Polygon 0225,-61.5,-2.5,NA,NA,2,8,0.384794096355573,0.322833529555224,0.0162511491983126,4.58697499306154,0.103769225769498,1178.56654731473,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0226,a0226,Amazon Polygon 0226,-60.5,-2.5,NA,NA,2,8,0.391387837747938,0.333180572612777,0.0151653244823465,4.14886476578854,0.0976049802387028,1190.23849846549,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0227,a0227,Amazon Polygon 0227,-59.5,-2.5,NA,NA,2,16,0.39368801431127,0.41897030411449,0.0159848658318426,4.05656529516995,0.0781792486583184,1165.52772808587,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0228,a0228,Amazon Polygon 0228,-58.5,-2.5,NA,NA,2,16,0.436608137421665,0.40402770637311,0.0160778985219255,4.14956738462942,0.0944311173872009,1165.84296631185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0229,a0229,Amazon Polygon 0229,-57.5,-2.5,NA,NA,2,6,0.479282903641197,0.346625089658027,0.0156348479275412,4.12573829897359,0.098496227238243,1166.06664423999,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0230,a0230,Amazon Polygon 0230,-56.5,-2.5,NA,NA,2,6,0.568451904758393,0.287509378431131,0.0137057084578839,4.03121116079173,0.083103354371674,1176.84889973747,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0231,a0231,Amazon Polygon 0231,-55.5,-2.5,NA,NA,2,16,0.412741742088074,0.41123452200969,0.0159234345366853,4.10431978283066,0.100178754600689,1166.25327145647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0232,a0232,Amazon Polygon 0232,-54.5,-2.5,NA,NA,2,5,0.369,0.222,0.0165,4.6,0.124,1160,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0233,a0233,Amazon Polygon 0233,-53.5,-2.5,NA,NA,2,11,0.258783928069683,0.487778870469233,0.0174272548468671,4.49269457712841,0.107891261590334,1169.15987636977,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0234,a0234,Amazon Polygon 0234,-52.5,-2.5,NA,NA,2,5,0.47,0.243,0.0154,4.4,0.104,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0235,a0235,Amazon Polygon 0235,-51.5,-2.5,NA,NA,2,6,0.486723228995058,0.296668314113125,0.0166360241625481,4.37144426139484,0.0979077429983525,1190.0823723229,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0236,a0236,Amazon Polygon 0236,-50.5,-2.5,NA,NA,2,6,0.455851878847693,0.305996691233648,0.0185474019218788,4.43283007888501,0.109237515123583,1178.0902214773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0237,a0237,Amazon Polygon 0237,-49.5,-2.5,NA,NA,2,8,0.416494,0.330832,0.0206422,4.5,0.125394,1182.88,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0238,a0238,Amazon Polygon 0238,-48.5,-2.5,NA,NA,2,5,0.456,0.241,0.0165,4.7,0.093,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0239,a0239,Amazon Polygon 0239,-47.5,-2.5,NA,NA,2,5,0.395,0.246,0.0157,4.9,0.076,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0240,a0240,Amazon Polygon 0240,-46.5,-2.5,NA,NA,2,8,0.366523568668258,0.366549613332243,0.016339490616958,4.55215271258003,0.08033462738003,1174.40768787318,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0241,a0241,Amazon Polygon 0241,-45.5,-2.5,NA,NA,2,8,0.412,0.291,0.0167,5,0.095,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0242,a0242,Amazon Polygon 0242,-44.5,-2.5,NA,NA,2,8,0.349,0.314,0.0197,5.1,0.148,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0243,a0243,Amazon Polygon 0243,-68.5,-1.5,NA,NA,2,3,0.583286919831224,0.191196905766526,0.0204880450070324,4.24838255977496,0.147434599156118,1174.75386779184,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0244,a0244,Amazon Polygon 0244,-67.5,-1.5,NA,NA,2,8,0.359,0.338,0.0251,4.3,0.14,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0245,a0245,Amazon Polygon 0245,-66.5,-1.5,NA,NA,2,6,0.484,0.261,0.0216,4.3,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0246,a0246,Amazon Polygon 0246,-65.5,-1.5,NA,NA,2,5,0.483153846153846,0.217,0.0222769230769231,4.3,0.101076923076923,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0247,a0247,Amazon Polygon 0247,-64.5,-1.5,NA,NA,2,5,0.332199570164771,0.226728347704738,0.0229433604016956,4.15299560886021,0.109355631266316,1140.07653008428,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0248,a0248,Amazon Polygon 0248,-63.5,-1.5,NA,NA,2,8,0.283137652629851,0.275732067246036,0.0222419811718623,4.10356431250998,0.126085245743094,1156.30507181702,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0249,a0249,Amazon Polygon 0249,-62.5,-1.5,NA,NA,2,8,0.278494276944493,0.278303735285365,0.0259597767751026,4.04693747670087,0.114247037965245,1161.43611359252,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0250,a0250,Amazon Polygon 0250,-61.5,-1.5,NA,NA,2,8,0.293022662889518,0.344461756373938,0.0409393767705382,4.03371104815864,0.137597733711048,1130.22662889518,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0251,a0251,Amazon Polygon 0251,-60.5,-1.5,NA,NA,2,8,0.306637396681003,0.37073806896197,0.0180052615048106,4.13085875382976,0.0963526754981705,1179.21859014325,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0252,a0252,Amazon Polygon 0252,-59.5,-1.5,NA,NA,2,16,0.300556308615255,0.401741069547032,0.0184511341679462,4.21649253416002,0.0842416870038793,1174.29416581795,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0253,a0253,Amazon Polygon 0253,-58.5,-1.5,NA,NA,2,17,0.249196236234406,0.409889027806853,0.0169219522241721,4.25042630421649,0.0909396671003949,1176.75135849828,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0254,a0254,Amazon Polygon 0254,-57.5,-1.5,NA,NA,2,8,0.353953296510074,0.356318795150176,0.0162318951959305,4.16127921138137,0.0921185700147406,1169.03315845088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0255,a0255,Amazon Polygon 0255,-56.5,-1.5,NA,NA,2,8,0.428561397205884,0.357890819191029,0.0170443708892477,4.07668184177044,0.102229315858188,1172.03342349047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0256,a0256,Amazon Polygon 0256,-55.5,-1.5,NA,NA,2,8,0.394724258319037,0.285435050554816,0.0174574132596345,4.58042111599446,0.120983760700622,1140.94614837231,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0257,a0257,Amazon Polygon 0257,-54.5,-1.5,NA,NA,2,6,0.453466860183841,0.30700145137881,0.0147157232704403,4.44944363812288,0.0934358974358974,1168.24383164006,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0258,a0258,Amazon Polygon 0258,-53.5,-1.5,NA,NA,2,8,0.358051985792703,0.375059412334517,0.0217846625766871,4.69667420083952,0.102369066838876,1149.43816596706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0259,a0259,Amazon Polygon 0259,-52.5,-1.5,NA,NA,2,6,0.489193198804185,0.267949177877429,0.0144534379671151,4.48789237668161,0.104897608370703,1180.63153961136,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0260,a0260,Amazon Polygon 0260,-51.5,-1.5,NA,NA,2,8,0.4179221017771,0.328776241876915,0.0169746115109358,4.50445071598713,0.105085291270001,1176.97838613175,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0261,a0261,Amazon Polygon 0261,-50.5,-1.5,NA,NA,2,6,0.547492846393835,0.282247721731745,0.0208268214779869,4.51611375009776,0.101198815924279,1198.09744113304,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0262,a0262,Amazon Polygon 0262,-49.5,-1.5,NA,NA,2,6,0.4680421384336,0.314970467602685,0.0255416866979813,4.57188082717456,0.127847153682839,1192.2391132314,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0263,a0263,Amazon Polygon 0263,-48.5,-1.5,NA,NA,2,8,0.391037326388889,0.327946180555556,0.0201565972222222,4.671875,0.141463541666667,1194.19270833333,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0264,a0264,Amazon Polygon 0264,-47.5,-1.5,NA,NA,2,5,0.383,0.249,0.0161,4.9,0.102,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0265,a0265,Amazon Polygon 0265,-46.5,-1.5,NA,NA,2,5,0.365,0.271,0.0168,4.9,0.107,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0266,a0266,Amazon Polygon 0266,-45.5,-1.5,NA,NA,2,8,0.372681588447653,0.363571119133574,0.0232038989169675,4.83451263537906,0.140849097472924,1191.12635379061,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0267,a0267,Amazon Polygon 0267,-69.5,-0.5,NA,NA,2,6,0.513583189169413,0.245977740531898,0.0276737157238781,4.58843583440703,0.12858002948712,1194.93803226348,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0268,a0268,Amazon Polygon 0268,-68.5,-0.5,NA,NA,2,3,0.600080368544563,0.184909434794784,0.0266536832169823,4.45450123700453,0.13408238057271,1160.05935057225,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0269,a0269,Amazon Polygon 0269,-67.5,-0.5,NA,NA,2,6,0.497991462671745,0.274257998162199,0.0237007313136071,4.41340109443275,0.129521088572825,1136.4929430812,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0270,a0270,Amazon Polygon 0270,-66.5,-0.5,NA,NA,2,6,0.487163751757489,0.259332591217498,0.0247852706061505,4.28013241098742,0.11444026279783,1143.40517343133,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0271,a0271,Amazon Polygon 0271,-65.5,-0.5,NA,NA,2,5,0.479092105263158,0.217730263157895,0.0217730263157895,4.2,0.0977763157894737,1173.88157894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0272,a0272,Amazon Polygon 0272,-64.5,-0.5,NA,NA,2,5,0.472669608463471,0.249291511524267,0.02087983621479,4.13056551181114,0.106210734138445,1160.99596029531,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0273,a0273,Amazon Polygon 0273,-63.5,-0.5,NA,NA,2,6,0.46518007761852,0.262138086454371,0.0250127829843773,4.11123340189234,0.11280515756391,1155.37493870311,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0274,a0274,Amazon Polygon 0274,-62.5,-0.5,NA,NA,2,8,0.399849910285365,0.303517220341941,0.0301553996969191,4.09137312319897,0.116908159627452,1150.9291358209,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0275,a0275,Amazon Polygon 0275,-61.5,-0.5,NA,NA,2,8,0.401,0.296,0.0293,4.1,0.121,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0276,a0276,Amazon Polygon 0276,-60.5,-0.5,NA,NA,2,8,0.43759229436722,0.327765854198416,0.0239312319665031,4.07425046342091,0.103975187414491,1182.26604116517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0277,a0277,Amazon Polygon 0277,-59.5,-0.5,NA,NA,2,17,0.239715351812367,0.418997334754797,0.0188569829424307,4.20442430703625,0.0887681236673774,1185.07995735608,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0278,a0278,Amazon Polygon 0278,-58.5,-0.5,NA,NA,2,8,0.232,0.367,0.017,4.2,0.091,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0279,a0279,Amazon Polygon 0279,-57.5,-0.5,NA,NA,2,8,0.281511182108626,0.395685126020589,0.020892225772098,4.02744053958112,0.0987724529641463,1147.54348597799,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0280,a0280,Amazon Polygon 0280,-56.5,-0.5,NA,NA,2,8,0.333425168387214,0.385573036348581,0.0181079429907979,4.08479599600034,0.111452773708574,1167.16959626952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0281,a0281,Amazon Polygon 0281,-55.5,-0.5,NA,NA,2,8,0.367863167567993,0.389374358579361,0.0202798785670844,4.13969965062452,0.111505103338343,1159.92937182343,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0282,a0282,Amazon Polygon 0282,-54.5,-0.5,NA,NA,2,8,0.338900020480741,0.347237539346446,0.024187092972358,4.39643822949762,0.105208915705631,1174.61851509937,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0283,a0283,Amazon Polygon 0283,-53.5,-0.5,NA,NA,2,8,0.355,0.28,0.0153,4.5,0.098,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0284,a0284,Amazon Polygon 0284,-52.5,-0.5,NA,NA,2,8,0.339034131922173,0.374604688011251,0.0156990635612464,4.42961377701112,0.103277610183329,1204.46796846706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0285,a0285,Amazon Polygon 0285,-51.5,-0.5,NA,NA,2,8,0.372166159029789,0.380014992408354,0.0220836014901674,4.63160218234417,0.146076665566285,1177.6541729892,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0286,a0286,Amazon Polygon 0286,-50.5,-0.5,NA,NA,2,6,0.487482056944867,0.322890399180772,0.0234138451341345,4.56961782065618,0.120102198797205,1192.29829864262,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0287,a0287,Amazon Polygon 0287,-49.5,-0.5,NA,NA,2,5,0.4075,0.242,0.0301,5,0.17,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0288,a0288,Amazon Polygon 0288,-48.5,-0.5,NA,NA,2,8,0.410034389140271,0.337929411764706,0.0235811764705882,4.7020814479638,0.14496742081448,1174.00904977376,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0289,a0289,Amazon Polygon 0289,-69.5,0.5,NA,NA,2,6,0.518,0.244,0.024,4.5,0.124,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0290,a0290,Amazon Polygon 0290,-68.5,0.5,NA,NA,2,6,0.556031275302543,0.213491255142449,0.0269094765332795,4.77052293091954,0.128356794829367,1199.06133779691,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0291,a0291,Amazon Polygon 0291,-67.5,0.5,NA,NA,2,6,0.531345964496635,0.243997191584387,0.0252805275869034,4.58959693238905,0.12274820262963,1138.82061016445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0292,a0292,Amazon Polygon 0292,-66.5,0.5,NA,NA,2,6,0.548215196717419,0.224407028928467,0.0271229074631325,4.43939775224795,0.109745421821456,1113.94872134619,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0293,a0293,Amazon Polygon 0293,-65.5,0.5,NA,NA,2,6,0.484765179678734,0.256514100828391,0.0282823256655113,4.14867339135671,0.114060992235232,1143.58311648962,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0294,a0294,Amazon Polygon 0294,-64.5,0.5,NA,NA,2,6,0.487010403492551,0.258904649364713,0.0268010597810063,4.10729350353887,0.118673620957919,1124.26391973434,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0295,a0295,Amazon Polygon 0295,-63.5,0.5,NA,NA,2,5,0.490013881177124,0.223543586896169,0.0233667962243198,4.29244863964464,0.111192670738479,1171.7157134925,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0296,a0296,Amazon Polygon 0296,-62.5,0.5,NA,NA,2,6,0.483,0.261,0.0177,4.8,0.127,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0297,a0297,Amazon Polygon 0297,-61.5,0.5,NA,NA,2,6,0.490005479452055,0.286574429223744,0.0155687671232877,4.6,0.115645662100457,1239.25114155251,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0298,a0298,Amazon Polygon 0298,-60.5,0.5,NA,NA,2,8,0.422827388919844,0.29860800842063,0.0148668648048191,4.45877357340052,0.10206694774671,1226.64877103883,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0299,a0299,Amazon Polygon 0299,-59.5,0.5,NA,NA,2,8,0.35218276921012,0.332975825521394,0.0176846653881449,4.36719699243703,0.103102231226806,1209.98824400904,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0300,a0300,Amazon Polygon 0300,-58.5,0.5,NA,NA,2,8,0.363830388886367,0.307647710465354,0.0175809224486845,4.43911678729251,0.103051225392196,1189.58270236001,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0301,a0301,Amazon Polygon 0301,-57.5,0.5,NA,NA,2,8,0.354931842769564,0.343516768842409,0.0181821853588172,4.35708618824378,0.100027046520014,1219.78723404255,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0302,a0302,Amazon Polygon 0302,-56.5,0.5,NA,NA,2,8,0.377,0.279,0.0156,4.5,0.098,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0303,a0303,Amazon Polygon 0303,-55.5,0.5,NA,NA,2,8,0.35,0.292,0.0178,4.5,0.1,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0304,a0304,Amazon Polygon 0304,-54.5,0.5,NA,NA,2,8,0.326,0.309,0.0184,4.5,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0305,a0305,Amazon Polygon 0305,-53.5,0.5,NA,NA,2,8,0.323365210127657,0.370095805707387,0.0187482045535554,4.48093786377005,0.0996940546590494,1195.62742007063,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0306,a0306,Amazon Polygon 0306,-52.5,0.5,NA,NA,2,8,0.292867015931683,0.397491722254934,0.0192186303907941,4.4352519463437,0.103649205072188,1202.97149068891,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0307,a0307,Amazon Polygon 0307,-51.5,0.5,NA,NA,2,8,0.354676744608013,0.342080412276782,0.0198860758037557,4.59291576539618,0.104769497337053,1216.29109710547,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0308,a0308,Amazon Polygon 0308,-69.5,1.5,NA,NA,2,6,0.526,0.24,0.024,4.5,0.097,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0309,a0309,Amazon Polygon 0309,-68.5,1.5,NA,NA,2,6,0.52253906795127,0.205054553070751,0.0427814812837994,4.66687109294238,0.126099018640665,1194.61921079365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0310,a0310,Amazon Polygon 0310,-67.5,1.5,NA,NA,2,6,0.561091043671355,0.20421021465581,0.0270715025906736,4.8,0.125521835677276,1167.21687638786,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0311,a0311,Amazon Polygon 0311,-63.5,1.5,NA,NA,2,8,0.42494387755102,0.300469023323615,0.0162231413994169,4.46344752186589,0.11184584548105,1160.36807580175,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0312,a0312,Amazon Polygon 0312,-62.5,1.5,NA,NA,2,5,0.461726939264444,0.258288962317539,0.0154604370768904,4.66603356058363,0.108984270747554,1194.30671490346,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0313,a0313,Amazon Polygon 0313,-61.5,1.5,NA,NA,2,6,0.491579346398351,0.244625519219408,0.0134864468276648,4.76323965635835,0.117913015594765,1223.94573462479,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0314,a0314,Amazon Polygon 0314,-60.5,1.5,NA,NA,2,6,0.504332049917661,0.253297503740243,0.0135588157703226,4.78218311497323,0.0964585250071972,1215.72461292972,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0315,a0315,Amazon Polygon 0315,-59.5,1.5,NA,NA,2,6,0.481927994873695,0.255205541384766,0.0150356642601167,4.74670830089643,0.103511291584974,1207.44096428706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0316,a0316,Amazon Polygon 0316,-57.5,1.5,NA,NA,2,8,0.320494450050454,0.381883955600404,0.0240853683148335,4.43296333669694,0.130706020854356,1230.91153716784,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0317,a0317,Amazon Polygon 0317,-56.5,1.5,NA,NA,2,8,0.379,0.278,0.0166,4.6,0.102,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0318,a0318,Amazon Polygon 0318,-55.5,1.5,NA,NA,2,5,0.392,0.263,0.0161,4.6,0.101,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0319,a0319,Amazon Polygon 0319,-54.5,1.5,NA,NA,2,8,0.350395925297114,0.379331069609508,0.0170010526315789,4.57011884550085,0.100765365025467,1205.64006791171,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0320,a0320,Amazon Polygon 0320,-53.5,1.5,NA,NA,2,8,0.33561267805929,0.378876602523137,0.017076443885941,4.53922886608355,0.0972183506159432,1210.01906683005,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0321,a0321,Amazon Polygon 0321,-52.5,1.5,NA,NA,2,8,0.335149100257069,0.374988982739625,0.0183976496511201,4.54168196841719,0.117102093279471,1219.54829232464,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0322,a0322,Amazon Polygon 0322,-51.5,1.5,NA,NA,2,8,0.342559043915282,0.375207384619859,0.0198429336435915,4.53589145059832,0.111399201408253,1218.60642701711,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0323,a0323,Amazon Polygon 0323,-50.5,1.5,NA,NA,2,8,0.334285904255319,0.309539893617021,0.0247304521276596,4.85345744680851,0.195167553191489,747.114361702128,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0324,a0324,Amazon Polygon 0324,-63.5,2.5,NA,NA,2,5,0.394,0.267,0.0229,4.2,0.106,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0325,a0325,Amazon Polygon 0325,-62.5,2.5,NA,NA,2,8,0.373555616051848,0.347475527485543,0.0166705535882847,4.47090601554171,0.110173448007595,1154.31042803282,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0326,a0326,Amazon Polygon 0326,-61.5,2.5,NA,NA,2,6,0.474488977350501,0.284508323716426,0.0158915215631065,4.71459515869303,0.0970353676585795,1191.61066134685,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0327,a0327,Amazon Polygon 0327,-60.5,2.5,NA,NA,2,6,0.595486028789162,0.217139712108383,0.0127133361558002,4.97417442845047,0.0982561388653683,1264.29297205758,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0328,a0328,Amazon Polygon 0328,-52.5,2.5,NA,NA,2,8,0.363187161639598,0.365375870069606,0.0310636117556071,4.62965970610982,0.129161252900232,1214.36194895592,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0329,a0329,Amazon Polygon 0329,-51.5,2.5,NA,NA,2,8,0.357012872350827,0.354746872110307,0.0213451569559534,4.58902910482537,0.143151406767849,1205.39553680222,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0330,a0330,Amazon Polygon 0330,-63.5,3.5,NA,NA,2,8,0.361,0.281,0.0224,4.1,0.117,1120,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0331,a0331,Amazon Polygon 0331,-62.5,3.5,NA,NA,2,8,0.346073414671842,0.369487859609459,0.0177165198541867,4.37372537735457,0.10968214765377,1131.10602529551,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0332,a0332,Amazon Polygon 0332,-61.5,3.5,NA,NA,2,6,0.479615694573823,0.293875810816361,0.0152221313921233,4.85439423856933,0.110973840211288,1214.41237963628,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0333,a0333,Amazon Polygon 0333,-60.5,3.5,NA,NA,2,6,0.498,0.26,0.0101,5.3,0.153,1320,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0334,a0334,Amazon Polygon 0334,-51.5,3.5,NA,NA,2,8,0.359,0.366,0.0225,4.6,0.123,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0335,a0335,Amazon Polygon 0335,-60.5,4.5,NA,NA,2,5,0.442668521094112,0.255291608715809,0.0228799258229022,5.36764024107557,0.13246314325452,1224.35790449699,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0336,a0336,Amazon Polygon 0336,-59.5,-11.5,NA,NA,2,6,0.531965811840757,0.243728325972639,0.0187127669238973,4.4686539658477,0.108225292926799,1211.32454358169,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0337,a0337,Amazon Polygon 0337,-58.5,-12.5,NA,NA,2,3,0.754084244600303,0.15137239297781,0.0138599813936637,4.61700499339524,0.094790242484175,1221.66075690442,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0338,a0338,Amazon Polygon 0338,-51.5,-12.5,NA,NA,2,6,0.604934210526316,0.241301619433198,0.0233360829959514,4.81376518218624,0.092747975708502,1230.43016194332,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0339,a0339,Amazon Polygon 0339,-54.5,-13.5,NA,NA,2,6,0.604719512195122,0.254965447154472,0.0216197154471545,4.8,0.106475609756098,1225.91463414634,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0340,a0340,Amazon Polygon 0340,-46.5,-5.5,NA,NA,2,6,0.568910083727703,0.251582089552239,0.0157911175828176,4.90910083727703,0.0982085911903895,1276.40698944303,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0341,a0341,Amazon Polygon 0341,-59.5,-12.5,NA,NA,2,3,0.668453719723183,0.181541522491349,0.0159257352941176,4.6780276816609,0.103732698961938,1216.35813148789,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0342,a0342,Amazon Polygon 0342,-59.5,-13.5,NA,NA,2,3,0.699488842211707,0.186988779988865,0.0157302321721259,4.91277867918269,0.087079116612656,1214.97471074384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0343,a0343,Amazon Polygon 0343,-53.5,-13.5,NA,NA,2,6,0.556761283851555,0.280124373119358,0.0183568706118355,5.03019057171515,0.0786880641925777,1240.33099297894,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0344,a0344,Amazon Polygon 0344,-53.5,2.5,NA,NA,2,8,0.307401814058957,0.396586848072562,0.0224716553287982,4.62208616780045,0.108532426303855,1201.46031746032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0345,a0345,Amazon Polygon 0345,-73.5,-6.5,NA,NA,2,8,0.38418927140332,0.323272575377048,0.0253926179596497,4.18006928075437,0.134395888997171,1213.40132840139,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0346,a0346,Amazon Polygon 0346,-65.5,-11.5,NA,NA,2,8,0.436925311203319,0.291680497925311,0.0164742738589212,4.73112033195021,0.10660857538036,1211.53526970954,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0347,a0347,Amazon Polygon 0347,-69.5,-1.5,NA,NA,2,3,0.566508552631579,0.187552631578947,0.02448125,4.32605263157895,0.137514473684211,1178.75657894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0348,a0348,Amazon Polygon 0348,-59.5,4.5,NA,NA,2,8,0.41111091393079,0.277334516415262,0.0196432120674357,5.4318544809228,0.129808340727595,1221.20674356699,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0349,a0349,Amazon Polygon 0349,-50.5,-10.5,NA,NA,2,6,0.568891694352159,0.229058803986711,0.025399634551495,4.89614617940199,0.106660465116279,1234.76079734219,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0350,a0350,Amazon Polygon 0350,-50.5,0.5,NA,NA,2,8,0.339461871069182,0.341968553459119,0.0205159591194969,4.81088836477987,0.145310927672956,1209.13128930818,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 diff --git a/R-utils/amzif_poi.csv b/R-utils/amzif_poi.csv new file mode 100644 index 000000000..3b569db43 --- /dev/null +++ b/R-utils/amzif_poi.csv @@ -0,0 +1,351 @@ +short,iata,longname,lon,lat,alt,wmo,isoilflg,istext,sand,clay,slsoc,slph,slcec,sldbd,depth,isoilbc,sldrain,scolour,met.driver,yeara,yearz,iphen,iage +AMZIF_0001,i0001,Amazon Intact 0001,-61.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0002,i0002,Amazon Intact 0002,-60.5,-13.5,NA,NA,2,3,0.614,0.173,0.0179,5.2,0.099,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0003,i0003,Amazon Intact 0003,-63.5,-12.5,NA,NA,2,6,0.495,0.262,0.016,5,0.086,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0004,i0004,Amazon Intact 0004,-62.5,-12.5,NA,NA,2,6,0.532827158181877,0.223343203931085,0.0151842159320799,4.81890525820088,0.0924997073894,1223.15593565532,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0005,i0005,Amazon Intact 0005,-61.5,-12.5,NA,NA,2,6,0.450731520182141,0.306403635818869,0.0183703078468289,4.88934097681909,0.0847669342966816,1220.75569914233,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0006,i0006,Amazon Intact 0006,-60.5,-12.5,NA,NA,2,3,0.612,0.161,0.017,5,0.083,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0007,i0007,Amazon Intact 0007,-57.5,-12.5,NA,NA,2,3,0.688,0.106,0.0165,4.5,0.101,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0008,i0008,Amazon Intact 0008,-56.5,-12.5,NA,NA,2,3,0.606,0.148,0.0193,4.8,0.119,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0009,i0009,Amazon Intact 0009,-55.5,-12.5,NA,NA,2,3,0.589,0.157,0.0202,4.9,0.103,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0010,i0010,Amazon Intact 0010,-54.5,-12.5,NA,NA,2,6,0.588931216931217,0.262272927689594,0.0225351851851852,4.77416225749559,0.0949766313932981,1217.7557319224,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0011,i0011,Amazon Intact 0011,-53.5,-12.5,NA,NA,2,6,0.599319673617407,0.255952493200363,0.0254086854034451,4.85642792384406,0.0997787851314597,1223.12420670898,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0012,i0012,Amazon Intact 0012,-52.5,-12.5,NA,NA,2,6,0.612817371143214,0.240545211342964,0.0232944533618691,4.87788478687355,0.0945580524344569,1232.01533797039,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0013,i0013,Amazon Intact 0013,-64.5,-11.5,NA,NA,2,6,0.479828543080773,0.284419945311968,0.0166047393115583,4.81936043008105,0.100291496056211,1195.82545471844,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0014,i0014,Amazon Intact 0014,-63.5,-11.5,NA,NA,2,6,0.485,0.257,0.0158,4.9,0.106,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0015,i0015,Amazon Intact 0015,-62.5,-11.5,NA,NA,2,6,0.501,0.249,0.0156,4.8,0.097,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0016,i0016,Amazon Intact 0016,-61.5,-11.5,NA,NA,2,6,0.523848657024793,0.226321280991736,0.0169982954545455,4.49927685950413,0.124055785123967,1184.70041322314,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0017,i0017,Amazon Intact 0017,-60.5,-11.5,NA,NA,2,6,0.497783881692461,0.240416956240693,0.0196677284365722,4.45150152401207,0.126352349579395,1200.16621915694,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0018,i0018,Amazon Intact 0018,-58.5,-11.5,NA,NA,2,3,0.693155778355077,0.173519040956307,0.0190220585730911,4.49683832001874,0.093880134066002,1204.17132873688,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0019,i0019,Amazon Intact 0019,-57.5,-11.5,NA,NA,2,3,0.645,0.148,0.0169,4.6,0.108,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0020,i0020,Amazon Intact 0020,-56.5,-11.5,NA,NA,2,3,0.604,0.168,0.0182,4.6,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0021,i0021,Amazon Intact 0021,-55.5,-11.5,NA,NA,2,3,0.569,0.193,0.0185,4.6,0.094,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0022,i0022,Amazon Intact 0022,-54.5,-11.5,NA,NA,2,6,0.492119074281448,0.276775662560657,0.0195657334826428,4.45733482642777,0.0928402388951101,1212.03807390817,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0023,i0023,Amazon Intact 0023,-53.5,-11.5,NA,NA,2,6,0.556383399980493,0.248132351506876,0.0224636399102702,4.54969277284697,0.106959816639032,1202.66068467766,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0024,i0024,Amazon Intact 0024,-52.5,-11.5,NA,NA,2,6,0.590901915708812,0.240373946360153,0.0237653256704981,4.7,0.0953348659003831,1219.11111111111,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0025,i0025,Amazon Intact 0025,-51.5,-11.5,NA,NA,2,3,0.577,0.185,0.0223,5,0.098,1280,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0026,i0026,Amazon Intact 0026,-70.5,-10.5,NA,NA,2,5,0.268586573884568,0.273290216946377,0.0155534588620549,5.11150225133033,0.137365534179288,1232.50511665984,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0027,i0027,Amazon Intact 0027,-69.5,-10.5,NA,NA,2,5,0.255309546902415,0.270967242632211,0.0138333107995789,4.98478570186679,0.108638683442099,1228.99132282708,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0028,i0028,Amazon Intact 0028,-68.5,-10.5,NA,NA,2,8,0.406,0.381,0.0143,4.8,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0029,i0029,Amazon Intact 0029,-67.5,-10.5,NA,NA,2,8,0.35,0.376,0.01775,4.9,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0030,i0030,Amazon Intact 0030,-64.5,-10.5,NA,NA,2,6,0.529973709369025,0.283845602294455,0.0171866156787763,4.35984703632887,0.100737571701721,1192.34703632887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0031,i0031,Amazon Intact 0031,-63.5,-10.5,NA,NA,2,8,0.432643394648829,0.299053929765886,0.0166405936454849,4.67403846153846,0.112194816053512,1210.72324414716,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0032,i0032,Amazon Intact 0032,-62.5,-10.5,NA,NA,2,6,0.494,0.243,0.016,4.7,0.105,1260,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0033,i0033,Amazon Intact 0033,-61.5,-10.5,NA,NA,2,6,0.49244186594181,0.238797371096574,0.014983443469425,4.43026238832619,0.111291163568836,1186.34065867886,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0034,i0034,Amazon Intact 0034,-60.5,-10.5,NA,NA,2,6,0.491073476702509,0.23670394265233,0.01958,4.50075268817204,0.163920788530466,1192.56630824373,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0035,i0035,Amazon Intact 0035,-59.5,-10.5,NA,NA,2,5,0.461174165897482,0.210466248712498,0.0178801675803811,4.24772576654593,0.127716360263101,1188.02454954436,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0036,i0036,Amazon Intact 0036,-58.5,-10.5,NA,NA,2,6,0.496,0.262,0.0189,4.4,0.113,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0037,i0037,Amazon Intact 0037,-57.5,-10.5,NA,NA,2,6,0.512,0.238,0.0209,4.6,0.144,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0038,i0038,Amazon Intact 0038,-56.5,-10.5,NA,NA,2,6,0.502,0.251,0.0217,4.7,0.118,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0039,i0039,Amazon Intact 0039,-55.5,-10.5,NA,NA,2,6,0.505,0.253,0.0235,4.7,0.103,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0040,i0040,Amazon Intact 0040,-54.5,-10.5,NA,NA,2,8,0.436,0.299,0.0229,4.7,0.107,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0041,i0041,Amazon Intact 0041,-53.5,-10.5,NA,NA,2,5,0.402522463234624,0.243850803832543,0.025400373492383,4.59887601936764,0.150494617704104,1194.2512709253,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0042,i0042,Amazon Intact 0042,-52.5,-10.5,NA,NA,2,5,0.399637471243974,0.242709380581886,0.0238326686745709,4.72583446003614,0.150625690337864,1210.92894080837,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0043,i0043,Amazon Intact 0043,-51.5,-10.5,NA,NA,2,6,0.549,0.238,0.0247,5,0.104,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0044,i0044,Amazon Intact 0044,-71.5,-9.5,NA,NA,2,11,0.281,0.455,0.017,5.3,0.14,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0045,i0045,Amazon Intact 0045,-70.5,-9.5,NA,NA,2,5,0.305348457483086,0.261165160140003,0.0162451771355698,5.03126122777269,0.137244831040208,1230.80489335802,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0046,i0046,Amazon Intact 0046,-69.5,-9.5,NA,NA,2,7,0.179644132168629,0.313389669578428,0.0173817698442841,4.66532472464869,0.112062666160273,1175.17280668439,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0047,i0047,Amazon Intact 0047,-68.5,-9.5,NA,NA,2,11,0.247,0.466,0.0157,4.5,0.1,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0048,i0048,Amazon Intact 0048,-67.5,-9.5,NA,NA,2,17,0.294,0.401,0.016,4.4,0.103,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0049,i0049,Amazon Intact 0049,-66.5,-9.5,NA,NA,2,8,0.390965537390559,0.326264148863619,0.0155160579886473,4.10831258032794,0.110196527696416,1181.08181612982,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0050,i0050,Amazon Intact 0050,-65.5,-9.5,NA,NA,2,6,0.502480310179564,0.292924625920026,0.0149670508436175,4.08581239331415,0.0987440934990041,1196.04507161374,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0051,i0051,Amazon Intact 0051,-64.5,-9.5,NA,NA,2,6,0.494187799505387,0.312813945287714,0.0149187115745389,4.11208667279386,0.106490502680508,1191.6781646651,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0052,i0052,Amazon Intact 0052,-63.5,-9.5,NA,NA,2,5,0.422,0.228,0.0154,4.2,0.112,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0053,i0053,Amazon Intact 0053,-62.5,-9.5,NA,NA,2,6,0.526723673792557,0.304761678543151,0.0146926365795724,4.13927157561362,0.135636579572447,1158.82026920032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0054,i0054,Amazon Intact 0054,-61.5,-9.5,NA,NA,2,6,0.475837709065701,0.29394519942737,0.015715992691971,4.3700175457831,0.116479974835913,1164.29444036872,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0055,i0055,Amazon Intact 0055,-60.5,-9.5,NA,NA,2,5,0.442820171430543,0.255906432266955,0.0147556308949299,4.41158322892077,0.11992612198258,1187.18252216066,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0056,i0056,Amazon Intact 0056,-59.5,-9.5,NA,NA,2,8,0.436,0.293,0.0156,4.4,0.119,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0057,i0057,Amazon Intact 0057,-58.5,-9.5,NA,NA,2,8,0.426,0.303,0.0174,4.5,0.109,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0058,i0058,Amazon Intact 0058,-57.5,-9.5,NA,NA,2,8,0.415,0.282,0.0209,4.5,0.116,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0059,i0059,Amazon Intact 0059,-56.5,-9.5,NA,NA,2,6,0.473,0.254,0.022,4.6,0.115,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0060,i0060,Amazon Intact 0060,-55.5,-9.5,NA,NA,2,8,0.361656974459725,0.309918271119843,0.0260042043222004,4.72495088408644,0.127231827111984,1144.39685658153,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0061,i0061,Amazon Intact 0061,-54.5,-9.5,NA,NA,2,8,0.349,0.362,0.025,4.7,0.11,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0062,i0062,Amazon Intact 0062,-53.5,-9.5,NA,NA,2,5,0.349855406244037,0.264574030049878,0.0247361279049624,4.79534808484788,0.114095044355591,1180.68561139773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0063,i0063,Amazon Intact 0063,-52.5,-9.5,NA,NA,2,5,0.33865035510691,0.261535925271796,0.0256825678221337,4.87961449338954,0.129706389892549,1199.54266478572,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0064,i0064,Amazon Intact 0064,-51.5,-9.5,NA,NA,2,6,0.498,0.268,0.0245,4.9,0.104,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0065,i0065,Amazon Intact 0065,-50.5,-9.5,NA,NA,2,6,0.507,0.274,0.0237,4.8,0.096,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0066,i0066,Amazon Intact 0066,-72.5,-8.5,NA,NA,2,8,0.308196101665935,0.278748366544917,0.0183815152392838,4.86620001626734,0.134061153724777,1229.3862292831,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0067,i0067,Amazon Intact 0067,-71.5,-8.5,NA,NA,2,8,0.264883241943049,0.300300623375535,0.0162334923811684,5.03047408913002,0.119286187412714,1219.72116159341,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0068,i0068,Amazon Intact 0068,-70.5,-8.5,NA,NA,2,11,0.235,0.473,0.0154,4.7,0.125,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0069,i0069,Amazon Intact 0069,-69.5,-8.5,NA,NA,2,17,0.195,0.475,0.0187,4.5,0.129,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0070,i0070,Amazon Intact 0070,-68.5,-8.5,NA,NA,2,8,0.284172835164074,0.310147088504925,0.0167848071918792,4.19720324027838,0.125654576915696,1182.77061513042,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0071,i0071,Amazon Intact 0071,-67.5,-8.5,NA,NA,2,8,0.292415094339623,0.280952830188679,0.0174801886792453,4.00471698113208,0.128358490566038,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0072,i0072,Amazon Intact 0072,-66.5,-8.5,NA,NA,2,5,0.333994414551417,0.273713230915524,0.0166014804391806,4.00638898330226,0.124824917685918,1182.2743102262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0073,i0073,Amazon Intact 0073,-65.5,-8.5,NA,NA,2,5,0.391689886228156,0.270636335410864,0.016295352637965,4.07896382826861,0.126661592497729,1179.22209455998,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0074,i0074,Amazon Intact 0074,-64.5,-8.5,NA,NA,2,8,0.275761382799325,0.305858347386172,0.0152971753794266,4.03537099494098,0.131158094435076,1168.42327150084,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0075,i0075,Amazon Intact 0075,-63.5,-8.5,NA,NA,2,5,0.44463884957865,0.229491292024114,0.0159032543220568,4.10166668675833,0.137151642422065,1157.3308357903,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0076,i0076,Amazon Intact 0076,-62.5,-8.5,NA,NA,2,6,0.485391852708602,0.303511448010119,0.0159982613780063,4.07286673656322,0.142600464137334,1155.32594619365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0077,i0077,Amazon Intact 0077,-61.5,-8.5,NA,NA,2,8,0.39032962633452,0.345288256227758,0.0164452846975089,4.03171708185053,0.159075622775801,1152.02846975089,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0078,i0078,Amazon Intact 0078,-60.5,-8.5,NA,NA,2,8,0.449616911764706,0.296716911764706,0.0162023897058824,4.20419117647059,0.125605882352941,1148.41544117647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0079,i0079,Amazon Intact 0079,-59.5,-8.5,NA,NA,2,8,0.430033564013841,0.302976124567474,0.0164828719723183,4.30847750865052,0.119707958477509,1179.83737024221,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0080,i0080,Amazon Intact 0080,-58.5,-8.5,NA,NA,2,8,0.394577675922117,0.296017847845743,0.0219717984785969,4.16831558112525,0.111375879436032,1158.48458933164,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0081,i0081,Amazon Intact 0081,-57.5,-8.5,NA,NA,2,8,0.315638539518452,0.296398497272827,0.0217040873252256,4.25230282100439,0.125653331708667,1186.68046425431,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0082,i0082,Amazon Intact 0082,-56.5,-8.5,NA,NA,2,6,0.483814907575956,0.273005780648467,0.020767937415412,4.37064210130148,0.124972786107768,1144.58596627468,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0083,i0083,Amazon Intact 0083,-55.5,-8.5,NA,NA,2,8,0.421587032842893,0.290319392737938,0.0241565207003981,4.52127644933888,0.126940318506445,1121.21486336916,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0084,i0084,Amazon Intact 0084,-54.5,-8.5,NA,NA,2,5,0.458282146473169,0.246636854539318,0.0201726628417145,4.65366182922713,0.111901788727641,1171.96085048937,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0085,i0085,Amazon Intact 0085,-53.5,-8.5,NA,NA,2,5,0.431616948300138,0.244417809042943,0.0215428077825752,4.86602068162482,0.112193635844849,1174.86039365359,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0086,i0086,Amazon Intact 0086,-52.5,-8.5,NA,NA,2,8,0.308990110529378,0.277067481093659,0.0239304828388598,4.89464805119255,0.109695753344968,1182.61780104712,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0087,i0087,Amazon Intact 0087,-51.5,-8.5,NA,NA,2,8,0.406,0.338,0.0222,4.9,0.108,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0088,i0088,Amazon Intact 0088,-50.5,-8.5,NA,NA,2,6,0.4685,0.295,0.0185,4.9,0.1,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0089,i0089,Amazon Intact 0089,-49.5,-8.5,NA,NA,2,8,0.431,0.339,0.0169,5,0.092,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0090,i0090,Amazon Intact 0090,-73.5,-7.5,NA,NA,2,8,0.391,0.324,0.0224,4.5,0.136,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0091,i0091,Amazon Intact 0091,-72.5,-7.5,NA,NA,2,5,0.444441610513001,0.204659918732888,0.0266572703059183,4.3666707129805,0.118013108343385,1215.66088118286,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0092,i0092,Amazon Intact 0092,-71.5,-7.5,NA,NA,2,5,0.386658737850952,0.272557957864953,0.0199268460635044,4.31066929344001,0.124357484483654,1219.21429426263,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0093,i0093,Amazon Intact 0093,-70.5,-7.5,NA,NA,2,5,0.366125589077417,0.253766524780332,0.0181243697535265,4.48917334601188,0.136852753442216,1221.44094531756,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0094,i0094,Amazon Intact 0094,-69.5,-7.5,NA,NA,2,8,0.253972444637277,0.312403365737154,0.0178998208380468,4.34265742362901,0.136120903769662,1182.20953369047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0095,i0095,Amazon Intact 0095,-68.5,-7.5,NA,NA,2,8,0.200743368179314,0.301632325090516,0.0172303795472488,4.22280023851364,0.137691803984821,1181.03801223613,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0096,i0096,Amazon Intact 0096,-67.5,-7.5,NA,NA,2,5,0.381922800638101,0.255151761226465,0.0196085375387342,4.09823179411313,0.135412690661849,1175.34945814459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0097,i0097,Amazon Intact 0097,-66.5,-7.5,NA,NA,2,5,0.348184485006519,0.23294035202086,0.024803520208605,4.04439374185137,0.191614732724902,1177.87157757497,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0098,i0098,Amazon Intact 0098,-65.5,-7.5,NA,NA,2,8,0.308420070011669,0.321481135744846,0.0307659665499806,3.96472189809413,0.169152080902373,1180.05056398289,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0099,i0099,Amazon Intact 0099,-64.5,-7.5,NA,NA,2,5,0.351106795659845,0.254051741535766,0.0203675119637823,4.07047266919123,0.136158306477854,1174.39542714777,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0100,i0100,Amazon Intact 0100,-63.5,-7.5,NA,NA,2,5,0.348967213114754,0.26909079445145,0.0190341740226986,4.06746532156368,0.141581336696091,1157.49054224464,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0101,i0101,Amazon Intact 0101,-62.5,-7.5,NA,NA,2,5,0.378444493006993,0.260364073426573,0.0191657342657343,3.94291958041958,0.134450174825175,1164.74213286713,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0102,i0102,Amazon Intact 0102,-61.5,-7.5,NA,NA,2,6,0.453149367351377,0.28299968276548,0.0227161959982204,3.88057940082181,0.151093734890761,1143.15157711345,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0103,i0103,Amazon Intact 0103,-60.5,-7.5,NA,NA,2,8,0.373584675406836,0.329590782847593,0.0207403994178037,3.96982038909162,0.145212434772781,1148.79399666279,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0104,i0104,Amazon Intact 0104,-59.5,-7.5,NA,NA,2,8,0.405411632262946,0.327696254382808,0.018126229491516,4.09238941624413,0.110656700148928,1151.25093690372,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0105,i0105,Amazon Intact 0105,-58.5,-7.5,NA,NA,2,8,0.428718387571201,0.29752014655824,0.0203812926641996,4.06013174998406,0.114318209045183,1142.86488831388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0106,i0106,Amazon Intact 0106,-57.5,-7.5,NA,NA,2,6,0.472673811569476,0.27488861900762,0.0187833172623552,4.1798953546306,0.11831492959481,1142.06634486178,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0107,i0107,Amazon Intact 0107,-56.5,-7.5,NA,NA,2,6,0.500921888020872,0.288057685256937,0.0208270270845811,4.2068280147721,0.12062062271103,1146.91242218899,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0108,i0108,Amazon Intact 0108,-55.5,-7.5,NA,NA,2,6,0.502766601941748,0.260951067961165,0.0187345242718447,4.44784466019418,0.126612815533981,1148.86990291262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0109,i0109,Amazon Intact 0109,-54.5,-7.5,NA,NA,2,8,0.448037156462829,0.279485268453837,0.0204603661946344,4.58734200570774,0.123710238224751,1141.20139248498,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0110,i0110,Amazon Intact 0110,-53.5,-7.5,NA,NA,2,5,0.405870414394448,0.272369805154135,0.023213342243383,4.74567721897063,0.121075053077005,1161.26218937101,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0111,i0111,Amazon Intact 0111,-52.5,-7.5,NA,NA,2,5,0.423161031407032,0.260672216314762,0.0215711442273108,4.91259080863187,0.123516537823892,1174.36324277597,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0112,i0112,Amazon Intact 0112,-51.5,-7.5,NA,NA,2,5,0.41030231838826,0.239494717325198,0.0220526448879972,4.92635660676482,0.126257567676888,1171.95394064303,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0113,i0113,Amazon Intact 0113,-50.5,-7.5,NA,NA,2,8,0.423,0.313,0.0219,4.9,0.105,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0114,i0114,Amazon Intact 0114,-49.5,-7.5,NA,NA,2,8,0.419,0.312,0.0186,5,0.091,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0115,i0115,Amazon Intact 0115,-72.5,-6.5,NA,NA,2,8,0.345939206079485,0.303633795622216,0.0243704137723336,4.17603294844803,0.150050279166451,1196.53872861361,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0116,i0116,Amazon Intact 0116,-71.5,-6.5,NA,NA,2,8,0.365716493645615,0.300526175467609,0.0226478336799038,4.22261301260796,0.147174307282635,1182.35775502717,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0117,i0117,Amazon Intact 0117,-70.5,-6.5,NA,NA,2,8,0.305412541254125,0.315392326732673,0.0216017326732673,4.21839933993399,0.150901402640264,1205.20627062706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0118,i0118,Amazon Intact 0118,-69.5,-6.5,NA,NA,2,8,0.34921965818152,0.289604052229818,0.0203178301890008,4.18135129314014,0.145573370106932,1184.21751984388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0119,i0119,Amazon Intact 0119,-68.5,-6.5,NA,NA,2,5,0.348604688763137,0.253696038803557,0.0206685529506871,4.08164915117219,0.167421180274859,1176.0064672595,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0120,i0120,Amazon Intact 0120,-67.5,-6.5,NA,NA,2,5,0.365728348805189,0.260591566985573,0.0227778287695533,4.02753760229251,0.14967491544859,1183.13628939597,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0121,i0121,Amazon Intact 0121,-66.5,-6.5,NA,NA,2,8,0.363994422005904,0.287466842724147,0.0256279680184059,4.03136513463336,0.162374574213007,1172.78109534152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0122,i0122,Amazon Intact 0122,-65.5,-6.5,NA,NA,2,8,0.289125427594071,0.328168757126568,0.0314795515013303,3.91022424933485,0.261543139490688,1155.68985176739,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0123,i0123,Amazon Intact 0123,-64.5,-6.5,NA,NA,2,8,0.249266584145497,0.284162360328903,0.020971189741879,4.08993166317843,0.14584038391267,1174.72197515196,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0124,i0124,Amazon Intact 0124,-63.5,-6.5,NA,NA,2,7,0.196579547290917,0.275370295899876,0.0199282736771132,4.11996596514939,0.150321114510502,1171.63357395483,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0125,i0125,Amazon Intact 0125,-62.5,-6.5,NA,NA,2,5,0.244662535410765,0.274032577903683,0.0191499291784703,4.13445467422096,0.117794971671388,1159.95042492918,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0126,i0126,Amazon Intact 0126,-61.5,-6.5,NA,NA,2,3,0.560114285714286,0.1922,0.0275228571428571,3.88285714285714,0.1474,1111.71428571429,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0127,i0127,Amazon Intact 0127,-60.5,-6.5,NA,NA,2,8,0.388485111813259,0.358129854186806,0.0245543343694118,3.92201855126991,0.129592882908742,1138.78255735462,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0128,i0128,Amazon Intact 0128,-59.5,-6.5,NA,NA,2,8,0.329346531302876,0.337793570219966,0.0191165143824027,4.04602368866328,0.109199323181049,1143.87140439932,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0129,i0129,Amazon Intact 0129,-58.5,-6.5,NA,NA,2,8,0.401046897022193,0.331684073736919,0.0208013602676036,4.02297069725274,0.107369580881748,1162.37055629501,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0130,i0130,Amazon Intact 0130,-57.5,-6.5,NA,NA,2,8,0.402082448308531,0.329085118646906,0.0205117771282756,4.05679704007993,0.120642426752595,1147.70319656278,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0131,i0131,Amazon Intact 0131,-56.5,-6.5,NA,NA,2,8,0.403477622136805,0.311749766298696,0.0207805693787863,4.07391789389225,0.135365797214032,1141.82167733301,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0132,i0132,Amazon Intact 0132,-55.5,-6.5,NA,NA,2,8,0.407,0.289,0.0207,4.2,0.127,1140,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0133,i0133,Amazon Intact 0133,-54.5,-6.5,NA,NA,2,5,0.472456509042975,0.232519024079735,0.0184966023346652,4.39294157816014,0.120887602741927,1139.14116702345,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0134,i0134,Amazon Intact 0134,-53.5,-6.5,NA,NA,2,5,0.433865380282771,0.260146140656473,0.020582968267837,4.68518820884446,0.114179586990585,1161.35344960581,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0135,i0135,Amazon Intact 0135,-52.5,-6.5,NA,NA,2,8,0.398,0.302,0.0219,4.7,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0136,i0136,Amazon Intact 0136,-51.5,-6.5,NA,NA,2,8,0.399,0.3,0.0223,4.7,0.11,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0137,i0137,Amazon Intact 0137,-50.5,-6.5,NA,NA,2,8,0.369625296536983,0.299049618502065,0.0250926362147123,4.83620161647673,0.117865077193322,1161.80329672384,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0138,i0138,Amazon Intact 0138,-49.5,-6.5,NA,NA,2,8,0.41,0.305,0.0195,4.9,0.102,1240,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0139,i0139,Amazon Intact 0139,-48.5,-6.5,NA,NA,2,8,0.438,0.295,0.0163,5,0.084,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0140,i0140,Amazon Intact 0140,-72.5,-5.5,NA,NA,2,8,0.316631318267378,0.293731070052168,0.0212564050324336,4.03435012014072,0.133540200221238,1204.23283989838,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0141,i0141,Amazon Intact 0141,-71.5,-5.5,NA,NA,2,8,0.261831067264059,0.331674853274107,0.0242969500923943,4.13961911542858,0.144168750466063,1175.89916503948,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0142,i0142,Amazon Intact 0142,-70.5,-5.5,NA,NA,2,8,0.343382487520799,0.321202787021631,0.0223361064891847,4.14968801996672,0.135537853577371,1182.25457570715,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0143,i0143,Amazon Intact 0143,-69.5,-5.5,NA,NA,2,8,0.274067385416902,0.372217615069417,0.0230286438385721,4.12630420864217,0.1318701219462,1184.8735444809,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0144,i0144,Amazon Intact 0144,-68.5,-5.5,NA,NA,2,8,0.376389945078158,0.339515842839037,0.0280085762568652,4.00566117448247,0.167994930291508,1190.59146599071,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0145,i0145,Amazon Intact 0145,-67.5,-5.5,NA,NA,2,8,0.356222727272727,0.306647159090909,0.0269543181818182,4.03232954545455,0.150550568181818,1144.60227272727,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0146,i0146,Amazon Intact 0146,-66.5,-5.5,NA,NA,2,8,0.371920323009405,0.315239792837457,0.0268064244874011,4.08748153937897,0.153513564625017,1163.25080116365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0147,i0147,Amazon Intact 0147,-65.5,-5.5,NA,NA,2,8,0.320175685557587,0.328858500914077,0.0264373126142596,4.2209689213894,0.152609140767825,1175.46252285192,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0148,i0148,Amazon Intact 0148,-64.5,-5.5,NA,NA,2,17,0.19,0.501,0.0244,4.1,0.15,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0149,i0149,Amazon Intact 0149,-63.5,-5.5,NA,NA,2,17,0.151,0.531,0.021,4.2,0.148,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0150,i0150,Amazon Intact 0150,-62.5,-5.5,NA,NA,2,7,0.162319696146735,0.283881096617385,0.02113330578884,4.10775040297384,0.137642820829614,1171.37074442068,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0151,i0151,Amazon Intact 0151,-61.5,-5.5,NA,NA,2,17,0.231,0.456,0.0193,4,0.114,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0152,i0152,Amazon Intact 0152,-60.5,-5.5,NA,NA,2,8,0.341970195896916,0.374434081407434,0.020952469499411,3.94210630242548,0.116940004238079,1151.01613736737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0153,i0153,Amazon Intact 0153,-59.5,-5.5,NA,NA,2,8,0.338,0.298,0.0169,4.1,0.111,1150,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0154,i0154,Amazon Intact 0154,-58.5,-5.5,NA,NA,2,8,0.367328599477271,0.346718543401378,0.0163035298076339,4.16878166280633,0.105175781723714,1141.87391642773,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0155,i0155,Amazon Intact 0155,-57.5,-5.5,NA,NA,2,8,0.357098701250047,0.3620339573164,0.0193660672959784,4.19626448101776,0.112960418923554,1149.06354993779,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0156,i0156,Amazon Intact 0156,-56.5,-5.5,NA,NA,2,8,0.34612741653184,0.3127191263931,0.0202685715388804,4.02263168324212,0.137436727117829,1138.13882752506,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0157,i0157,Amazon Intact 0157,-55.5,-5.5,NA,NA,2,8,0.278051742100947,0.33339098713427,0.0196052091300199,4.09188828089866,0.140839386752368,1140.87748074938,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0158,i0158,Amazon Intact 0158,-54.5,-5.5,NA,NA,2,8,0.39464608371322,0.283622461665976,0.0203793203481144,4.24243680066308,0.117186904268545,1158.15167840862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0159,i0159,Amazon Intact 0159,-53.5,-5.5,NA,NA,2,8,0.394302088079942,0.287042205311682,0.0185841949886112,4.44558374069444,0.104233757115698,1159.35239376196,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0160,i0160,Amazon Intact 0160,-52.5,-5.5,NA,NA,2,8,0.398610950414417,0.285193127551434,0.0168288526619137,4.49620860509732,0.0943560255317985,1160.68634924208,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0161,i0161,Amazon Intact 0161,-51.5,-5.5,NA,NA,2,8,0.422262532563853,0.301807108592407,0.0167985824585007,4.4886403343559,0.0944742243282384,1159.71514316469,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0162,i0162,Amazon Intact 0162,-50.5,-5.5,NA,NA,2,8,0.370207576953433,0.318092344119968,0.0235119968429361,4.78003157063931,0.117884767166535,1167.6637726914,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0163,i0163,Amazon Intact 0163,-49.5,-5.5,NA,NA,2,8,0.428,0.3,0.0182,4.7,0.096,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0164,i0164,Amazon Intact 0164,-48.5,-5.5,NA,NA,2,5,0.445,0.272,0.0158,4.9,0.084,1220,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0165,i0165,Amazon Intact 0165,-71.5,-4.5,NA,NA,2,17,0.172,0.46,0.0438,4.2,0.119,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0166,i0166,Amazon Intact 0166,-70.5,-4.5,NA,NA,2,7,0.180844339539162,0.326875672395628,0.0378916021208374,4.25120446069311,0.119021785409909,1183.58017266654,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0167,i0167,Amazon Intact 0167,-69.5,-4.5,NA,NA,2,8,0.273516734693878,0.343818775510204,0.0231362448979592,4.19681632653061,0.121054285714286,1186.53469387755,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0168,i0168,Amazon Intact 0168,-68.5,-4.5,NA,NA,2,8,0.342060798209623,0.358166728832525,0.0194925400969787,4.27907497202536,0.12147034688549,1193.32711674748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0169,i0169,Amazon Intact 0169,-67.5,-4.5,NA,NA,2,8,0.348771046735434,0.306365616648273,0.0239883688631256,4.10847593744122,0.141212122899216,1154.67484644238,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0170,i0170,Amazon Intact 0170,-66.5,-4.5,NA,NA,2,8,0.324960698490132,0.3012612351484,0.0265792256374342,4.20402743720121,0.142542745427422,1141.99287086459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0171,i0171,Amazon Intact 0171,-65.5,-4.5,NA,NA,2,8,0.282513583441138,0.297124838292367,0.0212324062095731,3.95873221216041,0.128265847347995,1179.42432082794,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0172,i0172,Amazon Intact 0172,-64.5,-4.5,NA,NA,2,7,0.19746709470305,0.290691813804173,0.01776886035313,3.97512038523274,0.137132423756019,1192.31942215088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0173,i0173,Amazon Intact 0173,-63.5,-4.5,NA,NA,2,7,0.126954475308642,0.292680941358025,0.0181841820987654,3.78769290123457,0.126659722222222,1189.32098765432,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0174,i0174,Amazon Intact 0174,-62.5,-4.5,NA,NA,2,4,0.163475716064757,0.273605230386052,0.0177661270236613,4.15230386052304,0.136013698630137,1161.02117061021,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0175,i0175,Amazon Intact 0175,-61.5,-4.5,NA,NA,2,7,0.13280727212721,0.302809712941324,0.0262820949943889,3.94619143567497,0.113322670499445,1165.89946168109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0176,i0176,Amazon Intact 0176,-60.5,-4.5,NA,NA,2,7,0.179919421487603,0.312974690082645,0.0183882747933884,4.09395661157025,0.127867768595041,1160.86260330579,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0177,i0177,Amazon Intact 0177,-59.5,-4.5,NA,NA,2,8,0.336,0.318,0.0166,4.1,0.105,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0178,i0178,Amazon Intact 0178,-58.5,-4.5,NA,NA,2,8,0.321354241129811,0.375408567922717,0.0144654642733048,4.09468715420435,0.104033143211168,1156.81244095367,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0179,i0179,Amazon Intact 0179,-57.5,-4.5,NA,NA,2,8,0.415331305303557,0.366601371168554,0.0171815995710085,4.11656375020538,0.104339695117783,1157.63684320586,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0180,i0180,Amazon Intact 0180,-56.5,-4.5,NA,NA,2,8,0.355593315895006,0.393720972354411,0.0162704985607786,4.19262089454544,0.105047794626876,1155.94914097185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0181,i0181,Amazon Intact 0181,-55.5,-4.5,NA,NA,2,8,0.333254551700447,0.356485056681553,0.0200386808656819,4.18979732050842,0.100683613878392,1147.5334936448,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0182,i0182,Amazon Intact 0182,-54.5,-4.5,NA,NA,2,8,0.36203836952556,0.363111520041128,0.0200708210486965,4.38380479003491,0.0977894594579951,1168.20588858607,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0183,i0183,Amazon Intact 0183,-53.5,-4.5,NA,NA,2,8,0.412961517904864,0.307752004275788,0.0185749331908071,4.39567076429717,0.0942057723142704,1164.0994120791,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0184,i0184,Amazon Intact 0184,-52.5,-4.5,NA,NA,2,8,0.411855537435268,0.337758914280448,0.0158014482785004,4.33425209540328,0.10255163071051,1179.34930849609,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0185,i0185,Amazon Intact 0185,-51.5,-4.5,NA,NA,2,8,0.407422168172342,0.365154968728284,0.016791000694927,4.45868658790827,0.101891938846421,1185.28492008339,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0186,i0186,Amazon Intact 0186,-50.5,-4.5,NA,NA,2,5,0.428,0.239,0.0181,4.6,0.093,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0187,i0187,Amazon Intact 0187,-49.5,-4.5,NA,NA,2,5,0.441,0.267,0.0193,4.7,0.093,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0188,i0188,Amazon Intact 0188,-48.5,-4.5,NA,NA,2,5,0.43,0.25,0.0182,4.7,0.078,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0189,i0189,Amazon Intact 0189,-47.5,-4.5,NA,NA,2,5,0.382,0.245,0.0164,4.9,0.075,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0190,i0190,Amazon Intact 0190,-46.5,-4.5,NA,NA,2,8,0.439428484011334,0.358171322892075,0.0173332375996905,4.93920405875888,0.0900584877584942,1245.42093411732,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0191,i0191,Amazon Intact 0191,-45.5,-4.5,NA,NA,2,5,0.448,0.259,0.0159,5.2,0.081,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0192,i0192,Amazon Intact 0192,-69.5,-3.5,NA,NA,2,5,0.318452568295237,0.27335013367275,0.0429284412195275,4.30292278054564,0.131592159120715,1180.0924575863,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0193,i0193,Amazon Intact 0193,-68.5,-3.5,NA,NA,2,8,0.289615166039776,0.302296043277158,0.0243809465206284,4.28969269797309,0.112370333047237,1179.8274509834,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0194,i0194,Amazon Intact 0194,-67.5,-3.5,NA,NA,2,8,0.2700686321647,0.311963459336089,0.0251306205205177,4.14459388065387,0.133479905527406,1150.91269511748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0195,i0195,Amazon Intact 0195,-66.5,-3.5,NA,NA,2,8,0.302732084799917,0.317106665959767,0.0257642142408992,4.19155826315183,0.137826048525465,1135.74955305385,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0196,i0196,Amazon Intact 0196,-65.5,-3.5,NA,NA,2,8,0.258101936799184,0.303352701325178,0.0245166666666667,4.09964322120285,0.127257900101937,1130.76962283384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0197,i0197,Amazon Intact 0197,-64.5,-3.5,NA,NA,2,11,0.191,0.511,0.023,4.1,0.113,1150,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0198,i0198,Amazon Intact 0198,-63.5,-3.5,NA,NA,2,7,0.173980475688053,0.284462404732551,0.0183109889017527,4.06681640015756,0.112112878079992,1197.74383952955,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0199,i0199,Amazon Intact 0199,-62.5,-3.5,NA,NA,2,8,0.205569367108256,0.279964966850437,0.0228394088267051,4.11279350923955,0.113313215921889,1169.96765862445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0200,i0200,Amazon Intact 0200,-61.5,-3.5,NA,NA,2,17,0.209,0.486,0.0198,4.2,0.111,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0201,i0201,Amazon Intact 0201,-60.5,-3.5,NA,NA,2,7,0.164556952081697,0.335710919088767,0.0174515318146112,4.1420005236973,0.0925653312385441,1158.56245090338,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0202,i0202,Amazon Intact 0202,-59.5,-3.5,NA,NA,2,17,0.206,0.445,0.0185,4.2,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0203,i0203,Amazon Intact 0203,-58.5,-3.5,NA,NA,2,8,0.256,0.36,0.0165,4.2,0.109,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0204,i0204,Amazon Intact 0204,-57.5,-3.5,NA,NA,2,16,0.361287001225935,0.400896875184196,0.0195501365989632,4.21184136529572,0.11345984693712,1182.29455769475,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0205,i0205,Amazon Intact 0205,-56.5,-3.5,NA,NA,2,9,0.466265704196725,0.359033669562661,0.0156241671891566,4.09684359417543,0.0942319636252154,1176.10157498244,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0206,i0206,Amazon Intact 0206,-55.5,-3.5,NA,NA,2,6,0.48989805511363,0.342665064851515,0.014674402617952,4.11786563803893,0.097472504212456,1188.98461685856,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0207,i0207,Amazon Intact 0207,-54.5,-3.5,NA,NA,2,6,0.450073758865248,0.343052482269504,0.0156248226950355,4.2090780141844,0.0934992907801418,1177.39007092199,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0208,i0208,Amazon Intact 0208,-53.5,-3.5,NA,NA,2,8,0.388478597880332,0.386833348638904,0.0167795303617296,4.47863495593655,0.107195153680423,1181.71986743304,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0209,i0209,Amazon Intact 0209,-52.5,-3.5,NA,NA,2,5,0.382,0.208,0.0179,4.7,0.098,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0210,i0210,Amazon Intact 0210,-51.5,-3.5,NA,NA,2,5,0.439,0.205,0.0184,4.6,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0211,i0211,Amazon Intact 0211,-50.5,-3.5,NA,NA,2,5,0.455,0.219,0.0174,4.6,0.099,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0212,i0212,Amazon Intact 0212,-49.5,-3.5,NA,NA,2,5,0.4545,0.235,0.0202,4.7,0.092,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0213,i0213,Amazon Intact 0213,-48.5,-3.5,NA,NA,2,5,0.481,0.217,0.0169,4.5,0.078,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0214,i0214,Amazon Intact 0214,-47.5,-3.5,NA,NA,2,5,0.467,0.207,0.0157,4.8,0.071,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0215,i0215,Amazon Intact 0215,-46.5,-3.5,NA,NA,2,6,0.45541505595117,0.345739572736521,0.016979518480841,4.61631061376738,0.0877416073245168,1190.91217361818,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0216,i0216,Amazon Intact 0216,-45.5,-3.5,NA,NA,2,8,0.376,0.314,0.014,5.1,0.091,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0217,i0217,Amazon Intact 0217,-69.5,-2.5,NA,NA,2,5,0.501084205518554,0.186823977164605,0.039562226450999,4.30428163653663,0.152717411988582,1153.55851569933,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0218,i0218,Amazon Intact 0218,-68.5,-2.5,NA,NA,2,5,0.474578107885745,0.225788409727348,0.0350460210800488,4.24778382175107,0.157631583701463,1120.71969737027,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0219,i0219,Amazon Intact 0219,-67.5,-2.5,NA,NA,2,7,0.196220794392523,0.317254672897196,0.0251533878504673,4.2,0.134580607476636,1137.23130841121,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0220,i0220,Amazon Intact 0220,-66.5,-2.5,NA,NA,2,8,0.263612791702679,0.311148660328436,0.0280566119273984,4.19273984442524,0.152225583405359,1142.05704407952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0221,i0221,Amazon Intact 0221,-65.5,-2.5,NA,NA,2,7,0.185346839867306,0.290991858339675,0.0266765038387251,4.2015748646035,0.14271704441742,1105.73817449625,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0222,i0222,Amazon Intact 0222,-64.5,-2.5,NA,NA,2,17,0.22,0.477,0.0261,4.1,0.136,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0223,i0223,Amazon Intact 0223,-63.5,-2.5,NA,NA,2,8,0.238802126881665,0.28627569123884,0.0242921620325804,4.12534833508294,0.121304591884166,1157.52515713517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0224,i0224,Amazon Intact 0224,-62.5,-2.5,NA,NA,2,8,0.303226557975135,0.323876468990194,0.0221805349432241,4.32238435161985,0.102009606543295,1175.28861746452,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0225,i0225,Amazon Intact 0225,-61.5,-2.5,NA,NA,2,8,0.384794096355573,0.322833529555224,0.0162511491983126,4.58697499306154,0.103769225769498,1178.56654731473,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0226,i0226,Amazon Intact 0226,-60.5,-2.5,NA,NA,2,8,0.369814850494501,0.33377306007965,0.0152474823558628,4.13446662775592,0.0976310729886332,1188.5430997087,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0227,i0227,Amazon Intact 0227,-59.5,-2.5,NA,NA,2,16,0.39368801431127,0.41897030411449,0.0159848658318426,4.05656529516995,0.0781792486583184,1165.52772808587,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0228,i0228,Amazon Intact 0228,-58.5,-2.5,NA,NA,2,5,0.42,0.194,0.0155,4.1,0.091,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0229,i0229,Amazon Intact 0229,-57.5,-2.5,NA,NA,2,6,0.479282903641197,0.346625089658027,0.0156348479275412,4.12573829897359,0.098496227238243,1166.06664423999,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0230,i0230,Amazon Intact 0230,-56.5,-2.5,NA,NA,2,6,0.568451904758393,0.287509378431131,0.0137057084578839,4.03121116079173,0.083103354371674,1176.84889973747,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0231,i0231,Amazon Intact 0231,-55.5,-2.5,NA,NA,2,3,0.548,0.169,0.0143,4.1,0.107,1160,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0232,i0232,Amazon Intact 0232,-54.5,-2.5,NA,NA,2,5,0.369,0.222,0.0165,4.6,0.124,1160,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0233,i0233,Amazon Intact 0233,-53.5,-2.5,NA,NA,2,11,0.258783928069683,0.487778870469233,0.0174272548468671,4.49269457712841,0.107891261590334,1169.15987636977,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0234,i0234,Amazon Intact 0234,-52.5,-2.5,NA,NA,2,5,0.47,0.243,0.0154,4.4,0.104,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0235,i0235,Amazon Intact 0235,-51.5,-2.5,NA,NA,2,6,0.486723228995058,0.296668314113125,0.0166360241625481,4.37144426139484,0.0979077429983525,1190.0823723229,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0236,i0236,Amazon Intact 0236,-50.5,-2.5,NA,NA,2,6,0.466559221658206,0.302565989847716,0.0178413705583756,4.42301184433164,0.10463282571912,1181.5820642978,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0237,i0237,Amazon Intact 0237,-49.5,-2.5,NA,NA,2,5,0.472,0.242,0.0186,4.6,0.107,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0238,i0238,Amazon Intact 0238,-48.5,-2.5,NA,NA,2,5,0.456,0.241,0.0165,4.7,0.093,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0239,i0239,Amazon Intact 0239,-47.5,-2.5,NA,NA,2,5,0.395,0.246,0.0157,4.9,0.076,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0240,i0240,Amazon Intact 0240,-46.5,-2.5,NA,NA,2,8,0.366523568668258,0.366549613332243,0.016339490616958,4.55215271258003,0.08033462738003,1174.40768787318,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0241,i0241,Amazon Intact 0241,-45.5,-2.5,NA,NA,2,8,0.412,0.291,0.0167,5,0.095,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0242,i0242,Amazon Intact 0242,-44.5,-2.5,NA,NA,2,8,0.349,0.314,0.0197,5.1,0.148,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0243,i0243,Amazon Intact 0243,-68.5,-1.5,NA,NA,2,3,0.583286919831224,0.191196905766526,0.0204880450070324,4.24838255977496,0.147434599156118,1174.75386779184,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0244,i0244,Amazon Intact 0244,-67.5,-1.5,NA,NA,2,8,0.359,0.338,0.0251,4.3,0.14,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0245,i0245,Amazon Intact 0245,-66.5,-1.5,NA,NA,2,6,0.484,0.261,0.0216,4.3,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0246,i0246,Amazon Intact 0246,-65.5,-1.5,NA,NA,2,5,0.483153846153846,0.217,0.0222769230769231,4.3,0.101076923076923,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0247,i0247,Amazon Intact 0247,-64.5,-1.5,NA,NA,2,5,0.332199570164771,0.226728347704738,0.0229433604016956,4.15299560886021,0.109355631266316,1140.07653008428,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0248,i0248,Amazon Intact 0248,-63.5,-1.5,NA,NA,2,8,0.283137652629851,0.275732067246036,0.0222419811718623,4.10356431250998,0.126085245743094,1156.30507181702,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0249,i0249,Amazon Intact 0249,-62.5,-1.5,NA,NA,2,8,0.278494276944493,0.278303735285365,0.0259597767751026,4.04693747670087,0.114247037965245,1161.43611359252,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0250,i0250,Amazon Intact 0250,-61.5,-1.5,NA,NA,2,8,0.293022662889518,0.344461756373938,0.0409393767705382,4.03371104815864,0.137597733711048,1130.22662889518,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0251,i0251,Amazon Intact 0251,-60.5,-1.5,NA,NA,2,8,0.306637396681003,0.37073806896197,0.0180052615048106,4.13085875382976,0.0963526754981705,1179.21859014325,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0252,i0252,Amazon Intact 0252,-59.5,-1.5,NA,NA,2,16,0.300556308615255,0.401741069547032,0.0184511341679462,4.21649253416002,0.0842416870038793,1174.29416581795,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0253,i0253,Amazon Intact 0253,-58.5,-1.5,NA,NA,2,17,0.249196236234406,0.409889027806853,0.0169219522241721,4.25042630421649,0.0909396671003949,1176.75135849828,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0254,i0254,Amazon Intact 0254,-57.5,-1.5,NA,NA,2,8,0.353953296510074,0.356318795150176,0.0162318951959305,4.16127921138137,0.0921185700147406,1169.03315845088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0255,i0255,Amazon Intact 0255,-56.5,-1.5,NA,NA,2,8,0.428561397205884,0.357890819191029,0.0170443708892477,4.07668184177044,0.102229315858188,1172.03342349047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0256,i0256,Amazon Intact 0256,-55.5,-1.5,NA,NA,2,8,0.326753267119707,0.365852064819655,0.0162360690015682,4.17762676424464,0.109025614218505,1155.24307370622,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0257,i0257,Amazon Intact 0257,-54.5,-1.5,NA,NA,2,6,0.453466860183841,0.30700145137881,0.0147157232704403,4.44944363812288,0.0934358974358974,1168.24383164006,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0258,i0258,Amazon Intact 0258,-53.5,-1.5,NA,NA,2,8,0.358051985792703,0.375059412334517,0.0217846625766871,4.69667420083952,0.102369066838876,1149.43816596706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0259,i0259,Amazon Intact 0259,-52.5,-1.5,NA,NA,2,5,0.425,0.266,0.0211,4.7,0.13,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0260,i0260,Amazon Intact 0260,-51.5,-1.5,NA,NA,2,8,0.422570366881509,0.324241067101816,0.0166373957360906,4.5004522363151,0.103892049038098,1177.00228423286,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0261,i0261,Amazon Intact 0261,-50.5,-1.5,NA,NA,2,6,0.561072147239264,0.28404981595092,0.0209613987730061,4.51754601226994,0.0997418404907976,1198.81717791411,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0262,i0262,Amazon Intact 0262,-49.5,-1.5,NA,NA,2,6,0.538880931837791,0.296545297670406,0.024327868852459,4.54831751509922,0.110910267471959,1196.7558239862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0263,i0263,Amazon Intact 0263,-48.5,-1.5,NA,NA,2,5,0.393,0.274,0.0242,4.7,0.144,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0264,i0264,Amazon Intact 0264,-47.5,-1.5,NA,NA,2,5,0.383,0.249,0.0161,4.9,0.102,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0265,i0265,Amazon Intact 0265,-46.5,-1.5,NA,NA,2,5,0.365,0.271,0.0168,4.9,0.107,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0266,i0266,Amazon Intact 0266,-45.5,-1.5,NA,NA,2,5,0.386,0.266,0.0217,4.9,0.127,1190,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0267,i0267,Amazon Intact 0267,-69.5,-0.5,NA,NA,2,6,0.513583189169413,0.245977740531898,0.0276737157238781,4.58843583440703,0.12858002948712,1194.93803226348,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0268,i0268,Amazon Intact 0268,-68.5,-0.5,NA,NA,2,3,0.600080368544563,0.184909434794784,0.0266536832169823,4.45450123700453,0.13408238057271,1160.05935057225,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0269,i0269,Amazon Intact 0269,-67.5,-0.5,NA,NA,2,6,0.497991462671745,0.274257998162199,0.0237007313136071,4.41340109443275,0.129521088572825,1136.4929430812,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0270,i0270,Amazon Intact 0270,-66.5,-0.5,NA,NA,2,6,0.487163751757489,0.259332591217498,0.0247852706061505,4.28013241098742,0.11444026279783,1143.40517343133,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0271,i0271,Amazon Intact 0271,-65.5,-0.5,NA,NA,2,5,0.479092105263158,0.217730263157895,0.0217730263157895,4.2,0.0977763157894737,1173.88157894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0272,i0272,Amazon Intact 0272,-64.5,-0.5,NA,NA,2,5,0.472669608463471,0.249291511524267,0.02087983621479,4.13056551181114,0.106210734138445,1160.99596029531,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0273,i0273,Amazon Intact 0273,-63.5,-0.5,NA,NA,2,6,0.46518007761852,0.262138086454371,0.0250127829843773,4.11123340189234,0.11280515756391,1155.37493870311,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0274,i0274,Amazon Intact 0274,-62.5,-0.5,NA,NA,2,8,0.399849910285365,0.303517220341941,0.0301553996969191,4.09137312319897,0.116908159627452,1150.9291358209,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0275,i0275,Amazon Intact 0275,-61.5,-0.5,NA,NA,2,8,0.401,0.296,0.0293,4.1,0.121,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0276,i0276,Amazon Intact 0276,-60.5,-0.5,NA,NA,2,8,0.43759229436722,0.327765854198416,0.0239312319665031,4.07425046342091,0.103975187414491,1182.26604116517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0277,i0277,Amazon Intact 0277,-59.5,-0.5,NA,NA,2,17,0.239715351812367,0.418997334754797,0.0188569829424307,4.20442430703625,0.0887681236673774,1185.07995735608,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0278,i0278,Amazon Intact 0278,-58.5,-0.5,NA,NA,2,8,0.232,0.367,0.017,4.2,0.091,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0279,i0279,Amazon Intact 0279,-57.5,-0.5,NA,NA,2,8,0.281511182108626,0.395685126020589,0.020892225772098,4.02744053958112,0.0987724529641463,1147.54348597799,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0280,i0280,Amazon Intact 0280,-56.5,-0.5,NA,NA,2,8,0.333425168387214,0.385573036348581,0.0181079429907979,4.08479599600034,0.111452773708574,1167.16959626952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0281,i0281,Amazon Intact 0281,-55.5,-0.5,NA,NA,2,8,0.367863167567993,0.389374358579361,0.0202798785670844,4.13969965062452,0.111505103338343,1159.92937182343,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0282,i0282,Amazon Intact 0282,-54.5,-0.5,NA,NA,2,8,0.338900020480741,0.347237539346446,0.024187092972358,4.39643822949762,0.105208915705631,1174.61851509937,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0283,i0283,Amazon Intact 0283,-53.5,-0.5,NA,NA,2,8,0.355,0.28,0.0153,4.5,0.098,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0284,i0284,Amazon Intact 0284,-52.5,-0.5,NA,NA,2,8,0.339034131922173,0.374604688011251,0.0156990635612464,4.42961377701112,0.103277610183329,1204.46796846706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0285,i0285,Amazon Intact 0285,-51.5,-0.5,NA,NA,2,8,0.372166159029789,0.380014992408354,0.0220836014901674,4.63160218234417,0.146076665566285,1177.6541729892,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0286,i0286,Amazon Intact 0286,-50.5,-0.5,NA,NA,2,5,0.445,0.222,0.0262,4.6,0.133,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0287,i0287,Amazon Intact 0287,-49.5,-0.5,NA,NA,2,5,0.4075,0.242,0.0301,5,0.17,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0288,i0288,Amazon Intact 0288,-48.5,-0.5,NA,NA,2,8,0.314,0.304,0.0325,5.2,0.173,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0289,i0289,Amazon Intact 0289,-69.5,0.5,NA,NA,2,6,0.518,0.244,0.024,4.5,0.124,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0290,i0290,Amazon Intact 0290,-68.5,0.5,NA,NA,2,6,0.556031275302543,0.213491255142449,0.0269094765332795,4.77052293091954,0.128356794829367,1199.06133779691,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0291,i0291,Amazon Intact 0291,-67.5,0.5,NA,NA,2,6,0.531345964496635,0.243997191584387,0.0252805275869034,4.58959693238905,0.12274820262963,1138.82061016445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0292,i0292,Amazon Intact 0292,-66.5,0.5,NA,NA,2,6,0.548215196717419,0.224407028928467,0.0271229074631325,4.43939775224795,0.109745421821456,1113.94872134619,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0293,i0293,Amazon Intact 0293,-65.5,0.5,NA,NA,2,6,0.484765179678734,0.256514100828391,0.0282823256655113,4.14867339135671,0.114060992235232,1143.58311648962,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0294,i0294,Amazon Intact 0294,-64.5,0.5,NA,NA,2,6,0.487010403492551,0.258904649364713,0.0268010597810063,4.10729350353887,0.118673620957919,1124.26391973434,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0295,i0295,Amazon Intact 0295,-63.5,0.5,NA,NA,2,5,0.490013881177124,0.223543586896169,0.0233667962243198,4.29244863964464,0.111192670738479,1171.7157134925,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0296,i0296,Amazon Intact 0296,-62.5,0.5,NA,NA,2,6,0.483,0.261,0.0177,4.8,0.127,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0297,i0297,Amazon Intact 0297,-61.5,0.5,NA,NA,2,6,0.490005479452055,0.286574429223744,0.0155687671232877,4.6,0.115645662100457,1239.25114155251,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0298,i0298,Amazon Intact 0298,-60.5,0.5,NA,NA,2,8,0.422827388919844,0.29860800842063,0.0148668648048191,4.45877357340052,0.10206694774671,1226.64877103883,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0299,i0299,Amazon Intact 0299,-59.5,0.5,NA,NA,2,8,0.35218276921012,0.332975825521394,0.0176846653881449,4.36719699243703,0.103102231226806,1209.98824400904,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0300,i0300,Amazon Intact 0300,-58.5,0.5,NA,NA,2,8,0.363830388886367,0.307647710465354,0.0175809224486845,4.43911678729251,0.103051225392196,1189.58270236001,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0301,i0301,Amazon Intact 0301,-57.5,0.5,NA,NA,2,8,0.354931842769564,0.343516768842409,0.0181821853588172,4.35708618824378,0.100027046520014,1219.78723404255,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0302,i0302,Amazon Intact 0302,-56.5,0.5,NA,NA,2,8,0.377,0.279,0.0156,4.5,0.098,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0303,i0303,Amazon Intact 0303,-55.5,0.5,NA,NA,2,8,0.35,0.292,0.0178,4.5,0.1,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0304,i0304,Amazon Intact 0304,-54.5,0.5,NA,NA,2,8,0.326,0.309,0.0184,4.5,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0305,i0305,Amazon Intact 0305,-53.5,0.5,NA,NA,2,8,0.323365210127657,0.370095805707387,0.0187482045535554,4.48093786377005,0.0996940546590494,1195.62742007063,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0306,i0306,Amazon Intact 0306,-52.5,0.5,NA,NA,2,8,0.292867015931683,0.397491722254934,0.0192186303907941,4.4352519463437,0.103649205072188,1202.97149068891,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0307,i0307,Amazon Intact 0307,-51.5,0.5,NA,NA,2,8,0.354676744608013,0.342080412276782,0.0198860758037557,4.59291576539618,0.104769497337053,1216.29109710547,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0308,i0308,Amazon Intact 0308,-69.5,1.5,NA,NA,2,6,0.526,0.24,0.024,4.5,0.097,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0309,i0309,Amazon Intact 0309,-68.5,1.5,NA,NA,2,6,0.52253906795127,0.205054553070751,0.0427814812837994,4.66687109294238,0.126099018640665,1194.61921079365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0310,i0310,Amazon Intact 0310,-67.5,1.5,NA,NA,2,6,0.561091043671355,0.20421021465581,0.0270715025906736,4.8,0.125521835677276,1167.21687638786,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0311,i0311,Amazon Intact 0311,-63.5,1.5,NA,NA,2,8,0.42494387755102,0.300469023323615,0.0162231413994169,4.46344752186589,0.11184584548105,1160.36807580175,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0312,i0312,Amazon Intact 0312,-62.5,1.5,NA,NA,2,5,0.461726939264444,0.258288962317539,0.0154604370768904,4.66603356058363,0.108984270747554,1194.30671490346,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0313,i0313,Amazon Intact 0313,-61.5,1.5,NA,NA,2,6,0.491579346398351,0.244625519219408,0.0134864468276648,4.76323965635835,0.117913015594765,1223.94573462479,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0314,i0314,Amazon Intact 0314,-60.5,1.5,NA,NA,2,6,0.549014345688791,0.230570332291842,0.013304077377855,4.86755000506628,0.0961091934521206,1208.56740319152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0315,i0315,Amazon Intact 0315,-59.5,1.5,NA,NA,2,6,0.481927994873695,0.255205541384766,0.0150356642601167,4.74670830089643,0.103511291584974,1207.44096428706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0316,i0316,Amazon Intact 0316,-57.5,1.5,NA,NA,2,8,0.320494450050454,0.381883955600404,0.0240853683148335,4.43296333669694,0.130706020854356,1230.91153716784,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0317,i0317,Amazon Intact 0317,-56.5,1.5,NA,NA,2,8,0.379,0.278,0.0166,4.6,0.102,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0318,i0318,Amazon Intact 0318,-55.5,1.5,NA,NA,2,5,0.392,0.263,0.0161,4.6,0.101,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0319,i0319,Amazon Intact 0319,-54.5,1.5,NA,NA,2,8,0.350395925297114,0.379331069609508,0.0170010526315789,4.57011884550085,0.100765365025467,1205.64006791171,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0320,i0320,Amazon Intact 0320,-53.5,1.5,NA,NA,2,8,0.33561267805929,0.378876602523137,0.017076443885941,4.53922886608355,0.0972183506159432,1210.01906683005,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0321,i0321,Amazon Intact 0321,-52.5,1.5,NA,NA,2,8,0.335149100257069,0.374988982739625,0.0183976496511201,4.54168196841719,0.117102093279471,1219.54829232464,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0322,i0322,Amazon Intact 0322,-51.5,1.5,NA,NA,2,8,0.342559043915282,0.375207384619859,0.0198429336435915,4.53589145059832,0.111399201408253,1218.60642701711,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0323,i0323,Amazon Intact 0323,-50.5,1.5,NA,NA,2,8,0.334285904255319,0.309539893617021,0.0247304521276596,4.85345744680851,0.195167553191489,747.114361702128,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0324,i0324,Amazon Intact 0324,-63.5,2.5,NA,NA,2,5,0.394,0.267,0.0229,4.2,0.106,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0325,i0325,Amazon Intact 0325,-62.5,2.5,NA,NA,2,8,0.373555616051848,0.347475527485543,0.0166705535882847,4.47090601554171,0.110173448007595,1154.31042803282,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0326,i0326,Amazon Intact 0326,-61.5,2.5,NA,NA,2,6,0.474488977350501,0.284508323716426,0.0158915215631065,4.71459515869303,0.0970353676585795,1191.61066134685,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0327,i0327,Amazon Intact 0327,-60.5,2.5,NA,NA,2,3,0.582,0.197,0.0137,5.1,0.106,1270,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0328,i0328,Amazon Intact 0328,-52.5,2.5,NA,NA,2,8,0.363187161639598,0.365375870069606,0.0310636117556071,4.62965970610982,0.129161252900232,1214.36194895592,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0329,i0329,Amazon Intact 0329,-51.5,2.5,NA,NA,2,8,0.357012872350827,0.354746872110307,0.0213451569559534,4.58902910482537,0.143151406767849,1205.39553680222,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0330,i0330,Amazon Intact 0330,-63.5,3.5,NA,NA,2,8,0.361,0.281,0.0224,4.1,0.117,1120,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0331,i0331,Amazon Intact 0331,-62.5,3.5,NA,NA,2,8,0.346073414671842,0.369487859609459,0.0177165198541867,4.37372537735457,0.10968214765377,1131.10602529551,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0332,i0332,Amazon Intact 0332,-61.5,3.5,NA,NA,2,6,0.479615694573823,0.293875810816361,0.0152221313921233,4.85439423856933,0.110973840211288,1214.41237963628,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0333,i0333,Amazon Intact 0333,-60.5,3.5,NA,NA,2,6,0.498,0.26,0.0101,5.3,0.153,1320,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0334,i0334,Amazon Intact 0334,-51.5,3.5,NA,NA,2,8,0.307,0.331,0.0258,4.7,0.171,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0335,i0335,Amazon Intact 0335,-60.5,4.5,NA,NA,2,8,0.348,0.334,0.0249,5.3,0.151,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0336,i0336,Amazon Intact 0336,-59.5,-11.5,NA,NA,2,6,0.531965811840757,0.243728325972639,0.0187127669238973,4.4686539658477,0.108225292926799,1211.32454358169,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0337,i0337,Amazon Intact 0337,-58.5,-12.5,NA,NA,2,3,0.754084244600303,0.15137239297781,0.0138599813936637,4.61700499339524,0.094790242484175,1221.66075690442,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0338,i0338,Amazon Intact 0338,-51.5,-12.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0339,i0339,Amazon Intact 0339,-54.5,-13.5,NA,NA,2,6,0.604719512195122,0.254965447154472,0.0216197154471545,4.8,0.106475609756098,1225.91463414634,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0340,i0340,Amazon Intact 0340,-46.5,-5.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0341,i0341,Amazon Intact 0341,-59.5,-12.5,NA,NA,2,3,0.668453719723183,0.181541522491349,0.0159257352941176,4.6780276816609,0.103732698961938,1216.35813148789,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0342,i0342,Amazon Intact 0342,-59.5,-13.5,NA,NA,2,3,0.699488842211707,0.186988779988865,0.0157302321721259,4.91277867918269,0.087079116612656,1214.97471074384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0343,i0343,Amazon Intact 0343,-53.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0344,i0344,Amazon Intact 0344,-53.5,2.5,NA,NA,2,8,0.307401814058957,0.396586848072562,0.0224716553287982,4.62208616780045,0.108532426303855,1201.46031746032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0345,i0345,Amazon Intact 0345,-73.5,-6.5,NA,NA,2,8,0.38418927140332,0.323272575377048,0.0253926179596497,4.18006928075437,0.134395888997171,1213.40132840139,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0346,i0346,Amazon Intact 0346,-65.5,-11.5,NA,NA,2,8,0.436925311203319,0.291680497925311,0.0164742738589212,4.73112033195021,0.10660857538036,1211.53526970954,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0347,i0347,Amazon Intact 0347,-69.5,-1.5,NA,NA,2,3,0.566508552631579,0.187552631578947,0.02448125,4.32605263157895,0.137514473684211,1178.75657894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0348,i0348,Amazon Intact 0348,-59.5,4.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0349,i0349,Amazon Intact 0349,-50.5,-10.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0350,i0350,Amazon Intact 0350,-50.5,0.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 diff --git a/R-utils/assign.pft.r b/R-utils/assign.pft.r index 4567345dc..5d22144da 100644 --- a/R-utils/assign.pft.r +++ b/R-utils/assign.pft.r @@ -333,7 +333,7 @@ assign.pft <<- function(datum,path=srcdir,approach=c("rho","cluster"),verbose=FA #==========================================================================================# #==========================================================================================# -# This function finds the most similar group to the data in +# This function finds the most similar group to the data input. #------------------------------------------------------------------------------------------# which.pft <<- function(datum,medoid,trait,wcluster){ diff --git a/R-utils/cci.lieberman.r b/R-utils/cci.lieberman.r index df17f632a..f8cde7212 100644 --- a/R-utils/cci.lieberman.r +++ b/R-utils/cci.lieberman.r @@ -167,7 +167,7 @@ cci.lieberman <<- function( xyz, dxy = 1, radius = 10, undef = -9999., closure }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! grepl("^cci.lieberman",wcm[[n]]) #---------------------------------------------------------------------------------# }#end if diff --git a/R-utils/charutils.r b/R-utils/charutils.r index 9d4a86944..2f9283c37 100644 --- a/R-utils/charutils.r +++ b/R-utils/charutils.r @@ -36,7 +36,7 @@ capwords <<- function(s, strict = FALSE) { #--------------------------------------------------------------------------------------# #---- Force NAs to remain NAs. --------------------------------------------------------# - ans[sel] = NA + ans[sel] = NA_character_ return(ans) #--------------------------------------------------------------------------------------# }#end if @@ -178,7 +178,7 @@ nregexpr <<- function(pattern,text,...){ }else{ #---- Use gregexpr to identifiy the number of occurrences. --------------------------# ans = gregexpr(pattern=pattern,text=text,...)[[1]] - ans = length(ans[ans %>% 0]) + ans = length(ans[ans %gt% 0]) #------------------------------------------------------------------------------------# }#end if (length(text) > 1) #---------------------------------------------------------------------------------------# diff --git a/R-utils/closest.r b/R-utils/closest.r index 4c56982f9..9a5537698 100644 --- a/R-utils/closest.r +++ b/R-utils/closest.r @@ -33,12 +33,12 @@ which.closest <<- function(x,A,mask=rep(TRUE,length(A)) ){ if (! any(is.finite(x)) || ! any(mask,na.rm=TRUE)){ #----- x is invalid, return NA. -----------------------------------------------------# idx = NA - }else if(sum(x %==% A,na.rm=TRUE) > 1){ + }else if(sum(x %eq% A,na.rm=TRUE) > 1){ #------------------------------------------------------------------------------------# # If there are multiple values of x that are the same as x, we randomly sample # # one value. # #------------------------------------------------------------------------------------# - idx = sample(A.idx[x %==% A],size=1) + idx = sample(A.idx[x %eq% A],size=1) #------------------------------------------------------------------------------------# }else{ #------------------------------------------------------------------------------------# diff --git a/R-utils/cloud.metrics.r b/R-utils/cloud.metrics.r index 881dd1ff5..d1256e6cc 100644 --- a/R-utils/cloud.metrics.r +++ b/R-utils/cloud.metrics.r @@ -389,7 +389,7 @@ cloud.metrics <<- function( x #-------------------------------------------------------------------------------------# # Keep only the last returns. # #-------------------------------------------------------------------------------------# - sellast = x$retn.number %==% x$number.retn.gp + sellast = x$retn.number %eq% x$number.retn.gp #----- Check whether to use the subset or the entire thing (to generate NA). ---------# if (sum(sellast) >= min.pts){ zlast = x$z[sellast] @@ -496,7 +496,7 @@ cloud.metrics <<- function( x }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! ( grepl("cloud.metrics",wcm[[n]]) || grepl("grid.metrics" ,wcm[[n]]) ) #---------------------------------------------------------------------------------# @@ -585,7 +585,7 @@ cloud.metrics <<- function( x zdens = data.frame(x=zzdens$x,y=zzdens$y) if (any(is.finite(zzdens$y))){ dz = mean(diff(zdens$x)) - spk = peaks(zdens$y) & zdens$y %>% 1.e-10 + spk = peaks(zdens$y) & zdens$y %gt% 1.e-10 zpeaks = zdens[spk,] o = order(zpeaks$y,decreasing=TRUE) zpeaks = zpeaks[o,] @@ -727,7 +727,7 @@ cloud.metrics <<- function( x }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! ( grepl("cloud.metrics",wcm[[n]]) || grepl("grid.metrics" ,wcm[[n]]) ) #---------------------------------------------------------------------------------# @@ -824,7 +824,7 @@ open.fcan <<- function( pt.cloud ans = rep(NA,times=length(zabove)) }else{ #----- Discard data that are not classified as vegetation. --------------------------# - zveg = ifelse( pt.cloud$pt.class %in% c(0,1,3,4,5) & pt.cloud$z %>=% zabove[1] + zveg = ifelse( pt.cloud$pt.class %in% c(0,1,3,4,5) & pt.cloud$z %ge% zabove[1] , pt.cloud$z , NA )#end ifelse diff --git a/R-utils/colour.palettes.r b/R-utils/colour.palettes.r new file mode 100644 index 000000000..34fcb9d9a --- /dev/null +++ b/R-utils/colour.palettes.r @@ -0,0 +1,410 @@ +#==========================================================================================# +#==========================================================================================# +# List of functions that generate colour palettes. They all call a single inter- # +# polation function. Most functions are derived from QGIS colour palettes. # +#------------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Blues. # + #---------------------------------------------------------------------------------------# + blues <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F7FBFF", "#DEEBF7", "#C6DBEF", "#9ECAE1", "#6BAED6", "#4292C6" + , "#2171B5", "#08519C", "#08306B") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function blues + #----- Inverse colour palette. ---------------------------------------------------------# + iblues <- function(n,alpha=1.0){ rev(blues(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + #---------------------------------------------------------------------------------------# + # BrBG. # + #---------------------------------------------------------------------------------------# + brbg <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#A6611A", "#DFC27D", "#F5F5F5", "#80CDC1", "#018571") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function brbg + #----- Inverse colour palette. ---------------------------------------------------------# + ibrbg <- function(n,alpha=1.0){ rev(brbg(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuGn. # + #---------------------------------------------------------------------------------------# + bugn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#C2D2F2", "#7AB1CC", "#63A6A6", "#338066", "#115929", "#003300") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bugn + #----- Inverse colour palette. ---------------------------------------------------------# + ibugn <- function(n,alpha=1.0){ rev(bugn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuGy. # + #---------------------------------------------------------------------------------------# + bugy <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#0050CE", "#1E64FF", "#2896FF", "#78D2FF", "#B4E6FF", "#FDFDFD" + , "#DEDEDE", "#B6B6B6", "#8E8E8E", "#666666", "#3E3E3E") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bugy + #----- Inverse colour palette. ---------------------------------------------------------# + ibugy <- function(n,alpha=1.0){ rev(bugy(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuPu. # + #---------------------------------------------------------------------------------------# + bupu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#EDF8FB", "#CCE0EE", "#AEC5DF", "#97A6CF", "#8B84BD", "#895FAC" + , "#853795", "#810F7C") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bupu + #----- Inverse colour palette. ---------------------------------------------------------# + ibupu <- function(n,alpha=1.0){ rev(bupu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # Greys. # + #---------------------------------------------------------------------------------------# + greys <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#fafafa","#050505") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function greys + #----- Inverse colour palette. ---------------------------------------------------------# + igreys <- function(n,alpha=1.0){ rev(greys(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # OrRd. # + #---------------------------------------------------------------------------------------# + orrd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FEFAE4", "#FEE7B7", "#F2BB83", "#CC7549", "#A6341E", "#800000") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function orrd + #----- Inverse colour palette. ---------------------------------------------------------# + iorrd <- function(n,alpha=1.0){ rev(orrd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PiYG. # + #---------------------------------------------------------------------------------------# + piyg <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#D01C8B", "#F1B6DA", "#F7F7F7", "#B8E186", "#4DAC26") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function piyg + #----- Inverse colour palette. ---------------------------------------------------------# + ipiyg <- function(n,alpha=1.0){ rev(piyg(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PRGn. # + #---------------------------------------------------------------------------------------# + prgn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#7B3294", "#C2A5CF", "#F7F7F7", "#A6DBA0", "#008837") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function prgn + #----- Inverse colour palette. ---------------------------------------------------------# + iprgn <- function(n,alpha=1.0){ rev(prgn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuOr. # + #---------------------------------------------------------------------------------------# + puor <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#5E3C99", "#B2ABD2", "#F7F7F7", "#FDB863", "#E66101") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function puor + #----- Inverse colour palette. ---------------------------------------------------------# + ipuor <- function(n,alpha=1.0){ rev(puor(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuRd. # + #---------------------------------------------------------------------------------------# + purd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F1EEF6", "#D7B5D8", "#DF65B0", "#DD1C77", "#980043") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function purd + #----- Inverse colour palette. ---------------------------------------------------------# + ipurd <- function(n,alpha=1.0){ rev(purd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuBuGn. # + #---------------------------------------------------------------------------------------# + pubugn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F6EFF7", "#D6DAEB", "#B1C5DF", "#80B2D4", "#51A2C0", "#2694A1" + , "#10817E", "#016C59") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function pubugn + #----- Inverse colour palette. ---------------------------------------------------------# + ipubugn <- function(n,alpha=1.0){ rev(pubugn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # RdBu. # + #---------------------------------------------------------------------------------------# + rdbu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#CA0020", "#F4A582", "#F7F7F7", "#92C5DE", "#0571B0") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function rdbu + #----- Inverse colour palette. ---------------------------------------------------------# + irdbu <- function(n,alpha=1.0){ rev(rdbu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # RdGy. # + #---------------------------------------------------------------------------------------# + rdgy <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = C( "#CA0020", "#F4A582", "#FFFFFF", "#BABABA", "#404040") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function rdgy + #----- Inverse colour palette. ---------------------------------------------------------# + irdgy <- function(n,alpha=1.0){ rev(rdgy(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # YlGnBu. # + #---------------------------------------------------------------------------------------# + ylgnbu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FFFFCC", "#CAEABF", "#93D5B6", "#5CC1C0", "#3BA6C1", "#2F87BA" + , "#295FA9", "#253494") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function ylgnbu + #----- Inverse colour palette. ---------------------------------------------------------# + iylgnbu <- function(n,alpha=1.0){ rev(ylgnbu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # YlOrRd. # + #---------------------------------------------------------------------------------------# + ylorrd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FFFFB2", "#FECC5C", "#FD8D3C", "#F03B20", "#BD0026") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function ylorrd + #----- Inverse colour palette. ---------------------------------------------------------# + iylorrd <- function(n,alpha=1.0){ rev(ylorrd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # For the following palettes, we use the default from package "viridis". We only # + # define the inverse functions for convenience. # + #---------------------------------------------------------------------------------------# + iinferno <- function(n,alpha=1.0){ inferno(n=n,alpha=alpha,direction=-1)} + imagma <- function(n,alpha=1.0){ magma (n=n,alpha=alpha,direction=-1)} + iviridis <- function(n,alpha=1.0){ viridis(n=n,alpha=alpha,direction=-1)} + #---------------------------------------------------------------------------------------# + + + + + +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/colour.utils.r b/R-utils/colour.utils.r index 6998de6c9..2d11c65a9 100644 --- a/R-utils/colour.utils.r +++ b/R-utils/colour.utils.r @@ -172,3 +172,45 @@ blacken <<- function(colour,f=c(s=0.50,v=0.50),...){ }#end function blacken #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# General function that interpolates nodes by using HSV. # +#------------------------------------------------------------------------------------------# +colour.interpol <<- function(nodes,n){ + #----- Decompose colours. --------------------------------------------------------------# + rgbmat = data.table(t(col2rgb(nodes))) + #---------------------------------------------------------------------------------------# + + + #----- Find the reference points for the interpolation functions. ----------------------# + rgbmat$x = seq(from=0,to=1,length.out=nrow(rgbmat)) + #---------------------------------------------------------------------------------------# + + + #----- Create functions to interpolate. ------------------------------------------------# + f.red = splinefun(x=rgbmat$x,y=rgbmat$red ,method="monoH.FC") + f.green = splinefun(x=rgbmat$x,y=rgbmat$green,method="monoH.FC") + f.blue = splinefun(x=rgbmat$x,y=rgbmat$blue ,method="monoH.FC") + #---------------------------------------------------------------------------------------# + + + #----- Create output table. ------------------------------------------------------------# + rgbout = data.table( x = seq(from=0,to=1,length.out=n) ) + rgbout$red = round(pmax(0,pmin(255,f.red (rgbout$x)))) + rgbout$green = round(pmax(0,pmin(255,f.green(rgbout$x)))) + rgbout$blue = round(pmax(0,pmin(255,f.blue (rgbout$x)))) + #---------------------------------------------------------------------------------------# + + + #------ Colour rainbow. ----------------------------------------------------------------# + ans = with(rgbout,rgb(red=red,green=green,blue=blue,maxColorValue=255)) + return(ans) + #---------------------------------------------------------------------------------------# +}#end colour.interpol +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/commonest.r b/R-utils/commonest.r index 5431722fa..57b82a993 100644 --- a/R-utils/commonest.r +++ b/R-utils/commonest.r @@ -8,7 +8,7 @@ commonest <<- function(x,na.rm=FALSE) { unique.x = unique(x) nu = length(unique.x) idx = which.max(tabulate(match(x, unique.x))) - fine = is.finite(idx) && idx %>=% 1 && idx %<=% nu + fine = is.finite(idx) && idx %ge% 1 && idx %le% nu if (fine){ often = unique.x[idx] }else{ @@ -30,9 +30,9 @@ commonest <<- function(x,na.rm=FALSE) { weighted.commonest <<- function(x,w,na.rm=FALSE) { #------ Discard NA entries. ------------------------------------------------------------# if (na.rm){ - keep = (! is.na(x)) & (w %>% 0) + keep = (! is.na(x)) & (w %gt% 0) }else{ - keep = w %>% 0 + keep = w %gt% 0 }#end if (na.rm) #---------------------------------------------------------------------------------------# diff --git a/R-utils/coord.utils.r b/R-utils/coord.utils.r index 9583dde7e..1314931b5 100644 --- a/R-utils/coord.utils.r +++ b/R-utils/coord.utils.r @@ -471,7 +471,7 @@ dec2dms <<- function(lon=NULL,lat=NULL){ degree = sprintf("%3i" ,floor(abs(lon)) ) minute = sprintf("%2.2i",floor(abs(lon) %% 1 * 60) ) second = sprintf("%2.2i",floor((abs(lon) %% 1 * 60) %% 1 * 60)) - hemisf = ifelse(lon %>=% 0,"E","W") + hemisf = ifelse(lon %ge% 0,"E","W") olon = paste0(degree,"-",minute,"\'",second,"\"",hemisf) olon = ifelse(is.finite(lon),olon,NA_character_) }else{ @@ -486,7 +486,7 @@ dec2dms <<- function(lon=NULL,lat=NULL){ degree = sprintf("%2i" ,floor(abs(lat)) ) minute = sprintf("%2.2i",floor(abs(lat) %% 1 * 60) ) second = sprintf("%2.2i",floor((abs(lat) %% 1 * 60) %% 1 * 60)) - hemisf = ifelse(lat %>=% 0,"N","S") + hemisf = ifelse(lat %ge% 0,"N","S") olat = paste0(degree,"-",minute,"\'",second,"\"",hemisf) olat = ifelse(is.finite(lat),olat,NA_character_) }else{ diff --git a/R-utils/curve.features.r b/R-utils/curve.features.r index 4a4fdf080..a8b48d358 100644 --- a/R-utils/curve.features.r +++ b/R-utils/curve.features.r @@ -15,14 +15,13 @@ curve.features <<- function( x , span = 3L , do.pad = TRUE , xscale = max(abs(x),na.rm=TRUE) - , toler = 10000. * .Machine$double.eps - , toler2 = 100. * .Machine$double.eps + , toler = 1.e-4 ){ #----- Make sure span is odd. ----------------------------------------------------------# span = as.integer(span) - if ( ! ((span %% 2) %==% 1 && span %>=% 3L)){ + if ( ! ((span %% 2) %eq% 1 && span %ge% 3L)){ stop(paste0(" Invalid span (",span,")! It must be an odd number (3 or greater)!")) - }#end if ( ! ((span %% 2) %==% 1)) + }#end if ( ! ((span %% 2) %eq% 1)) #---------------------------------------------------------------------------------------# @@ -41,7 +40,7 @@ curve.features <<- function( x #---------------------------------------------------------------------------------------# # Make sure that x can be normalised by the given scale. # #---------------------------------------------------------------------------------------# - if (xscale %>% 0.){ + if (xscale %gt% 0.){ x = x / xscale }else{ stop(paste0("Invalid xscale (",xscale,"). It must be positive.")) @@ -57,12 +56,22 @@ curve.features <<- function( x im1 = pmax(i-1, 1) #----- First derivative. ---------------------------------------------------------------# xp = x[ip1] - x[im1] - xp = ifelse(test=abs(xp) %>=% toler, yes=xp, no = 0.) + xpscale = max(abs(xp),na.rm=TRUE) + if (xpscale %gt% 0.){ + xp = ifelse(test= abs( xp / xpscale ) %ge% toler, yes= xp / xpscale, no = 0.) + }else{ + xp = 0. * xp + }#end if (xpscale %gt% 0.) #----- Second derivative. --------------------------------------------------------------# - xpp = x[ip1] - 2.*x[i] + x[im1] - xpp[1] = xpp[2] - xpp[nx] = xpp[nx-1] - xpp = ifelse(test=abs(xpp) %>=% toler2, yes=xpp, no = 0.) + xpp = x[ip1] - 2.*x[i] + x[im1] + xpp[1] = xpp[2] + xpp[nx] = xpp[nx-1] + xppscale = max(abs(xpp),na.rm=TRUE) + if (xppscale %gt% 0.){ + xpp = ifelse(test= abs( xpp / xppscale ) %ge% toler, yes= xpp / xppscale, no = 0.) + }else{ + xpp = 0. * xpp + }#end if (xppscale %gt% 0.) #---------------------------------------------------------------------------------------# @@ -79,6 +88,7 @@ curve.features <<- function( x # Create an zero matrix to pad the answers. # #---------------------------------------------------------------------------------------# zero = matrix(data=0.,nrow=soff,ncol=span) + x.mat = t(apply(X=rbind(zero,embed(x=x ,dimension=span),zero),MARGIN=1,FUN=rev)) xp.mat = t(apply(X=rbind(zero,embed(x=xp ,dimension=span),zero),MARGIN=1,FUN=rev)) xpp.mat = t(apply(X=rbind(zero,embed(x=xpp,dimension=span),zero),MARGIN=1,FUN=rev)) #---------------------------------------------------------------------------------------# @@ -102,30 +112,83 @@ curve.features <<- function( x xpp.left = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "left" ) xpp.right = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "right" ) xpp.both = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "all" ) - #----- Make sure we only select one element in the neighbourhood. ----------------------# - xp.zeroest = apply( X = abs(xp.mat[,smid]) < abs(xp.mat[,-smid,drop=FALSE]) - , MARGIN = 1 - , FUN = all - )#end apply - xpp.zeroest = apply( X = abs(xpp.mat[,smid]) < abs(xpp.mat[,-smid,drop=FALSE]) - , MARGIN = 1 - , FUN = all - )#end apply #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # Find maxima. # + # Find features. # #---------------------------------------------------------------------------------------# - ans = data.frame( max = xp.zeroest & xp.left*xp.right == -1 & xpp.both == -1 - , min = xp.zeroest & xp.left*xp.right == -1 & xpp.both == +1 - , iph = xpp.zeroest & xpp.left*xpp.right == -1 & xpp.left*xp.both == -1 - , ipv = xpp.zeroest & xpp.left*xpp.right == -1 & xpp.left*xp.both == +1 + ans = data.frame( max = xp.left*xp.right == -1 & xpp.both == -1 + , min = xp.left*xp.right == -1 & xpp.both == +1 + , iph = xpp.left*xpp.right == -1 & xpp.left*xp.both == -1 + , ipv = xpp.left*xpp.right == -1 & xpp.left*xp.both == +1 )#end data.frame #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # It is often the case that neighbouring cells are selected. In this case we # + # only keep one in the neighbourhood. # + #---------------------------------------------------------------------------------------# + #---- Maximum. Pick the maximum in the immediate vicinity. -----------------------------# + imax = which(ans$max) + if (length(imax) > 1){ + xtest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xoff = x[imax+o] + xoff = ifelse(test=(imax+o) %in% imax,yes=xoff,no=-Inf) + xtest = cbind(xtest,xoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xrefr = apply(X=xtest[,-smid],MARGIN=1,FUN=max) + iskip = xtest[,smid] < xrefr + ans$max[imax[iskip]] = FALSE + }#end if (length(imax) > 1) + #---- Minimum. Pick the minimum in the immediate vicinity. -----------------------------# + imin = which(ans$min) + if (length(imin) > 1){ + xtest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xoff = x[imin+o] + xoff = ifelse(test=(imin+o) %in% imin,yes=xoff,no=+Inf) + xtest = cbind(xtest,xoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xrefr = apply(X=xtest[,-smid],MARGIN=1,FUN=min) + iskip = xtest[,smid] > xrefr + ans$min[imin[iskip]] = FALSE + }#end if (length(imin) > 1) + #---- Horizontal inflection point. Pick the flattest point in the immediate vicinity. -# + iiph = which(ans$iph) + if (length(iiph) > 1){ + xptest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xpoff = xp[iiph+o] + xpoff = ifelse(test=(iiph+o) %in% iiph,yes=xpoff,no=+Inf) + xptest = cbind(xptest,xpoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xprefr = apply(X=abs(xptest[,-smid]),MARGIN=1,FUN=min) + iskip = abs(xptest[,smid]) > xprefr + ans$iph[iiph[iskip]] = FALSE + }#end if (length(iiph) > 1) + #---- Vertical inflection point. Pick the steepest point in the immediate vicinity. ---# + iipv = which(ans$ipv) + if (length(iipv) > 1){ + xptest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xpoff = xp[iipv+o] + xpoff = ifelse(test=(iipv+o) %in% iipv,yes=xpoff,no=0.) + xptest = cbind(xptest,xpoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xprefr = apply(X=abs(xptest[,-smid]),MARGIN=1,FUN=max) + iskip = abs(xptest[,smid]) < xprefr + ans$ipv[iipv[iskip]] = FALSE + }#end if (length(iipv) > 1) + #---------------------------------------------------------------------------------------# + + + + #----- Flag edges as inflection points in case their first derivative is not zero. -----# ans$iph[ 1] = ans$max[ 1] || (xp.right[ 1] == -1) ans$iph[nx] = ans$max[nx] || (xp.left [nx] == +1) diff --git a/R-utils/del.bad.rshort.r b/R-utils/del.bad.rshort.r index 4e5383ecb..0e4f95287 100644 --- a/R-utils/del.bad.rshort.r +++ b/R-utils/del.bad.rshort.r @@ -115,7 +115,7 @@ del.bad.rshort <<- function(dat,rshort.day.min=0.,par.frac.min=0.80,alb.max=0.30 #---------------------------------------------------------------------------------------# # We don't let radiation exceed maximum. # #---------------------------------------------------------------------------------------# - cat (" - Ensure daytime radiation does not exceed maximum.") + cat0(" - Ensure daytime radiation does not exceed maximum.") dat$rshort.in[dat$daytime] = pmin(dat$rshort.in[dat$daytime],dat$rshort.pot[dat$daytime]) dat$par.in [dat$daytime] = pmin(dat$par.in [dat$daytime],dat$par.pot [dat$daytime]) #---------------------------------------------------------------------------------------# diff --git a/R-utils/del.outliers.r b/R-utils/del.outliers.r index 7749fd482..99d206fa9 100644 --- a/R-utils/del.outliers.r +++ b/R-utils/del.outliers.r @@ -102,9 +102,9 @@ del.outliers <<- function( x # Vector to be evaluated # Discard suspicious data. # #---------------------------------------------------------------------------------# is.infty = is.infinite(thisnorm) - is.unreal = abs(thisnorm ) %>% max.real - is.outlier = abs(thisnorm ) %>% max.fine - is.spike = abs(thisnorm-neigh.norm) %>=% spike.min + is.unreal = abs(thisnorm ) %gt% max.real + is.outlier = abs(thisnorm ) %gt% max.fine + is.spike = abs(thisnorm-neigh.norm) %ge% spike.min weird = is.infty | is.unreal | (is.outlier & is.spike) thisvar[weird] = NA_real_ nweird = sum(weird) @@ -191,9 +191,9 @@ del.outliers <<- function( x # Vector to be evaluated # Discard suspicious data. # #---------------------------------------------------------------------------------# is.infty = is.infinite(thisnorm) - is.unreal = abs(thisnorm ) %>% max.real - is.outlier = abs(thisnorm ) %>% max.fine - is.spike = abs(thisnorm-neigh.norm) %>=% spike.min + is.unreal = abs(thisnorm ) %gt% max.real + is.outlier = abs(thisnorm ) %gt% max.fine + is.spike = abs(thisnorm-neigh.norm) %ge% spike.min weird = is.infty | is.unreal | (is.outlier & is.spike) thisvar[weird] = NA_real_ nweird = sum(weird) diff --git a/R-utils/demography.rates.r b/R-utils/demography.rates.r index e421197b0..deacd47c2 100644 --- a/R-utils/demography.rates.r +++ b/R-utils/demography.rates.r @@ -834,7 +834,7 @@ acc.recruitment.rate <<- function( property expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -886,7 +886,7 @@ acc.recruitment.rate <<- function( property expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1061,7 +1061,7 @@ acc.mortality.rate <<- function( property expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1113,7 +1113,7 @@ acc.mortality.rate <<- function( property expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1188,7 +1188,7 @@ acc.growth.rate <<- function(nok,lok,pop,gpop=pop,dtime,taxon,R=100,itb.max=50){ expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1218,7 +1218,7 @@ acc.growth.rate <<- function(nok,lok,pop,gpop=pop,dtime,taxon,R=100,itb.max=50){ expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# diff --git a/R-utils/density.safe.r b/R-utils/density.safe.r index 58702a79e..7c0601d3f 100644 --- a/R-utils/density.safe.r +++ b/R-utils/density.safe.r @@ -49,7 +49,7 @@ density.safe <<- function( x }else{ #----- Select the valid x and e values. ---------------------------------------------# - sel = x %>% 0 & e %>=% 0 + sel = (x %gt% 0) & (e %ge% 0) n.x.use = sum(sel) #------------------------------------------------------------------------------------# @@ -104,16 +104,16 @@ density.safe <<- function( x # (for example, negative CO2 concentration). # #---------------------------------------------------------------------------------------# if (is.finite(xmin)){ - bye = ans$x %<% xmin + bye = ans$x %lt% xmin xadd = min(ans$x[! bye],na.rm=TRUE) - iadd = which(ans$x %==% xadd) + iadd = which(ans$x %eq% xadd) ans$y[iadd] = ans$y[iadd] + sum(ans$y[bye]) ans$y[bye ] = 0. }#end if(is.finite(xmin)) if (is.finite(xmax)){ - bye = ans$x %>% xmax + bye = ans$x %gt% xmax xadd = max(ans$x[! bye],na.rm=TRUE) - iadd = which(ans$x %==% xadd) + iadd = which(ans$x %eq% xadd) ans$y[iadd] = ans$y[iadd] + sum(ans$y[bye]) ans$y[bye ] = 0. }#end if(is.finite(xmax)) diff --git a/R-utils/desc.unit.r b/R-utils/desc.unit.r index ca646d470..fa52af9c3 100644 --- a/R-utils/desc.unit.r +++ b/R-utils/desc.unit.r @@ -3,7 +3,7 @@ # This function creates an expression object that has the description and the units # # with sub-scripts, superscripts and stuff. # #------------------------------------------------------------------------------------------# -desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE){ +desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE,twolines=FALSE){ if (missing(desc) | missing(unit)){ cat(" - Missing \"desc\": ",missing(desc),"\n") cat(" - Missing \"unit\": ",missing(unit),"\n") @@ -26,14 +26,25 @@ desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE){ }#end if }else{ if (dxpr){ - if (bracket){ + if (bracket && twolines){ + answer = parse(text=paste0("atop(",desc,",paste(\"[\",",unit,",\"]\"))")) + }else if (bracket){ answer = parse(text=paste0("paste(",desc,",\" [\",",unit,",\"]\")")) + }else if (twolines){ + answer = parse(text=paste0("atop(",desc,",",unit,")")) }else{ answer = parse(text=paste0("paste(",desc,",\" \",",unit,",\"\")")) }#end if }else{ - if (bracket){ + if (bracket && twolines){ + answer = parse( text=paste0( "atop(paste(\"",desc,"\")," + , "paste(\"[\",",unit,",\"]\"))" + )#end paste0 + )#end paste + }else if (bracket){ answer = parse(text=paste0("paste(\"",desc,"\",\" [\",",unit,",\"]\")")) + }else if (twolines){ + answer = parse(text=paste0("atop(paste(\"",desc,"\"),paste(\"",unit,"\"))")) }else{ answer = parse(text=paste0("paste(\"",desc,"\",\" \",",unit,",\"\")")) }#end if diff --git a/R-utils/dynamics.proofer.r b/R-utils/dynamics.proofer.r index 7a9e9dd0e..4981c883a 100644 --- a/R-utils/dynamics.proofer.r +++ b/R-utils/dynamics.proofer.r @@ -84,7 +84,7 @@ death.proofer <<- function( datum # Forest inventory data set for (y in sequence(n.years)){ this.dead = paste(dead.pref,year4[y],sep=vsep) if (this.dead %in% names(datum)){ - sel = as.numeric(datum[[this.dead]]) %==% 1 + sel = as.numeric(datum[[this.dead]]) %eq% 1 datum$year.death[sel] = pmin(datum$year.death[sel],year4[y]) }#end if (this.dead %in% names(datum)) #---------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ death.proofer <<- function( datum # Forest inventory data set for (y in sequence(n.years)){ this.dbh = paste(dbh.pref ,year4[y],sep=vsep) alive = ( is.finite(datum[[this.dbh]]) - & datum$year.death %<=% year4[y] + & datum$year.death %le% year4[y] )#end alive datum$year.death[alive] = next.year[y] #---------------------------------------------------------------------------------# @@ -966,7 +966,7 @@ dbh.gap.filler <<- function( datum #----- Find out whether to fill the data. -------------------------------------------# - dbh.miss = is.na(datum[[dbh.label]]) | datum[[dbh.label]] %<% 0 + dbh.miss = is.na(datum[[dbh.label]]) | datum[[dbh.label]] %lt% 0 if (any(is.na(dbh.miss))){ cat0(" dbh.miss has NA!") }#end if @@ -979,7 +979,7 @@ dbh.gap.filler <<- function( datum # been taken care of before, but after discarding some bad measurements a few other # # pre-recruitment points may appear. # #------------------------------------------------------------------------------------# - bye = datum[[dbh.label]] %>% 0 & is.na(dbh.table[,y]) + bye = datum[[dbh.label]] %gt% 0 & is.na(dbh.table[,y]) message = paste0(dbh.label,"=",abs(datum[[dbh.label]]) ," is pre-recruitment thus removed",sep="") datum[[notes.label]][bye] = concatenate.message(datum[[notes.label]][bye] @@ -1045,8 +1045,8 @@ dbh.gap.filler <<- function( datum # Choose the years to update. It has to be NA and it has to be post- # # recruitment to be accepted. # #------------------------------------------------------------------------------------# - is.recruited = ( dbh.guess %>% ( dbh.min + dbh.min.toler ) - | datum[[dbh.label]] %>=% dbh.min + is.recruited = ( dbh.guess %gt% ( dbh.min + dbh.min.toler ) + | datum[[dbh.label]] %ge% dbh.min | datum$year.recruit <= year4[y] ) is.alive = datum$year.death > year4[y] update.year = dbh.miss & is.recruited & is.alive diff --git a/R-utils/elliptical.utils.r b/R-utils/elliptical.utils.r index f321a9772..a048d6d92 100644 --- a/R-utils/elliptical.utils.r +++ b/R-utils/elliptical.utils.r @@ -5,16 +5,16 @@ elliptical.radius <<- function(x,y,theta,degrees=FALSE){ if (degrees) theta = theta * pio180 - both.zero = x %==% 0 & y %==% 0 - x.zero = x %==% 0 & y %!=% 0 - y.zero = x %!=% 0 & y %==% 0 + both.zero = (x %eq% 0) & (y %eq% 0) + x.zero = (x %eq% 0) & (y %ne% 0) + y.zero = (x %ne% 0) & (y %eq% 0) x[x.zero] = sqrt(.Machine$double.eps) * y[x.zero] y[y.zero] = sqrt(.Machine$double.eps) * x[y.zero] - ans = ifelse( both.zero - , 0 - , x*y / sqrt(y*y*(cos(theta))^2+x*x*(sin(theta))^2) + ans = ifelse( test = both.zero + , yes = 0 + , no = x*y / sqrt(y*y*(cos(theta))^2+x*x*(sin(theta))^2) )#end ifelse return(ans) @@ -36,9 +36,9 @@ elliptical.area <<- function(x,y,theta0=0,theta1=2*pi,degrees=FALSE){ theta1 = theta1 * pio180 }#end if - both.zero = x %==% 0 & y %==% 0 - x.zero = x %==% 0 & y %!=% 0 - y.zero = x %!=% 0 & y %==% 0 + both.zero = ( x %eq% 0 ) & ( y %eq% 0 ) + x.zero = ( x %eq% 0 ) & ( y %ne% 0 ) + y.zero = ( x %ne% 0 ) & ( y %eq% 0 ) x[x.zero] = sqrt(.Machine$double.eps) * y[x.zero] y[y.zero] = sqrt(.Machine$double.eps) * x[y.zero] diff --git a/R-utils/entropy.r b/R-utils/entropy.r new file mode 100644 index 000000000..a795ab0bd --- /dev/null +++ b/R-utils/entropy.r @@ -0,0 +1,142 @@ +#==========================================================================================# +#==========================================================================================# +# Functions to help computing entropy fluxes. Most of the theory can be found in the # +# following papers. # +# # +# Quijano JC , Lin H. 2015. Is spatially integrated entropy production useful to predict # +# the dynamics of ecosystems? Ecol. Model., 313: 341-354. # +# doi:10.1016/j.ecolmodel.2015.06.012 (QJ15). # +# # +# Wright SE, Scott DS, Haddow JB , Rosen MA. 2001. On the entropy of radiative heat # +# transfer in engineering thermodynamics. Int. J. Eng. Sci., 39: 1691-1706. # +# doi:10.1016/S0020-7225(01)00024-6 (W01). # +# # +# Wu W , Liu Y. 2010. Radiation entropy flux and entropy production of the Earth system. # +# Rev. Geophys., 48: RG2003. doi:10.1029/2008RG000275 (WL10). # +# # +#------------------------------------------------------------------------------------------# + + +#------ Handy constants. ------------------------------------------------------------------# +w01.rf.sbeam <<- 2.31e-4 * tsun +w01.c0 <<- -45 / (4. * pi^4) +w01.c1 <<- +2.336 +w01.c2 <<- -0.260 +w01.rpfac <<- 4./3. +emis.atm <<- 0.85 # From Brunsell et al. (2011) +emis.sfc <<- 0.98 # From ED2 +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to shortwave radiation, following Q15, # +# who base their formulation on WL10 (which is done for the top of the atmosphere). This # +# assumes that albedo is the same for direct and diffuse radiation, and that all reflected # +# radiation is diffuse. # +#------------------------------------------------------------------------------------------# +fxentropy.rshort <<- function(rsdnwd,rswnet,rsbeam){ + + #----- Find derived radiation properties. ----------------------------------------------# + rsdiff = 0. * rsdnwd + pmax(0.,rsdnwd - rsbeam) # Diffuse radiation as residual + rsupwd = pmax(0.,rsdnwd - rswnet) # Upward radiation + albedo = 0. * rsdnwd + ifelse( test = rsdnwd %gt% 0. # Albedo + , yes = rsupwd / rsdnwd # + , no = 0.1 # + )#end ifelse # + #---------------------------------------------------------------------------------------# + + + + #----- Entropy due to direct radiation. ------------------------------------------------# + fs.rsbeam = w01.rf.sbeam * (1. - albedo) * rsbeam / tsun + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation. -----------------------------------------------# + delta = rsdiff / pi / radsol + rf.rsdiff = ifelse( test = delta %gt% 0. + , yes = ( w01.c0 * ( w01.c1 + w01.c2 * delta) * log(delta) + 1. ) + * w01.rpfac + , no = 0. + )#end ifelse + fs.rsdiff = rf.rsdiff * (1. - albedo) * rsdiff / tsun + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Total entropy flux due to solar radiation. # + #---------------------------------------------------------------------------------------# + ans = fs.rsbeam + fs.rsdiff + return(ans) + #---------------------------------------------------------------------------------------# +}#end sflux.rshort +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to downwelling longwave radiation, follow- # +# ing Q15, who base their formulation on WL10 and W01. Two differences from their # +# approach: # +# 1. We don't use the air temperature, but the equivalent atmospheric temperature, similar # +# to H10 (unless the user provides atmospheric temperature, in which case their values # +# take priority). # +# 2. We also account for the small amount of downwelling LW irradiance that is not # +# absorbed, using Kirchhoff's law. # +#------------------------------------------------------------------------------------------# +fxentropy.rldnwd <<- function(rldnwd,tatm.k){ + + #----- Find derived radiation properties. ----------------------------------------------# + if (missing(tatm.k)){ + tatm.k = sqrt(sqrt(rldnwd / (emis.atm * stefan))) + }#end if (missing(tsfc.k)) + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation (note we add the "LW albedo"). -----------------# + epsil = emis.atm + rf.rldnwd = ( w01.c0 * ( w01.c1 + w01.c2 * epsil) * log(epsil) + 1. ) * w01.rpfac + fs.rldnwd = rf.rldnwd * emis.sfc * rldnwd / tatm.k + #---------------------------------------------------------------------------------------# + + return(fs.rldnwd) + #---------------------------------------------------------------------------------------# +}#end sflux.rldnwd +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to upwelling longwave radiation, following # +# Q15, who base their formulation on WL10 and W01. Because skin temperature may be # +# available, we use that instead of calculating in here (unless skin temperature is not # +# provided). # +#------------------------------------------------------------------------------------------# +fxentropy.rlupwd <<- function(rlupwd,tsfc.k){ + + #----- Find derived radiation properties. ----------------------------------------------# + if (missing(tsfc.k)){ + tsfc.k = sqrt(sqrt(rlupwd / (emis.sfc * stefan))) + }#end if (missing(tsfc.k)) + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation (note we add the "LW albedo"). -----------------# + epsil = emis.sfc + rf.rlupwd = ( w01.c0 * ( w01.c1 + w01.c2 * epsil) * log(epsil) + 1. ) * w01.rpfac + fs.rlupwd = rf.rlupwd * rlupwd / tsfc.k + #---------------------------------------------------------------------------------------# + + return(fs.rlupwd) + #---------------------------------------------------------------------------------------# +}#end sflux.rlupwd +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/epolygon.r b/R-utils/epolygon.r index df955beb2..e0dec5726 100644 --- a/R-utils/epolygon.r +++ b/R-utils/epolygon.r @@ -47,19 +47,14 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL if (end > start) { den = density[i] if (is.na(den) || den < 0){ - if (R.Version()$major == "3"){ - polygon( x = xy$x[start:(end - 1)] - , y = xy$y[start:(end - 1)] - , col = col[i] - , border = NA - , density = den - , lty = lty[i] - , ... - )#end polygon - }else{ - .Internal(polygon( xy$x[start:(end - 1)] - , xy$y[start:(end - 1)], col[i], NA, lty[i], ...)) - }#end if + polygon( x = xy$x[start:(end - 1)] + , y = xy$y[start:(end - 1)] + , col = col[i] + , border = NA + , density = den + , lty = lty[i] + , ... + )#end polygon }else if (den > 0) { epolygon.fullhatch( x = xy$x[start:(end - 1)] , y = xy$y[start:(end - 1)] @@ -77,18 +72,16 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL }#end if start = end + 1 }#end for - if (R.Version()$major == "3"){ - polygon( x = xy$x - , y = xy$y - , density = 0 - , col = NA - , border = border - , lty = lty - , ... - )#end polygon - }else{ - .Internal(polygon(xy$x, xy$y, NA, border, lty, ...)) - }#end if + + polygon( x = xy$x + , y = xy$y + , density = 0 + , col = NA + , border = border + , lty = lty + , ... + )#end polygon + }else{ if (is.logical(border)) { if (!is.na(border) && border){ @@ -98,18 +91,15 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL }#end if }#end if - if (R.Version()$major == "3"){ - polygon( x = xy$x - , y = xy$y - , density = NULL - , col = col - , border = border - , lty = lty - , ... - )#end polygon - }else{ - .Internal(polygon(xy$x, xy$y, col, border, lty, ...)) - }#end if + polygon( x = xy$x + , y = xy$y + , density = NULL + , col = col + , border = border + , lty = lty + , ... + )#end polygon + }#end if }#end function #==========================================================================================# diff --git a/R-utils/fuse.fiss.utils.r b/R-utils/fuse.fiss.utils.r index 12d330bc4..4224c50d4 100644 --- a/R-utils/fuse.fiss.utils.r +++ b/R-utils/fuse.fiss.utils.r @@ -250,15 +250,21 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ #---------------------------------------------------------------------------------# - }else if ( length(grep(pattern="dead." ,x=vname)) > 0 - || length(grep(pattern="canopy." ,x=vname)) > 0 - || length(grep(pattern="height." ,x=vname)) > 0 - || length(grep(pattern="band." ,x=vname)) > 0 - || length(grep(pattern="pom." ,x=vname)) > 0 - || length(grep(pattern="ladder" ,x=vname)) > 0 - || length(grep(pattern="cnpj" ,x=vname)) > 0 - || length(grep(pattern="soil" ,x=vname)) > 0 - || length(grep(pattern="code" ,x=vname)) > 0 + }else if ( any(grepl(pattern="dead." ,x=vname)) + || any(grepl(pattern="canopy." ,x=vname)) + || any(grepl(pattern="height." ,x=vname)) + || any(grepl(pattern="band." ,x=vname)) + || any(grepl(pattern="pom." ,x=vname)) + || any(grepl(pattern="ladder" ,x=vname)) + || any(grepl(pattern="cnpj" ,x=vname)) + || any(grepl(pattern="soil" ,x=vname)) + || any(grepl(pattern="code" ,x=vname)) + || any(grepl(pattern="plant.ID" ,x=vname)) + || any(grepl(pattern="voucher.number",x=vname)) + || any(grepl(pattern="status" ,x=vname)) + || any(grepl(pattern="tax.reliab" ,x=vname)) + || any(grepl(pattern="flag" ,x=vname)) + || any(grepl(pattern="n.tag" ,x=vname)) ){ #---- Variables that we update only if they have NA. -----------------------------# sel = ( is.na(receptor[[vname]]) @@ -332,7 +338,7 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ }else{ #----- Missing instructions, quit... ---------------------------------------------# - cat (" * VARIABLE: ",vname," has no instrucion!","\n") + cat (" * VARIABLE: ",vname," has no instruction!","\n") stop("Could not process the variable, sorry!") #---------------------------------------------------------------------------------# }#end if @@ -351,19 +357,25 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ #==========================================================================================# #==========================================================================================# -# Function blend.trees # +# Function merge.trees # # # -# This function blends one tree to the other. This is slightly different from the # -# fusion routine above because blending adds information but compares the periods for # +# This function merges one tree to the other. This is slightly different from the # +# fusion routine above because merging adds information but compares the periods for # # which information is to be added. The other difference is that IT CANNOT BE USED IN # # VECTOR MODE: it works between one donor and one receptor only. # # # # receptor -- The data frame that will receive the data # # donor -- The data frame that will send the data # -# don.2.rec -- The indices of the receptor that will receive the data. # -# update.yr.notes -- Should we use notes.orig to make year notes? (TRUE/FALSE). # +# years.merge -- Years to merge data. # +# use.xy -- Variable to force using either donor ("from") or receptor ("to") # +# coordinate information. Default (NA_character_) is to check for # +# merged year and data availability. # +# use.tag -- Variable to force using either donor ("from") or receptor ("to") # +# tag information. Default (NA_character_) is to check for # +# merged year and data availability. # #------------------------------------------------------------------------------------------# -blend.trees = function(receptor,donor,years.blend){ +merge.trees = function(receptor,donor,years.merge + ,use.xy=NA_character_,use.tag=NA_character_){ #---------------------------------------------------------------------------------------# # Get the list of all variables. # @@ -394,7 +406,7 @@ blend.trees = function(receptor,donor,years.blend){ vname = variables[nv] old = paste("old",vname,sep=".") first = paste(vname,"1st",sep=".") - blend.input = paste(substring(vname,1,nchar(vname)-5),years.blend,sep=".") + merge.input = paste(substring(vname,1,nchar(vname)-5),years.merge,sep=".") #------------------------------------------------------------------------------------# @@ -402,16 +414,17 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------------# # Decide what to do based on the variable. # #------------------------------------------------------------------------------------# - if ( length(grep(pattern="trans" ,x=vname)) > 0 || - length(grep(pattern="full.tag" ,x=vname)) > 0 || - length(grep(pattern="old." ,x=vname)) > 0 || - length(grep(pattern=".1st" ,x=vname)) > 0 || - length(grep(pattern="scientific",x=vname)) > 0 || - length(grep(pattern="genus" ,x=vname)) > 0 || - length(grep(pattern="family" ,x=vname)) > 0 || - length(grep(pattern="year.last" ,x=vname)) > 0 || - length(grep(pattern="cnpj" ,x=vname)) > 0 || - length(grep(pattern="conflict." ,x=vname)) > 0){ + if ( any(grepl(pattern="trans" ,x=vname)) || + any(grepl(pattern="full.tag" ,x=vname)) || + any(grepl(pattern="old." ,x=vname)) || + any(grepl(pattern=".1st" ,x=vname)) || + any(grepl(pattern="scientific",x=vname)) || + any(grepl(pattern="genus" ,x=vname)) || + any(grepl(pattern="family" ,x=vname)) || + any(grepl(pattern="year.last" ,x=vname)) || + any(grepl(pattern="cnpj" ,x=vname)) || + any(grepl(pattern="conflict." ,x=vname)) + ){ #---------------------------------------------------------------------------------# # We skip these variables. # #---------------------------------------------------------------------------------# @@ -422,7 +435,7 @@ blend.trees = function(receptor,donor,years.blend){ }else if (vname %in% c("year.added")){ #---- We always keep the lowest value. -------------------------------------------# - receptor$year.added = min(receptor$year.added,min(years.blend)) + receptor$year.added = min(receptor$year.added,min(years.merge)) #---------------------------------------------------------------------------------# @@ -440,16 +453,17 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# - }else if (vname %in% c("tag","x","y")){ + }else if (vname %in% c("x","y")){ #---------------------------------------------------------------------------------# - # We will consider changing the values only if the donor has information. # + # We will consider changing the values only if the donor has information or # + # if we have clear instructions of what to do. # #---------------------------------------------------------------------------------# - if (! is.na(donor[[vname]])){ + if (is.na(use.xy) && (! is.na(donor[[vname]]))){ #------------------------------------------------------------------------------# # We update coordinates only if the last year of the original dataset was # - # less than the years we are blending. # + # less than the years we are merging. # #------------------------------------------------------------------------------# - if ( ( ( max(years.blend) > receptor$year.last ) + if ( ( ( max(years.merge) > receptor$year.last ) && ( receptor[[vname]] != donor[[vname]] ) ) || is.na(receptor[[vname]]) ){ receptor[[old ]] = receptor[[vname]] @@ -459,16 +473,83 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# - # We don't change the "1st" variables unless the data we are blending is # + # We don't change the "1st" variables unless the data we are merging is # # older than the first year the receptor has data. # #------------------------------------------------------------------------------# - if ( ( ( min(years.blend) < receptor$year.1st ) + if ( ( ( min(years.merge) < receptor$year.1st ) && ( receptor[[vname]] != donor[[vname]] ) ) || is.na(receptor[[vname]]) ){ receptor[[first]] = donor[[first]] }#end if #------------------------------------------------------------------------------# - }#end if + }else if (use.xy %in% "from"){ + #------------------------------------------------------------------------------# + # Set coordinates based on donor. # + #------------------------------------------------------------------------------# + receptor[[vname]] = donor[[vname]] + receptor[[old ]] = donor[[old ]] + receptor[[first]] = donor[[first]] + #------------------------------------------------------------------------------# + }else if (use.xy %in% "to"){ + #------------------------------------------------------------------------------# + # Set coordinates based on receptor. Dummy commands, no need to do # + # anything. # + #------------------------------------------------------------------------------# + receptor[[vname]] = receptor[[vname]] + receptor[[old ]] = receptor[[old ]] + receptor[[first]] = receptor[[first]] + #------------------------------------------------------------------------------# + }#end if (is.na(use.xy) && (! is.na(donor[[vname]]))) + #---------------------------------------------------------------------------------# + + + }else if (vname %in% c("tag")){ + #---------------------------------------------------------------------------------# + # We will consider changing the values only if the donor has information or # + # if we have clear instructions of what to do. # + #---------------------------------------------------------------------------------# + if (is.na(use.tag) && (! is.na(donor[[vname]]))){ + #------------------------------------------------------------------------------# + # We update coordinates only if the last year of the original dataset was # + # less than the years we are merging. # + #------------------------------------------------------------------------------# + if ( ( ( max(years.merge) > receptor$year.last ) + && ( receptor[[vname]] != donor[[vname]] ) ) + || is.na(receptor[[vname]]) ){ + receptor[[old ]] = receptor[[vname]] + receptor[[vname]] = donor [[vname]] + }#end if + #------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------# + # We don't change the "1st" variables unless the data we are merging is # + # older than the first year the receptor has data. # + #------------------------------------------------------------------------------# + if ( ( ( min(years.merge) < receptor$year.1st ) + && ( receptor[[vname]] != donor[[vname]] ) ) + || is.na(receptor[[vname]]) ){ + receptor[[first]] = donor[[first]] + }#end if + #------------------------------------------------------------------------------# + }else if (use.tag %in% "from"){ + #------------------------------------------------------------------------------# + # Set coordinates based on donor. # + #------------------------------------------------------------------------------# + receptor[[vname]] = donor[[vname]] + receptor[[old ]] = donor[[old ]] + receptor[[first]] = donor[[first]] + #------------------------------------------------------------------------------# + }else if (use.tag %in% "to"){ + #------------------------------------------------------------------------------# + # Set coordinates based on receptor. Dummy commands, no need to do # + # anything. # + #------------------------------------------------------------------------------# + receptor[[vname]] = receptor[[vname]] + receptor[[old ]] = receptor[[old ]] + receptor[[first]] = receptor[[first]] + #------------------------------------------------------------------------------# + }#end if (is.na(use.tag) && (! is.na(donor[[vname]]))) #---------------------------------------------------------------------------------# @@ -528,7 +609,7 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# # Check whether we update the common name. # #------------------------------------------------------------------------------# - if ( receptor$year.last < max(years.blend) ){ + if ( receptor$year.last < max(years.merge) ){ copy.common = ! donor.c.ignotum update.old = ( copy.common && (! receptor.c.ignotum) && receptor$common != donor$common ) @@ -541,7 +622,7 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# # Check whether the donor first name is older than the receptor one. # #------------------------------------------------------------------------------# - if ( receptor$year.1st > min(years.blend) ){ + if ( receptor$year.1st > min(years.merge) ){ if ( ! donor.f.ignotum ){ receptor$common.1st = donor$common.1st }#end if @@ -600,9 +681,9 @@ blend.trees = function(receptor,donor,years.blend){ || ( length(grep(pattern="notes.",x=vname)) > 0 && ! vname %in% c("notes.orig","notes.qaqc") ) ){ #---------------------------------------------------------------------------------# - # Variables that we update only if this is the blending year. # + # Variables that we update only if this is the merging year. # #---------------------------------------------------------------------------------# - if (vname %in% blend.input && (! is.na(donor[[vname]]))){ + if (vname %in% merge.input && (! is.na(donor[[vname]]))){ #----- Copy only the cells that had no info before. ---------------------------# receptor[[vname]] = donor[[vname]] #------------------------------------------------------------------------------# @@ -612,7 +693,7 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# # For DBH, we also check whether they match in case of overlap, and flag any # - # mismatch for blending years. # + # mismatch for merging years. # #---------------------------------------------------------------------------------# if ( length(grep(pattern="dbh." ,x=vname)) > 0){ dbh.vars = c(dbh.vars,vname) @@ -624,11 +705,18 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# - }else if ( length(grep(pattern="canopy." ,x=vname)) > 0 - || length(grep(pattern="height." ,x=vname)) > 0 - || length(grep(pattern="band." ,x=vname)) > 0 - || length(grep(pattern="pom." ,x=vname)) > 0 - || length(grep(pattern="ladder" ,x=vname)) > 0 + }else if ( any(grepl(pattern="canopy." ,x=vname)) + || any(grepl(pattern="height." ,x=vname)) + || any(grepl(pattern="band." ,x=vname)) + || any(grepl(pattern="pom." ,x=vname)) + || any(grepl(pattern="ladder" ,x=vname)) + || any(grepl(pattern="plant.ID" ,x=vname)) + || any(grepl(pattern="voucher.number",x=vname)) + || any(grepl(pattern="status" ,x=vname)) + || any(grepl(pattern="tax.reliab" ,x=vname)) + || any(grepl(pattern="flag" ,x=vname)) + || any(grepl(pattern="n.tag" ,x=vname)) + ){ #---- Variables that we update only if they have NA. -----------------------------# sel = ( is.na(receptor[[vname]]) @@ -645,7 +733,7 @@ blend.trees = function(receptor,donor,years.blend){ }else{ #----- Missing instructions, quit... ---------------------------------------------# - cat (" * VARIABLE: ",vname," has no instrucion!","\n") + cat (" * VARIABLE: ",vname," has no instruction!","\n") stop("Could not process the variable, sorry!") #---------------------------------------------------------------------------------# }#end if diff --git a/R-utils/globdims.r b/R-utils/globdims.r index 17bf676f4..35a4a64d6 100644 --- a/R-utils/globdims.r +++ b/R-utils/globdims.r @@ -7,7 +7,7 @@ nstyp <<- 17 # Number of default soil types #----- Radiation thresholds. --------------------------------------------------------------# -cosz.min <<- 0.03 # cos(89*pi/180) # Minimum cosine of zenith angle +cosz.min <<- 0.0001 # 0.03 # cos(89*pi/180) # Minimum cosine of zenith angle cosz.highsun <<- cos(84*pi/180) # Zenith angle to not be called sunrise or sunset cosz.twilight <<- cos(96*pi/180) # Cosine of the end of civil twilight fvis.beam.def <<- 0.43 diff --git a/R-utils/gridded.plot.r b/R-utils/gridded.plot.r index 15b91019d..357ff9b31 100644 --- a/R-utils/gridded.plot.r +++ b/R-utils/gridded.plot.r @@ -88,7 +88,7 @@ gridded.plot <<- function( x = seq(from=0,to=1,len=nrow(z)) #----- No messed-up axes are allowed, they must increase. ------------------------------# - if (any(diff(x) %<=% 0) || any(diff(y) %<=% 0)){ + if (any(diff(x) %le% 0) || any(diff(y) %le% 0)){ stop("increasing x and y values expected") }#end if #---------------------------------------------------------------------------------------# @@ -246,7 +246,19 @@ gridded.plot <<- function( x = seq(from=0,to=1,len=nrow(z)) #----- Plot the title. --------------------------------------------------------------# - if (! is.null(key.title)) do.call(what="title",args=key.title) + if (! is.null(key.title)){ + #---- Make sure that the key title will work with multiple configurations. -------# + if (! is.list(key.title)){ + key.title=list(main=key.title) + }else if (! "main" %in% names(key.title)){ + names(key.title)[[1]] = "main" + }#end if + #---------------------------------------------------------------------------------# + + #----- Call the command. ---------------------------------------------------------# + do.call(what="title",args=key.title) + #---------------------------------------------------------------------------------# + }#end if (! is.null(key.title)) #------------------------------------------------------------------------------------# #=======================================================================================# #=======================================================================================# diff --git a/R-utils/image.map.r b/R-utils/image.map.r index 40c99efbe..969f0f4b1 100644 --- a/R-utils/image.map.r +++ b/R-utils/image.map.r @@ -506,8 +506,8 @@ image.map <<- function( x zzz = tapply(X=zzz,INDEX=iii,FUN=mean,na.rm=TRUE) sss = tapply(X=sss,INDEX=iii,FUN=any ,na.rm=TRUE) #----- Generate output mesh. -----------------------------------------------------# - if (! (nx.interp %>% 0)) nx.interp = 10*length(unique(xx)) - if (! (ny.interp %>% 0)) ny.interp = 10*length(unique(yy)) + if (! (nx.interp %gt% 0)) nx.interp = 10*length(unique(xx)) + if (! (ny.interp %gt% 0)) ny.interp = 10*length(unique(yy)) xo = seq(from=0,to=1,length.out=nx.interp) yo = seq(from=0,to=1,length.out=ny.interp) xoyo = expand.grid(xo,yo) diff --git a/R-utils/is.peak.r b/R-utils/is.peak.r index fc89a9eea..eac2a33ee 100644 --- a/R-utils/is.peak.r +++ b/R-utils/is.peak.r @@ -12,7 +12,7 @@ is.peak <<- function( pt.cloud #----- Check whether to use only first returns or all returns. -------------------------# idx.retn = with(pt.cloud, which(retn.number %in% retn.use)) idx.clss = with(pt.cloud, which(pt.class %in% clss.use)) - idx.agnd = with(pt.cloud, which(z %>=% zmin)) + idx.agnd = with(pt.cloud, which(z %ge% zmin)) idx.keep = intersect(idx.clss,intersect(idx.retn,idx.agnd)) #---------------------------------------------------------------------------------------# diff --git a/R-utils/licorfun.r b/R-utils/licorfun.r index 663e1c6da..1b9dc986b 100644 --- a/R-utils/licorfun.r +++ b/R-utils/licorfun.r @@ -154,7 +154,7 @@ comp.photo.tempfun <<- function(thispft,met,quantum.t=FALSE){ ipsII.max = ( aparms$jm * ( 2.0 * thispft$curvpar - 1. - 2.0 * sqrt(thispft$curvpar * (thispft$curvpar-1.0) ) ) ) }else{ - ipsII.max = discard + ipsII.max = huge.num }#end if (thispft$curvpar > 1.) ipsII = min(0.5 * thispft$phi.psII * met$par,ipsII.max) aterm = thispft$curvpar @@ -390,14 +390,14 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # make the other negative, which will make the guess discarded. # #---------------------------------------------------------------------------------# ciroot1 = - bquad / (2.0 * aquad) - ciroot2 = - discard + ciroot2 = - huge.num }else if (discr > 0.0){ ciroot1 = (- bquad + sqrt(discr)) / (2.0 * aquad) ciroot2 = (- bquad - sqrt(discr)) / (2.0 * aquad) }else{ #----- Discriminant is negative. Impossible to solve. ---------------------------# - ciroot1 = - discard - ciroot2 = - discard + ciroot1 = - huge.num + ciroot2 = - huge.num }# end if }else{ #------------------------------------------------------------------------------------# @@ -405,7 +405,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # works for this case. # #------------------------------------------------------------------------------------# ciroot1 = - cquad / bquad - ciroot2 = - discard + ciroot2 = - huge.num #----- Not used, just for the debugging process. ------------------------------------# discr = bquad * bquad }# end if @@ -414,7 +414,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # the positive discard so this will never be chosen. # #---------------------------------------------------------------------------------------# cigsw=max(ciroot1, ciroot2) - if (cigsw == -discard) cigsw = discard + if (cigsw == -huge.num) cigsw = huge.num #---------------------------------------------------------------------------------------# @@ -446,14 +446,14 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # make the other negative, which will make the guess discarded. # #---------------------------------------------------------------------------------# ciroot1 = - bquad / (2.0 * aquad) - ciroot2 = -discard + ciroot2 = -huge.num }else if (discr > 0.0){ ciroot1 = (- bquad + sqrt(discr)) / (2.0 * aquad) ciroot2 = (- bquad - sqrt(discr)) / (2.0 * aquad) }else{ #----- Discriminant is negative. Impossible to solve. ---------------------------# - ciroot1 = -discard - ciroot2 = -discard + ciroot1 = -huge.num + ciroot2 = -huge.num }#end if }else{ #------------------------------------------------------------------------------------# @@ -461,7 +461,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # that works for this case. # #------------------------------------------------------------------------------------# ciroot1 = - cquad / bquad - ciroot2 = -discard + ciroot2 = -huge.num #----- Not used, just for the debugging process. ------------------------------------# discr = bquad * bquad }# end if @@ -470,7 +470,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # the positive discard so this will never be chosen. # #---------------------------------------------------------------------------------------# ciQ=max(ciroot1, ciroot2) - if (ciQ == -discard) ciQ = discard + if (ciQ == -huge.num) ciQ = huge.num #---------------------------------------------------------------------------------------# @@ -959,7 +959,7 @@ solve.aofixed.case <<- function(met,thispft,aparms){ if (aquad == 0.0){ #----- Not really a quadratic equation. ------------------------------------------# gswroot1 = -cquad / bquad - gswroot2 = discard + gswroot2 = huge.num }else{ #----- A quadratic equation, find the discriminant. ------------------------------# discr = bquad * bquad - 4.0 * aquad * cquad @@ -967,7 +967,7 @@ solve.aofixed.case <<- function(met,thispft,aparms){ if (discr == 0.0){ #----- Double root. -----------------------------------------------------------# gswroot1 = - bquad / (2.0 * aquad) - gswroot2 = discard + gswroot2 = huge.num }else if (discr > 0.0){ #----- Two distinct roots. ----------------------------------------------------# gswroot1 = (- bquad - sqrt(discr)) / (2.0 * aquad) diff --git a/R-utils/load.everything.r b/R-utils/load.everything.r index bc900c4f0..5683a0ab8 100644 --- a/R-utils/load.everything.r +++ b/R-utils/load.everything.r @@ -222,7 +222,6 @@ discreet.require <<- function(...){ #------------------------------------------------------------------------------------------# loaded.package = list() loaded.package[["abind" ]] = discreet.require(abind ) -loaded.package[["agricolae" ]] = discreet.require(agricolae ) loaded.package[["akima" ]] = discreet.require(akima ) loaded.package[["beanplot" ]] = discreet.require(beanplot ) loaded.package[["boot" ]] = discreet.require(boot ) @@ -236,15 +235,14 @@ loaded.package[["data.table" ]] = discreet.require(data.table ) loaded.package[["devtools" ]] = discreet.require(devtools ) loaded.package[["FAdist" ]] = discreet.require(FAdist ) loaded.package[["fields" ]] = discreet.require(fields ) +loaded.package[["foto" ]] = discreet.require(foto ) loaded.package[["gbm" ]] = discreet.require(gbm ) -loaded.package[["gdalUtils" ]] = discreet.require(gdalUtils ) -loaded.package[["geoR" ]] = discreet.require(geoR ) +#loaded.package[["geoR" ]] = discreet.require(geoR ) +loaded.package[["ggplot2" ]] = discreet.require(ggplot2 ) loaded.package[["gpclib" ]] = discreet.require(gpclib ) loaded.package[["grDevices" ]] = discreet.require(grDevices ) loaded.package[["gstat" ]] = discreet.require(gstat ) -loaded.package[["hdf5" ]] = discreet.require(hdf5 ) loaded.package[["Hmisc" ]] = discreet.require(Hmisc ) -loaded.package[["klaR" ]] = discreet.require(klaR ) loaded.package[["kriging" ]] = discreet.require(kriging ) loaded.package[["leaps" ]] = discreet.require(leaps ) loaded.package[["maps" ]] = discreet.require(maps ) @@ -252,20 +250,25 @@ loaded.package[["mapdata" ]] = discreet.require(mapdata ) loaded.package[["maptools" ]] = discreet.require(maptools ) loaded.package[["MASS" ]] = discreet.require(MASS ) loaded.package[["MCMCpack" ]] = discreet.require(MCMCpack ) +loaded.package[["nat.utils" ]] = discreet.require(nat.utils ) loaded.package[["nlme" ]] = discreet.require(nlme ) loaded.package[["numDeriv" ]] = discreet.require(numDeriv ) loaded.package[["onls" ]] = discreet.require(onls ) loaded.package[["PBSmapping" ]] = discreet.require(PBSmapping ) loaded.package[["plotrix" ]] = discreet.require(plotrix ) loaded.package[["pls" ]] = discreet.require(pls ) +loaded.package[["ppcor" ]] = discreet.require(ppcor ) loaded.package[["proto" ]] = discreet.require(proto ) loaded.package[["randomForest"]] = discreet.require(randomForest) loaded.package[["raster" ]] = discreet.require(raster ) +loaded.package[["reshape2" ]] = discreet.require(reshape2 ) loaded.package[["rgdal" ]] = discreet.require(rgdal ) loaded.package[["rgeos" ]] = discreet.require(rgeos ) +loaded.package[["rhdf5" ]] = discreet.require(rhdf5 ) loaded.package[["rlas" ]] = discreet.require(rlas ) loaded.package[["robustbase" ]] = discreet.require(robustbase ) loaded.package[["rworldmap" ]] = discreet.require(rworldmap ) +loaded.package[["RColorBrewer"]] = discreet.require(RColorBrewer) loaded.package[["RSEIS" ]] = discreet.require(RSEIS ) loaded.package[["R.utils" ]] = discreet.require(R.utils ) loaded.package[["shapefiles" ]] = discreet.require(shapefiles ) @@ -275,10 +278,12 @@ loaded.package[["sn" ]] = discreet.require(sn ) loaded.package[["sp" ]] = discreet.require(sp ) loaded.package[["stats4" ]] = discreet.require(stats4 ) loaded.package[["vioplot" ]] = discreet.require(vioplot ) -loaded.package[["VoxR" ]] = discreet.require(VoxR ) +loaded.package[["viridis" ]] = discreet.require(viridis ) loaded.package[["zoo" ]] = discreet.require(zoo ) #---- Packages that must be loaded at the end. --------------------------------------------# loaded.package[["forecast" ]] = discreet.require(forecast ) +loaded.package[["klaR" ]] = discreet.require(klaR ) +loaded.package[["agricolae" ]] = discreet.require(agricolae ) #------------------------------------------------------------------------------------------# @@ -368,16 +373,6 @@ try(unlockBinding("theme",envir),silent=TRUE) -#------------------------------------------------------------------------------------------# -# SHADY BUSINESS... We must unlock %>% from package forecast and replace by our # -# function. # -#------------------------------------------------------------------------------------------# -envir = as.environment("package:forecast") -try(unlockBinding("%>%",envir),silent=TRUE) -#------------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------------# # Organise the files so we load them in the right order. # #------------------------------------------------------------------------------------------# @@ -461,7 +456,9 @@ for (if90 in sequence(nall.f90)){ dummy = if (file.exists(flib.so)){file.remove(flib.so)}else{character(0)} dummy = if (file.exists(flib.sl)){file.remove(flib.sl)}else{character(0)} dummy = if (file.exists(flib.o )){file.remove(flib.o )}else{character(0)} - dummy = rcmd(cmd="SHLIB",cmdargs=fnow,libpath=srcdir) + dummy = rcmd(cmd="SHLIB",cmdargs=fnow ) + dummy = rcmd(cmd="SHLIB",cmdargs=flib.o) + #------------------------------------------------------------------------------------# }#end if ("try-error" %in% is(dummy)) #---------------------------------------------------------------------------------------# }#end for (if90 in sequence(nall.f90)) diff --git a/R-utils/locations.r b/R-utils/locations.r index 8fdfc7cb8..1c2fe4309 100644 --- a/R-utils/locations.r +++ b/R-utils/locations.r @@ -61,6 +61,33 @@ locations <<- function(where,here=getwd(),yearbeg=1500,yearend=2008,monthbeg=1,d pathrst = file.path(here,ici,"histo",ici) pathout = file.path(pathroot,"epost") + }else if( ( substring(ici,1,2) %in% c("ta","ti","tl") ) + & ( ( substring(ici,7,7) %in% "_" ) | ( nchar(ici) == 6 ) ) + ){ + #---- Regional based name. ----------------------------------------------------------# + metflag = substring(ici,1) + if (tolower(metflag) %in% "ta"){ + thismet = "(ERA5)" + }else{ + thismet = "" + }#end if + + #----- Grab the IATA code. ----------------------------------------------------------# + iata = substring(ici,2,6) + pp = which(poilist$iata %in% iata) + + #----- Put the name of the place and the meteorological forcing. --------------------# + testpoi = paste0(poilist$longname[pp]," ",thismet) + lon = poilist$lon[pp] + lat = poilist$lat[pp] + wmo = poilist$wmo[pp] + + lieu = simul.description(ici,testpoi,iata=FALSE) + pathroot = file.path(here,ici) + pathin = file.path(pathroot,"analy",ici) + pathrst = file.path(here,ici,"histo",ici) + pathout = file.path(pathroot,"epost") + }else if( substring(ici,4,4) == "_" & substring(ici,9,9) == "_"){ #---- Convert back to upper case. ---------------------------------------------------# ici = paste0(toupper(substring(ici,1,3)),substring(ici,4)) @@ -543,8 +570,8 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ #----- ivegt.dynamics is the flag for vegetation dynamics. -----------------------------# flagvar[["ivegt.dynamics"]] = list( descr = "Vegetation dynamics" , numeric = TRUE - , values = seq(from=0,to=2,by=1) - , names = c("OFF","ON","Multi") + , values = c(0,1,2,99) + , names = c("OFF","ON","Multi","Bare") )#end list #----- iphen.scheme is the phenology scheme for tropical broadleaf trees. --------------# flagvar[["iphen.scheme"]] = list( descr = "Phenology scheme" @@ -607,13 +634,13 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- irad.drought is the rainfall response. ------------------------------------------# flagvar[["irain.drought"]] = list( descr = "Rainfall" - , numeric = TRUE + , numeric = TRUE , values = seq(from=0,to=1,by=1) , names = c("Normal","2010 drought") )#end list #----- Photosynthesis parameters. ------------------------------------------------------# flagvar[["iphysiol"]] = list( descr = "Photosynthesis" - , numeric = TRUE + , numeric = TRUE , values = seq(from=0,to=3,by=1) , names = c("Arrhenius (no Jmax/TPmax)" ,"Arrenhius (with Jmax/TPmax)" @@ -623,13 +650,13 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["igrass"]] = list( descr = "Grass scheme" - , numeric = TRUE + , numeric = TRUE , values = c(0,1) , names = c("ED-1","Swann") )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["isoilbc"]] = list( descr = "Soil Bnd. Cond." - , numeric = TRUE + , numeric = TRUE , values = c(0,1,2,3,4) , names = c( "Bedrock" , "Free drainage" @@ -640,7 +667,7 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["ipercol"]] = list( descr = "Percolation" - , numeric = TRUE + , numeric = TRUE , values = c(0,1,2) , names = c( "Walko et al. (2000)" , "Anderson (1976)" @@ -655,11 +682,12 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ #----- Fire model. ---------------------------------------------------------------------# flagvar[["include.fire"]] = list( descr = "Fire model" , numeric = TRUE - , values = c(0,1,2,3) + , values = c(0,1,2,3,4) , names = c( "Off" , "ED-1.0 type" , "Default ED-2.1" - , "Water-deficit based" + , "EMBERFIRE" + , "FIRESTARTER" )#end c )#end list #----- Energy budget type. -------------------------------------------------------------# @@ -961,14 +989,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ , values = c(0,1) , names = c("OFF","ON") )#end list - flagvar[["soil.hydro"]] = list( descr = "Soil hydraulics" - , numeric = TRUE - , values = c(0,1,2) - , names = c( "Brooks-Corey-Cosby" - , "Brooks-Cory-Tomasella" - , "van Genuchten-Hodnett" - )#end c - )#end list flagvar[["dhist" ]] = list( descr = "LCLU history" , numeric = FALSE , values = c("int","ril","cl1","cl2","lt1" @@ -1536,11 +1556,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("iphen.scheme","d0","include.fire") na = c( 10, 16, 24) nz = c( 12, 18, 25) - }else if (lenici == 26 & grep(pattern="islhydro",x=ici)){ - nparms = 2 - param = c("ivegt.dynamics","soil.hydro") - na = c( 14, 25) - nz = c( 15, 26) }else if (lenici == 26){ nparms = 3 param = c("ianth.disturb","logging.type", "bharvest") @@ -1631,11 +1646,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("yeara","iphen.scheme","isoil.text","treefall") na = c( 9, 18, 27, 35) nz = c( 11, 20, 28, 37) - }else if (lenici == 38 & grep(pattern="islhydro",x=ici)){ - nparms = 3 - param = c("ivegt.dynamics","soil.hydro","hydrodyn.set") - na = c( 14, 25, 37) - nz = c( 15, 26, 38) }else if (lenici == 39){ nparms = 3 param = c("struct","iphen.scheme","include.fire") @@ -1677,6 +1687,16 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("lon","lat") na = c( 13, 23) nz = c( 18, 28) + }else if(lenici == 34 && grepl(pattern="ifire",x=ici)){ + nparms = 3 + param = c("lon","lat","include.fire") + na = c( 11, 21, 33) + nz = c( 16, 26, 34) + }else if(lenici == 46 && grepl(pattern="ifire",x=ici)){ + nparms = 4 + param = c("lon","lat","include.fire","sm.fire") + na = c( 11, 21, 33, 42) + nz = c( 16, 26, 34, 46) }#end if }#end if #---------------------------------------------------------------------------------------# @@ -1757,6 +1777,28 @@ poilist <<- read.csv( file = file.path(srcdir,"poilist.csv") , header = TRUE , stringsAsFactors = FALSE )#end read.csv +if (file.exists(file.path(srcdir,"amzbr_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzbr_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzbr_poi.csv"))) +if (file.exists(file.path(srcdir,"amzif_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzif_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzif_poi.csv"))) +npoi <<- nrow(poilist) +if (file.exists(file.path(srcdir,"amzlu_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzlu_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzif_poi.csv"))) npoi <<- nrow(poilist) #==========================================================================================# #==========================================================================================# diff --git a/R-utils/lt.weibull.r b/R-utils/lt.weibull.r index e929cf8f9..0b9c0ded3 100644 --- a/R-utils/lt.weibull.r +++ b/R-utils/lt.weibull.r @@ -8,7 +8,7 @@ dlt.weibull <<- function(x,left=0,shape,scale=1,log=FALSE){ lnorm = left / scale #---------------------------------------------------------------------------------------# - dens = ifelse( x %<% left + dens = ifelse( x %lt% left , 0. , shape / scale * xnorm ^ (shape-1) * exp( lnorm ^ shape - xnorm ^ shape ) )#end ifelse @@ -34,7 +34,7 @@ plt.weibull <<- function(q,left=0,shape,scale=1,lower.tail=TRUE,log.p=FALSE){ #---------------------------------------------------------------------------------------# - prob = ifelse( q %<% left, 0., 1. - exp( lnorm^shape - qnorm^shape ) ) + prob = ifelse( q %lt% left, 0., 1. - exp( lnorm^shape - qnorm^shape ) ) if (lower.tail) prob = 1. - prob if (log.p ) prob = log(prob) return(prob) diff --git a/R-utils/macarthur.horn.r b/R-utils/macarthur.horn.r index da9deb26c..e83971d9d 100644 --- a/R-utils/macarthur.horn.r +++ b/R-utils/macarthur.horn.r @@ -64,15 +64,15 @@ macarthur.horn <<- function( pt.cloud # Make sure the settings make sense. # #---------------------------------------------------------------------------------------# #----- Check additional values. --------------------------------------------------------# - if (! ( zh %>% 0 && - nz %>% 0 && - zh %>% zo && - zo %>=% 0 && - ( is.na(rvorg) || rvorg %>% 0 ) && - ( out.lai %>% 0 ) && + if (! ( zh %gt% 0 && + nz %gt% 0 && + zh %gt% zo && + zo %ge% 0 && + ( is.na(rvorg) || rvorg %gt% 0 ) && + ( out.lai %gt% 0 ) && ( is.logical(tall.at.zh) ) && - ( (sigma.z %>% 0) || (! wfsim) ) && - Gmu %>%0 + ( (sigma.z %gt% 0) || (! wfsim) ) && + Gmu %gt%0 ) ){ cat0("------------------------------------------------------------------") cat0(" MacArthur and Horn won't run due to problems with your settings:" ) @@ -191,12 +191,12 @@ macarthur.horn <<- function( pt.cloud #----- Assume that everything with height zero is ground. ------------------------------# - pt.cloud$pt.class[pt.cloud$z %<=% 0] = 2 + pt.cloud$pt.class[pt.cloud$z %le% 0] = 2 #---------------------------------------------------------------------------------------# #----- Keep only the points that are within bounds. ------------------------------------# - keep = pt.cloud$z %>=% 0 & pt.cloud$z %<% zh & pt.cloud$pt.class %in% c(0,1,2,3,4,5) + keep = pt.cloud$z %ge% 0 & pt.cloud$z %lt% zh & pt.cloud$pt.class %in% c(0,1,2,3,4,5) pt.cloud = pt.cloud[keep,,drop=FALSE] #---------------------------------------------------------------------------------------# @@ -460,7 +460,7 @@ macarthur.horn <<- function( pt.cloud }else{ #----- Create a pseudo-point cloud with the MH-corrected distribution. --------------# - nzmah = ceiling(3.*Rv0/min(veg.cloud$intensity[veg.cloud$intensity %>% 0])) + nzmah = ceiling(3.*Rv0/min(veg.cloud$intensity[veg.cloud$intensity %gt% 0])) zmah = jitter(x= sample(x=zmid,size=nzmah,replace=TRUE,prob=lad),amount=0.5*deltaz) #------------------------------------------------------------------------------------# diff --git a/R-utils/monthly.template.r b/R-utils/monthly.template.r index 614067f6e..776adb2d4 100644 --- a/R-utils/monthly.template.r +++ b/R-utils/monthly.template.r @@ -46,37 +46,60 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ed$nzs = mymont$NZS ed$ndcycle = mymont$NDCYCLE ed$ntimes = ntimes + ed$nsites = mymont$PYSI.N #---------------------------------------------------------------------------------------# #----- Find which soil are we solving, and save properties into soil.prop. -------------# - ed$isoilflg = mymont$ISOILFLG ed$slz = mymont$SLZ - ed$slxsand = mymont$SLXSAND - ed$slxclay = mymont$SLXCLAY - ed$ntext = mymont$NTEXT.SOIL[ed$nzg] + ed$slhydro = mymont$SLHYDRO.REF + ed$slxsand = mymont$SLXSAND.REF + ed$slxclay = mymont$SLXCLAY.REF + ed$slxsilt = mymont$SLXSILT.REF + ed$slsoc = mymont$SLSOC.REF + ed$slph = mymont$SLPH.REF + ed$slcec = mymont$SLCEC.REF + ed$sldbd = mymont$SLDBD.REF + ed$ntext = mymont$NTEXT.SOIL[,ed$nzg] + ed$lsl = mymont$LSL #---------------------------------------------------------------------------------------# #----- Derive the soil properties. -----------------------------------------------------# - ed$soil.prop = soil.params(ed$ntext,ed$isoilflg,ed$slxsand,ed$slxclay) + ed$soil.prop = soil.params( isoilflg = 2 + , slxsand = ed$slxsand + , slxclay = ed$slxclay + , slsoc = ed$slsoc + , slph = ed$slph + , slcec = ed$slcec + , sldbd = ed$sldbd + , slhydro = ed$slhydro + , out.dfr = TRUE + )#end soil.params ed$dslz = diff(c(ed$slz,0)) ed$soil.depth = rev(cumsum(rev(ed$dslz))) - ed$soil.dry = rev(cumsum(rev(ed$soil.prop$soilcp * wdns * ed$dslz))) - ed$soil.poro = rev(cumsum(rev(ed$soil.prop$slmsts * wdns * ed$dslz))) + ed$soil.dry = apply( X = outer(wdns * ed$dslz,ed$soil.prop$soilcp) + , MARGIN = 2 + , FUN = function(x) rev(cumsum(rev(x))) + )#end apply + ed$soil.poro = apply( X = outer(wdns * ed$dslz,ed$soil.prop$soilpo) + , MARGIN = 2 + , FUN = function(x) rev(cumsum(rev(x))) + )#end apply #---------------------------------------------------------------------------------------# #----- Find the layers we care about. --------------------------------------------------# sel = ed$slz < slz.min if (any(sel)){ - ed$ka = which.max(ed$slz[sel]) + ka.min = which.max(ed$slz[sel]) + ed$ka = pmax(ka.min,ed$lsl) }else{ - ed$ka = 1 + ed$ka = ed$lsl }#end if - ed$kz = ed$nzg + ed$kz = rep(x=ed$nzg,times=length(ed$lsl)) #---------------------------------------------------------------------------------------# @@ -118,6 +141,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ndcycle = ed$ndcycle nzg = ed$nzg nzs = ed$nzs + nsites = ed$nsites #---------------------------------------------------------------------------------------# @@ -155,6 +179,17 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$crop.harvest = rep(NA_real_,times=ntimes) emean$logging.harvest = rep(NA_real_,times=ntimes) emean$combusted.fuel = rep(NA_real_,times=ntimes) + emean$fire.density = rep(NA_real_,times=ntimes) + emean$fire.intensity = rep(NA_real_,times=ntimes) + emean$fire.ignition = rep(NA_real_,times=ntimes) + emean$fire.extinction = rep(NA_real_,times=ntimes) + emean$fire.spread = rep(NA_real_,times=ntimes) + emean$fire.tlethal = rep(NA_real_,times=ntimes) + emean$fire.f.bherb = rep(NA_real_,times=ntimes) + emean$fire.f.bwoody = rep(NA_real_,times=ntimes) + emean$fire.f.fgc = rep(NA_real_,times=ntimes) + emean$fire.f.stgc = rep(NA_real_,times=ntimes) + emean$burnt.area = rep(NA_real_,times=ntimes) emean$het.resp = rep(NA_real_,times=ntimes) emean$fgc.resp = rep(NA_real_,times=ntimes) emean$fsc.resp = rep(NA_real_,times=ntimes) @@ -221,6 +256,11 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$can.vpd = rep(NA_real_,times=ntimes) emean$can.depth = rep(NA_real_,times=ntimes) emean$can.area = rep(NA_real_,times=ntimes) + emean$sfcw.temp = rep(NA_real_,times=ntimes) + emean$sfcw.fliq = rep(NA_real_,times=ntimes) + emean$sfcw.mass = rep(NA_real_,times=ntimes) + emean$sfcw.depth = rep(NA_real_,times=ntimes) + emean$sfcw.cover = rep(NA_real_,times=ntimes) emean$soil.temp.top = rep(NA_real_,times=ntimes) emean$soil.water.top = rep(NA_real_,times=ntimes) emean$soil.water.bot = rep(NA_real_,times=ntimes) @@ -243,6 +283,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$last.2yr.lvpd = rep(NA_real_,times=ntimes) emean$last.3yr.lvpd = rep(NA_real_,times=ntimes) emean$leaf.water = rep(NA_real_,times=ntimes) + emean$leaf.water.im2 = rep(NA_real_,times=ntimes) emean$phap.lwater = rep(NA_real_,times=ntimes) emean$last.1yr.lwater = rep(NA_real_,times=ntimes) emean$last.2yr.lwater = rep(NA_real_,times=ntimes) @@ -390,6 +431,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$leaf.par.beam = rep(NA_real_,times=ntimes) emean$leaf.par.diff = rep(NA_real_,times=ntimes) emean$leaf.gpp = rep(NA_real_,times=ntimes) + emean$dmin.leaf.psi = rep(NA_real_,times=ntimes) + emean$dmax.leaf.psi = rep(NA_real_,times=ntimes) emean$phap.lpar = rep(NA_real_,times=ntimes) emean$last.1yr.lpar = rep(NA_real_,times=ntimes) emean$last.2yr.lpar = rep(NA_real_,times=ntimes) @@ -422,6 +465,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$acc.hydmort = rep(NA_real_,times=ntimes) emean$acc.dimort = rep(NA_real_,times=ntimes) emean$acc.recr = rep(NA_real_,times=ntimes) + emean$fire.lethal = rep(NA_real_,times=ntimes) emean$last.1yr.change = rep(NA_real_,times=ntimes) emean$last.2yr.change = rep(NA_real_,times=ntimes) emean$last.3yr.change = rep(NA_real_,times=ntimes) @@ -558,6 +602,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$leaf.temp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.ltemp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.water = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$leaf.water.im2 = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.lwater = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$wood.temp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.vpd = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -568,6 +613,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$dimort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$ncbmort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$hydmort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$fire.lethal = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$growth = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$recr = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$change = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -621,6 +667,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$leaf.par.beam = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.par.diff = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.gpp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$dmin.leaf.psi = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$dmax.leaf.psi = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.lpar = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.rshort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.rlong = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -724,6 +772,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ qmean$can.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$leaf.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$leaf.water = matrix(data=NA,nrow=ntimes,ncol=ndcycle) + qmean$leaf.water.im2 = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$wood.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$gnd.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$atm.shv = matrix(data=NA,nrow=ntimes,ncol=ndcycle) @@ -827,10 +876,104 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ + #---------------------------------------------------------------------------------------# + # SITE -- site level variables, we save as arrays because the number of sites is # + # constant throughout the simulations. # + #---------------------------------------------------------------------------------------# + site = list() + site$isi = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$lsl = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$ntext = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.density = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.extinction = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.intensity = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.tlethal = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.spread = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$burnt.area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ignition.rate = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.bherb = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.bwoody = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.fgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.stgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$lai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$tai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$agb = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ba = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nplant = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fast.grnd.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fast.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$struct.grnd.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$struct.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$microbe.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$slow.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$passive.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nep = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$het.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cflxst = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nee = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$qwflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ustar = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rshortup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rlongup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$parup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rshort.gnd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$par.gnd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rnet = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wood.dens = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$vm0 = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$llspan = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$sla = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$can.depth = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$can.area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$veg.height = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$sm.stress = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.temp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.water = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.water.im2 = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.vpd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.gpp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$dmin.leaf.psi = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$dmax.leaf.psi = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.gsw = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par.beam = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par.diff = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gpp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$npp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$plant.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cba = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$reco = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxlc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxwc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxlc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxwc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$transp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gnd.temp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gnd.shv = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.temp.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.water.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.water.bot = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.wetness.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.wetness.bot = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # PATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# patch = list() + patch$isi = list() + patch$lsl = list() + patch$ntext = list() patch$ipa = list() patch$age = list() patch$area = list() @@ -882,12 +1025,18 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$agb = list() patch$ba = list() patch$nplant = list() + patch$bleaf = list() patch$wood.dens = list() patch$vm0 = list() patch$llspan = list() patch$sla = list() patch$can.depth = list() patch$can.area = list() + patch$sfcw.temp = list() + patch$sfcw.fliq = list() + patch$sfcw.mass = list() + patch$sfcw.depth = list() + patch$sfcw.cover = list() patch$veg.height = list() patch$veg.displace = list() patch$veg.rough = list() @@ -902,8 +1051,11 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$sm.stress = list() patch$leaf.temp = list() patch$leaf.water = list() + patch$leaf.water.im2 = list() patch$leaf.vpd = list() patch$leaf.gpp = list() + patch$dmin.leaf.psi = list() + patch$dmax.leaf.psi = list() patch$leaf.gsw = list() patch$leaf.par = list() patch$leaf.par.beam = list() @@ -937,6 +1089,31 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$soil.water = list() patch$soil.mstpot = list() patch$rk4step = list() + patch$growth = list() + patch$agb.growth = list() + patch$acc.growth = list() + patch$bsa.growth = list() + patch$mort = list() + patch$ncbmort = list() + patch$hydmort = list() + patch$dimort = list() + patch$fire.lethal = list() + patch$agb.mort = list() + patch$agb.ncbmort = list() + patch$agb.hydmort = list() + patch$agb.dimort = list() + patch$acc.mort = list() + patch$acc.ncbmort = list() + patch$acc.hydmort = list() + patch$acc.dimort = list() + patch$bsa.mort = list() + patch$bsa.ncbmort = list() + patch$bsa.hydmort = list() + patch$bsa.dimort = list() + patch$recr = list() + patch$agb.recr = list() + patch$acc.recr = list() + patch$bsa.recr = list() #---------------------------------------------------------------------------------------# @@ -945,66 +1122,67 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ #---------------------------------------------------------------------------------------# # QPATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# - qpatch = list() - qpatch$nep = list() - qpatch$het.resp = list() - qpatch$fgc.resp = list() - qpatch$fsc.resp = list() - qpatch$stgc.resp = list() - qpatch$stsc.resp = list() - qpatch$msc.resp = list() - qpatch$ssc.resp = list() - qpatch$psc.resp = list() - qpatch$can.temp = list() - qpatch$gnd.temp = list() - qpatch$can.shv = list() - qpatch$gnd.shv = list() - qpatch$can.vpd = list() - qpatch$can.co2 = list() - qpatch$can.prss = list() - qpatch$cflxca = list() - qpatch$cflxst = list() - qpatch$nee = list() - qpatch$hflxca = list() - qpatch$hflxgc = list() - qpatch$qwflxca = list() - qpatch$wflxca = list() - qpatch$wflxgc = list() - qpatch$ustar = list() - qpatch$albedo = list() - qpatch$rshortup = list() - qpatch$rlongup = list() - qpatch$parup = list() - qpatch$rshort.gnd = list() - qpatch$par.gnd = list() - qpatch$rnet = list() - qpatch$sm.stress = list() - qpatch$leaf.temp = list() - qpatch$leaf.water = list() - qpatch$leaf.vpd = list() - qpatch$wood.temp = list() - qpatch$par.leaf = list() - qpatch$par.leaf.beam = list() - qpatch$par.leaf.diff = list() - qpatch$leaf.gpp = list() - qpatch$leaf.gsw = list() - qpatch$leaf.par = list() - qpatch$leaf.par.beam = list() - qpatch$leaf.par.diff = list() - qpatch$assim.light = list() - qpatch$assim.rubp = list() - qpatch$assim.co2 = list() - qpatch$gpp = list() - qpatch$npp = list() - qpatch$plant.resp = list() - qpatch$reco = list() - qpatch$hflxlc = list() - qpatch$hflxwc = list() - qpatch$wflxlc = list() - qpatch$wflxwc = list() - qpatch$transp = list() - qpatch$soil.resp = list() - qpatch$rk4step = list() + qpatch = list() + qpatch$nep = list() + qpatch$het.resp = list() + qpatch$fgc.resp = list() + qpatch$fsc.resp = list() + qpatch$stgc.resp = list() + qpatch$stsc.resp = list() + qpatch$msc.resp = list() + qpatch$ssc.resp = list() + qpatch$psc.resp = list() + qpatch$can.temp = list() + qpatch$gnd.temp = list() + qpatch$can.shv = list() + qpatch$gnd.shv = list() + qpatch$can.vpd = list() + qpatch$can.co2 = list() + qpatch$can.prss = list() + qpatch$cflxca = list() + qpatch$cflxst = list() + qpatch$nee = list() + qpatch$hflxca = list() + qpatch$hflxgc = list() + qpatch$qwflxca = list() + qpatch$wflxca = list() + qpatch$wflxgc = list() + qpatch$ustar = list() + qpatch$albedo = list() + qpatch$rshortup = list() + qpatch$rlongup = list() + qpatch$parup = list() + qpatch$rshort.gnd = list() + qpatch$par.gnd = list() + qpatch$rnet = list() + qpatch$sm.stress = list() + qpatch$leaf.temp = list() + qpatch$leaf.water = list() + qpatch$leaf.water.im2 = list() + qpatch$leaf.vpd = list() + qpatch$wood.temp = list() + qpatch$par.leaf = list() + qpatch$par.leaf.beam = list() + qpatch$par.leaf.diff = list() + qpatch$leaf.gpp = list() + qpatch$leaf.gsw = list() + qpatch$leaf.par = list() + qpatch$leaf.par.beam = list() + qpatch$leaf.par.diff = list() + qpatch$assim.light = list() + qpatch$assim.rubp = list() + qpatch$assim.co2 = list() + qpatch$gpp = list() + qpatch$npp = list() + qpatch$plant.resp = list() + qpatch$reco = list() + qpatch$hflxlc = list() + qpatch$hflxwc = list() + qpatch$wflxlc = list() + qpatch$wflxwc = list() + qpatch$transp = list() + qpatch$soil.resp = list() + qpatch$rk4step = list() #---------------------------------------------------------------------------------------# @@ -1012,6 +1190,9 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ #----- Cohort level, we save as lists because the dimensions vary. ---------------------# cohort = list() + cohort$isi = list() + cohort$lsl = list() + cohort$ntext = list() cohort$ipa = list() cohort$ico = list() cohort$area = list() @@ -1086,6 +1267,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ cohort$dimort = list() cohort$ncbmort = list() cohort$hydmort = list() + cohort$fire.lethal = list() cohort$recruit = list() cohort$growth = list() cohort$agb.growth = list() @@ -1106,6 +1288,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ cohort$leaf.par.beam = list() cohort$leaf.par.diff = list() cohort$leaf.gpp = list() + cohort$dmin.leaf.psi = list() + cohort$dmax.leaf.psi = list() cohort$phap.lpar = list() cohort$leaf.rshort = list() cohort$leaf.rlong = list() @@ -1126,6 +1310,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ed$qmsqu = qmsqu ed$lu = lu ed$szpft = szpft + ed$site = site ed$patch = patch ed$cohort = cohort #---------------------------------------------------------------------------------------# @@ -1187,6 +1372,17 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$crop.harvest [idx ] = old.datum$emean$crop.harvest [sel ] new.datum$emean$logging.harvest [idx ] = old.datum$emean$logging.harvest [sel ] new.datum$emean$combusted.fuel [idx ] = old.datum$emean$combusted.fuel [sel ] + new.datum$emean$fire.density [idx ] = old.datum$emean$fire.density [sel ] + new.datum$emean$fire.intensity [idx ] = old.datum$emean$fire.intensity [sel ] + new.datum$emean$fire.ignition [idx ] = old.datum$emean$fire.ignition [sel ] + new.datum$emean$fire.extinction [idx ] = old.datum$emean$fire.extinction [sel ] + new.datum$emean$fire.spread [idx ] = old.datum$emean$fire.spread [sel ] + new.datum$emean$fire.tlethal [idx ] = old.datum$emean$fire.tlethal [sel ] + new.datum$emean$fire.f.bherb [idx ] = old.datum$emean$fire.f.bherb [sel ] + new.datum$emean$fire.f.bwoody [idx ] = old.datum$emean$fire.f.bwoody [sel ] + new.datum$emean$fire.f.fgc [idx ] = old.datum$emean$fire.f.fgc [sel ] + new.datum$emean$fire.f.stgc [idx ] = old.datum$emean$fire.f.stgc [sel ] + new.datum$emean$burnt.area [idx ] = old.datum$emean$burnt.area [sel ] new.datum$emean$het.resp [idx ] = old.datum$emean$het.resp [sel ] new.datum$emean$fgc.resp [idx ] = old.datum$emean$fgc.resp [sel ] new.datum$emean$fsc.resp [idx ] = old.datum$emean$fsc.resp [sel ] @@ -1264,6 +1460,11 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$can.co2 [idx ] = old.datum$emean$can.co2 [sel ] new.datum$emean$can.depth [idx ] = old.datum$emean$can.depth [sel ] new.datum$emean$can.area [idx ] = old.datum$emean$can.area [sel ] + new.datum$emean$sfcw.temp [idx ] = old.datum$emean$sfcw.temp [sel ] + new.datum$emean$sfcw.fliq [idx ] = old.datum$emean$sfcw.fliq [sel ] + new.datum$emean$sfcw.mass [idx ] = old.datum$emean$sfcw.mass [sel ] + new.datum$emean$sfcw.depth [idx ] = old.datum$emean$sfcw.depth [sel ] + new.datum$emean$sfcw.cover [idx ] = old.datum$emean$sfcw.cover [sel ] new.datum$emean$soil.temp.top [idx ] = old.datum$emean$soil.temp.top [sel ] new.datum$emean$soil.water.top [idx ] = old.datum$emean$soil.water.top [sel ] new.datum$emean$soil.water.bot [idx ] = old.datum$emean$soil.water.bot [sel ] @@ -1279,6 +1480,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$last.2yr.ltemp [idx ] = old.datum$emean$last.2yr.ltemp [sel ] new.datum$emean$last.3yr.ltemp [idx ] = old.datum$emean$last.3yr.ltemp [sel ] new.datum$emean$leaf.water [idx ] = old.datum$emean$leaf.water [sel ] + new.datum$emean$leaf.water.im2 [idx ] = old.datum$emean$leaf.water.im2 [sel ] new.datum$emean$phap.lwater [idx ] = old.datum$emean$phap.lwater [sel ] new.datum$emean$last.1yr.lwater [idx ] = old.datum$emean$last.1yr.lwater [sel ] new.datum$emean$last.2yr.lwater [idx ] = old.datum$emean$last.2yr.lwater [sel ] @@ -1423,6 +1625,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$leaf.par.beam [idx ] = old.datum$emean$leaf.par.beam [sel ] new.datum$emean$leaf.par.diff [idx ] = old.datum$emean$leaf.par.diff [sel ] new.datum$emean$leaf.gpp [idx ] = old.datum$emean$leaf.gpp [sel ] + new.datum$emean$dmin.leaf.psi [idx ] = old.datum$emean$dmin.leaf.psi [sel ] + new.datum$emean$dmax.leaf.psi [idx ] = old.datum$emean$dmax.leaf.psi [sel ] new.datum$emean$phap.lpar [idx ] = old.datum$emean$phap.lpar [sel ] new.datum$emean$last.1yr.lpar [idx ] = old.datum$emean$last.1yr.lpar [sel ] new.datum$emean$last.2yr.lpar [idx ] = old.datum$emean$last.2yr.lpar [sel ] @@ -1448,6 +1652,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$last.1yr.hydmort [idx ] = old.datum$emean$last.1yr.hydmort [sel ] new.datum$emean$last.2yr.hydmort [idx ] = old.datum$emean$last.2yr.hydmort [sel ] new.datum$emean$last.3yr.hydmort [idx ] = old.datum$emean$last.3yr.hydmort [sel ] + new.datum$emean$fire.lethal [idx ] = old.datum$emean$fire.lethal [sel ] new.datum$emean$agb.change [idx ] = old.datum$emean$agb.change [sel ] new.datum$emean$acc.change [idx ] = old.datum$emean$acc.change [sel ] new.datum$emean$acc.growth [idx ] = old.datum$emean$acc.growth [sel ] @@ -1547,6 +1752,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$leaf.temp [idx,,] = old.datum$szpft$leaf.temp [sel,,] new.datum$szpft$phap.ltemp [idx,,] = old.datum$szpft$phap.ltemp [sel,,] new.datum$szpft$leaf.water [idx,,] = old.datum$szpft$leaf.water [sel,,] + new.datum$szpft$leaf.water.im2 [idx,,] = old.datum$szpft$leaf.water.im2 [sel,,] new.datum$szpft$phap.lwater [idx,,] = old.datum$szpft$phap.lwater [sel,,] new.datum$szpft$wood.temp [idx,,] = old.datum$szpft$wood.temp [sel,,] new.datum$szpft$leaf.vpd [idx,,] = old.datum$szpft$leaf.vpd [sel,,] @@ -1558,6 +1764,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$dimort [idx,,] = old.datum$szpft$dimort [sel,,] new.datum$szpft$ncbmort [idx,,] = old.datum$szpft$ncbmort [sel,,] new.datum$szpft$hydmort [idx,,] = old.datum$szpft$hydmort [sel,,] + new.datum$szpft$fire.lethal [idx,,] = old.datum$szpft$fire.lethal [sel,,] new.datum$szpft$growth [idx,,] = old.datum$szpft$growth [sel,,] new.datum$szpft$recr [idx,,] = old.datum$szpft$recr [sel,,] new.datum$szpft$change [idx,,] = old.datum$szpft$change [sel,,] @@ -1634,6 +1841,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$leaf.par.beam [idx,,] = old.datum$szpft$leaf.par.beam [sel,,] new.datum$szpft$leaf.par.diff [idx,,] = old.datum$szpft$leaf.par.diff [sel,,] new.datum$szpft$leaf.gpp [idx,,] = old.datum$szpft$leaf.gpp [sel,,] + new.datum$szpft$dmin.leaf.psi [idx,,] = old.datum$szpft$dmin.leaf.psi [sel,,] + new.datum$szpft$dmax.leaf.psi [idx,,] = old.datum$szpft$dmax.leaf.psi [sel,,] new.datum$szpft$phap.lpar [idx,,] = old.datum$szpft$phap.lpar [sel,,] new.datum$szpft$leaf.rshort [idx,,] = old.datum$szpft$leaf.rshort [sel,,] new.datum$szpft$leaf.rlong [idx,,] = old.datum$szpft$leaf.rlong [sel,,] @@ -1725,6 +1934,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$qmean$can.temp [idx,] = old.datum$qmean$can.temp [sel,] new.datum$qmean$leaf.temp [idx,] = old.datum$qmean$leaf.temp [sel,] new.datum$qmean$leaf.water [idx,] = old.datum$qmean$leaf.water [sel,] + new.datum$qmean$leaf.water.im2 [idx,] = old.datum$qmean$leaf.water.im2 [sel,] new.datum$qmean$wood.temp [idx,] = old.datum$qmean$wood.temp [sel,] new.datum$qmean$gnd.temp [idx,] = old.datum$qmean$gnd.temp [sel,] new.datum$qmean$atm.shv [idx,] = old.datum$qmean$atm.shv [sel,] @@ -1826,10 +2036,103 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ + #---------------------------------------------------------------------------------------# + # SITE -- Site-level variables. # + #---------------------------------------------------------------------------------------# + new.datum$site$isi [idx,] = old.datum$site$isi [sel,] + new.datum$site$lsl [idx,] = old.datum$site$lsl [sel,] + new.datum$site$ntext [idx,] = old.datum$site$ntext [sel,] + new.datum$site$area [idx,] = old.datum$site$area [sel,] + new.datum$site$fire.wmass.threshold[idx,] = old.datum$site$fire.wmass.threshold[sel,] + new.datum$site$fire.density [idx,] = old.datum$site$fire.density [sel,] + new.datum$site$fire.extinction [idx,] = old.datum$site$fire.extinction [sel,] + new.datum$site$fire.intensity [idx,] = old.datum$site$fire.intensity [sel,] + new.datum$site$fire.tlethal [idx,] = old.datum$site$fire.tlethal [sel,] + new.datum$site$fire.spread [idx,] = old.datum$site$fire.spread [sel,] + new.datum$site$burnt.area [idx,] = old.datum$site$burnt.area [sel,] + new.datum$site$ignition.rate [idx,] = old.datum$site$ignition.rate [sel,] + new.datum$site$fire.f.bherb [idx,] = old.datum$site$fire.f.bherb [sel,] + new.datum$site$fire.f.bwoody [idx,] = old.datum$site$fire.f.bwoody [sel,] + new.datum$site$fire.f.fgc [idx,] = old.datum$site$fire.f.fgc [sel,] + new.datum$site$fire.f.stgc [idx,] = old.datum$site$fire.f.stgc [sel,] + new.datum$site$lai [idx,] = old.datum$site$lai [sel,] + new.datum$site$wai [idx,] = old.datum$site$wai [sel,] + new.datum$site$tai [idx,] = old.datum$site$tai [sel,] + new.datum$site$agb [idx,] = old.datum$site$agb [sel,] + new.datum$site$ba [idx,] = old.datum$site$ba [sel,] + new.datum$site$nplant [idx,] = old.datum$site$nplant [sel,] + new.datum$site$fast.grnd.c [idx,] = old.datum$site$fast.grnd.c [sel,] + new.datum$site$fast.soil.c [idx,] = old.datum$site$fast.soil.c [sel,] + new.datum$site$struct.grnd.c [idx,] = old.datum$site$struct.grnd.c [sel,] + new.datum$site$struct.soil.c [idx,] = old.datum$site$struct.soil.c [sel,] + new.datum$site$microbe.soil.c [idx,] = old.datum$site$microbe.soil.c [sel,] + new.datum$site$slow.soil.c [idx,] = old.datum$site$slow.soil.c [sel,] + new.datum$site$passive.soil.c [idx,] = old.datum$site$passive.soil.c [sel,] + new.datum$site$nep [idx,] = old.datum$site$nep [sel,] + new.datum$site$het.resp [idx,] = old.datum$site$het.resp [sel,] + new.datum$site$soil.resp [idx,] = old.datum$site$soil.resp [sel,] + new.datum$site$cflxca [idx,] = old.datum$site$cflxca [sel,] + new.datum$site$cflxst [idx,] = old.datum$site$cflxst [sel,] + new.datum$site$nee [idx,] = old.datum$site$nee [sel,] + new.datum$site$hflxca [idx,] = old.datum$site$hflxca [sel,] + new.datum$site$hflxgc [idx,] = old.datum$site$hflxgc [sel,] + new.datum$site$qwflxca [idx,] = old.datum$site$qwflxca [sel,] + new.datum$site$wflxca [idx,] = old.datum$site$wflxca [sel,] + new.datum$site$wflxgc [idx,] = old.datum$site$wflxgc [sel,] + new.datum$site$ustar [idx,] = old.datum$site$ustar [sel,] + new.datum$site$rshortup [idx,] = old.datum$site$rshortup [sel,] + new.datum$site$rlongup [idx,] = old.datum$site$rlongup [sel,] + new.datum$site$parup [idx,] = old.datum$site$parup [sel,] + new.datum$site$rshort.gnd [idx,] = old.datum$site$rshort.gnd [sel,] + new.datum$site$par.gnd [idx,] = old.datum$site$par.gnd [sel,] + new.datum$site$rnet [idx,] = old.datum$site$rnet [sel,] + new.datum$site$wood.dens [idx,] = old.datum$site$wood.dens [sel,] + new.datum$site$vm0 [idx,] = old.datum$site$vm0 [sel,] + new.datum$site$llspan [idx,] = old.datum$site$llspan [sel,] + new.datum$site$sla [idx,] = old.datum$site$sla [sel,] + new.datum$site$can.depth [idx,] = old.datum$site$can.depth [sel,] + new.datum$site$can.area [idx,] = old.datum$site$can.area [sel,] + new.datum$site$veg.height [idx,] = old.datum$site$veg.height [sel,] + new.datum$site$sm.stress [idx,] = old.datum$site$sm.stress [sel,] + new.datum$site$leaf.temp [idx,] = old.datum$site$leaf.temp [sel,] + new.datum$site$leaf.water [idx,] = old.datum$site$leaf.water [sel,] + new.datum$site$leaf.water.im2 [idx,] = old.datum$site$leaf.water.im2 [sel,] + new.datum$site$leaf.vpd [idx,] = old.datum$site$leaf.vpd [sel,] + new.datum$site$leaf.gpp [idx,] = old.datum$site$leaf.gpp [sel,] + new.datum$site$dmin.leaf.psi [idx,] = old.datum$site$dmin.leaf.psi [sel,] + new.datum$site$dmax.leaf.psi [idx,] = old.datum$site$dmax.leaf.psi [sel,] + new.datum$site$leaf.gsw [idx,] = old.datum$site$leaf.gsw [sel,] + new.datum$site$leaf.par [idx,] = old.datum$site$leaf.par [sel,] + new.datum$site$leaf.par.beam [idx,] = old.datum$site$leaf.par.beam [sel,] + new.datum$site$leaf.par.diff [idx,] = old.datum$site$leaf.par.diff [sel,] + new.datum$site$gpp [idx,] = old.datum$site$gpp [sel,] + new.datum$site$npp [idx,] = old.datum$site$npp [sel,] + new.datum$site$plant.resp [idx,] = old.datum$site$plant.resp [sel,] + new.datum$site$cba [idx,] = old.datum$site$cba [sel,] + new.datum$site$reco [idx,] = old.datum$site$reco [sel,] + new.datum$site$hflxlc [idx,] = old.datum$site$hflxlc [sel,] + new.datum$site$hflxwc [idx,] = old.datum$site$hflxwc [sel,] + new.datum$site$wflxlc [idx,] = old.datum$site$wflxlc [sel,] + new.datum$site$wflxwc [idx,] = old.datum$site$wflxwc [sel,] + new.datum$site$transp [idx,] = old.datum$site$transp [sel,] + new.datum$site$gnd.temp [idx,] = old.datum$site$gnd.temp [sel,] + new.datum$site$gnd.shv [idx,] = old.datum$site$gnd.shv [sel,] + new.datum$site$soil.temp.top [idx,] = old.datum$site$soil.temp.top [sel,] + new.datum$site$soil.water.top [idx,] = old.datum$site$soil.water.top [sel,] + new.datum$site$soil.water.bot [idx,] = old.datum$site$soil.water.bot [sel,] + new.datum$site$soil.wetness.top [idx,] = old.datum$site$soil.wetness.top [sel,] + new.datum$site$soil.wetness.bot [idx,] = old.datum$site$soil.wetness.bot [sel,] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # PATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# + new.datum$patch$isi = old.datum$patch$isi + new.datum$patch$lsl = old.datum$patch$lsl + new.datum$patch$ntext = old.datum$patch$ntext new.datum$patch$ipa = old.datum$patch$ipa new.datum$patch$age = old.datum$patch$age new.datum$patch$area = old.datum$patch$area @@ -1881,12 +2184,18 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$agb = old.datum$patch$agb new.datum$patch$ba = old.datum$patch$ba new.datum$patch$nplant = old.datum$patch$nplant + new.datum$patch$bleaf = old.datum$patch$bleaf new.datum$patch$wood.dens = old.datum$patch$wood.dens new.datum$patch$vm0 = old.datum$patch$vm0 new.datum$patch$llspan = old.datum$patch$llspan new.datum$patch$sla = old.datum$patch$sla new.datum$patch$can.depth = old.datum$patch$can.depth new.datum$patch$can.area = old.datum$patch$can.area + new.datum$patch$sfcw.temp = old.datum$patch$sfcw.temp + new.datum$patch$sfcw.fliq = old.datum$patch$sfcw.fliq + new.datum$patch$sfcw.mass = old.datum$patch$sfcw.mass + new.datum$patch$sfcw.depth = old.datum$patch$sfcw.depth + new.datum$patch$sfcw.cover = old.datum$patch$sfcw.cover new.datum$patch$veg.height = old.datum$patch$veg.height new.datum$patch$veg.displace = old.datum$patch$veg.displace new.datum$patch$veg.rough = old.datum$patch$veg.rough @@ -1901,8 +2210,11 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$sm.stress = old.datum$patch$sm.stress new.datum$patch$leaf.temp = old.datum$patch$leaf.temp new.datum$patch$leaf.water = old.datum$patch$leaf.water + new.datum$patch$leaf.water.im2 = old.datum$patch$leaf.water.im2 new.datum$patch$leaf.vpd = old.datum$patch$leaf.vpd new.datum$patch$leaf.gpp = old.datum$patch$leaf.gpp + new.datum$patch$dmin.leaf.psi = old.datum$patch$dmin.leaf.psi + new.datum$patch$dmax.leaf.psi = old.datum$patch$dmax.leaf.psi new.datum$patch$leaf.gsw = old.datum$patch$leaf.gsw new.datum$patch$leaf.par = old.datum$patch$leaf.par new.datum$patch$leaf.par.beam = old.datum$patch$leaf.par.beam @@ -1936,6 +2248,31 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$soil.water = old.datum$patch$soil.water new.datum$patch$soil.mstpot = old.datum$patch$soil.mstpot new.datum$patch$rk4step = old.datum$patch$rk4step + new.datum$patch$growth = old.datum$patch$growth + new.datum$patch$agb.growth = old.datum$patch$agb.growth + new.datum$patch$acc.growth = old.datum$patch$acc.growth + new.datum$patch$bsa.growth = old.datum$patch$bsa.growth + new.datum$patch$mort = old.datum$patch$mort + new.datum$patch$ncbmort = old.datum$patch$ncbmort + new.datum$patch$hydmort = old.datum$patch$hydmort + new.datum$patch$dimort = old.datum$patch$dimort + new.datum$patch$fire.lethal = old.datum$patch$fire.lethal + new.datum$patch$agb.mort = old.datum$patch$agb.mort + new.datum$patch$agb.ncbmort = old.datum$patch$agb.ncbmort + new.datum$patch$agb.hydmort = old.datum$patch$agb.hydmort + new.datum$patch$agb.dimort = old.datum$patch$agb.dimort + new.datum$patch$acc.mort = old.datum$patch$acc.mort + new.datum$patch$acc.ncbmort = old.datum$patch$acc.ncbmort + new.datum$patch$acc.hydmort = old.datum$patch$acc.hydmort + new.datum$patch$acc.dimort = old.datum$patch$acc.dimort + new.datum$patch$bsa.mort = old.datum$patch$bsa.mort + new.datum$patch$bsa.ncbmort = old.datum$patch$bsa.ncbmort + new.datum$patch$bsa.hydmort = old.datum$patch$bsa.hydmort + new.datum$patch$bsa.dimort = old.datum$patch$bsa.dimort + new.datum$patch$recr = old.datum$patch$recr + new.datum$patch$agb.recr = old.datum$patch$agb.recr + new.datum$patch$acc.recr = old.datum$patch$acc.recr + new.datum$patch$bsa.recr = old.datum$patch$bsa.recr #---------------------------------------------------------------------------------------# @@ -1944,71 +2281,75 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ #---------------------------------------------------------------------------------------# # QPATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# - new.datum$qpatch$nep = old.datum$qpatch$nep - new.datum$qpatch$het.resp = old.datum$qpatch$het.resp - new.datum$qpatch$fgc.resp = new.datum$qpatch$fgc.resp - new.datum$qpatch$fsc.resp = new.datum$qpatch$fsc.resp - new.datum$qpatch$stgc.resp = new.datum$qpatch$stgc.resp - new.datum$qpatch$stsc.resp = new.datum$qpatch$stsc.resp - new.datum$qpatch$msc.resp = new.datum$qpatch$msc.resp - new.datum$qpatch$ssc.resp = new.datum$qpatch$ssc.resp - new.datum$qpatch$psc.resp = new.datum$qpatch$psc.resp - new.datum$qpatch$can.temp = old.datum$qpatch$can.temp - new.datum$qpatch$gnd.temp = old.datum$qpatch$gnd.temp - new.datum$qpatch$can.shv = old.datum$qpatch$can.shv - new.datum$qpatch$gnd.shv = old.datum$qpatch$gnd.shv - new.datum$qpatch$can.vpd = old.datum$qpatch$can.vpd - new.datum$qpatch$can.co2 = old.datum$qpatch$can.co2 - new.datum$qpatch$can.prss = old.datum$qpatch$can.prss - new.datum$qpatch$cflxca = old.datum$qpatch$cflxca - new.datum$qpatch$cflxst = old.datum$qpatch$cflxst - new.datum$qpatch$nee = old.datum$qpatch$nee - new.datum$qpatch$hflxca = old.datum$qpatch$hflxca - new.datum$qpatch$hflxgc = old.datum$qpatch$hflxgc - new.datum$qpatch$qwflxca = old.datum$qpatch$qwflxca - new.datum$qpatch$wflxca = old.datum$qpatch$wflxca - new.datum$qpatch$wflxgc = old.datum$qpatch$wflxgc - new.datum$qpatch$ustar = old.datum$qpatch$ustar - new.datum$qpatch$albedo = old.datum$qpatch$albedo - new.datum$qpatch$rshortup = old.datum$qpatch$rshortup - new.datum$qpatch$rlongup = old.datum$qpatch$rlongup - new.datum$qpatch$parup = old.datum$qpatch$parup - new.datum$qpatch$rshort.gnd = old.datum$qpatch$rshort.gnd - new.datum$qpatch$par.gnd = old.datum$qpatch$par.gnd - new.datum$qpatch$rnet = old.datum$qpatch$rnet - new.datum$qpatch$sm.stress = old.datum$qpatch$sm.stress - new.datum$qpatch$leaf.temp = old.datum$qpatch$leaf.temp - new.datum$qpatch$leaf.water = old.datum$qpatch$leaf.water - new.datum$qpatch$leaf.vpd = old.datum$qpatch$leaf.vpd - new.datum$qpatch$wood.temp = old.datum$qpatch$wood.temp - new.datum$qpatch$par.leaf = old.datum$qpatch$par.leaf - new.datum$qpatch$par.leaf.beam = old.datum$qpatch$par.leaf.beam - new.datum$qpatch$par.leaf.diff = old.datum$qpatch$par.leaf.diff - new.datum$qpatch$leaf.gpp = old.datum$qpatch$leaf.gpp - new.datum$qpatch$leaf.gsw = old.datum$qpatch$leaf.gsw - new.datum$qpatch$leaf.par = old.datum$qpatch$leaf.par - new.datum$qpatch$leaf.par.beam = old.datum$qpatch$leaf.par.beam - new.datum$qpatch$leaf.par.diff = old.datum$qpatch$leaf.par.diff - new.datum$qpatch$assim.light = old.datum$qpatch$assim.light - new.datum$qpatch$assim.rubp = old.datum$qpatch$assim.rubp - new.datum$qpatch$assim.co2 = old.datum$qpatch$assim.co2 - new.datum$qpatch$gpp = old.datum$qpatch$gpp - new.datum$qpatch$npp = old.datum$qpatch$npp - new.datum$qpatch$plant.resp = old.datum$qpatch$plant.resp - new.datum$qpatch$reco = old.datum$qpatch$reco - new.datum$qpatch$hflxlc = old.datum$qpatch$hflxlc - new.datum$qpatch$hflxwc = old.datum$qpatch$hflxwc - new.datum$qpatch$wflxlc = old.datum$qpatch$wflxlc - new.datum$qpatch$wflxwc = old.datum$qpatch$wflxwc - new.datum$qpatch$transp = old.datum$qpatch$transp - new.datum$qpatch$soil.resp = old.datum$qpatch$soil.resp - new.datum$qpatch$rk4step = old.datum$qpatch$rk4step + new.datum$qpatch$nep = old.datum$qpatch$nep + new.datum$qpatch$het.resp = old.datum$qpatch$het.resp + new.datum$qpatch$fgc.resp = new.datum$qpatch$fgc.resp + new.datum$qpatch$fsc.resp = new.datum$qpatch$fsc.resp + new.datum$qpatch$stgc.resp = new.datum$qpatch$stgc.resp + new.datum$qpatch$stsc.resp = new.datum$qpatch$stsc.resp + new.datum$qpatch$msc.resp = new.datum$qpatch$msc.resp + new.datum$qpatch$ssc.resp = new.datum$qpatch$ssc.resp + new.datum$qpatch$psc.resp = new.datum$qpatch$psc.resp + new.datum$qpatch$can.temp = old.datum$qpatch$can.temp + new.datum$qpatch$gnd.temp = old.datum$qpatch$gnd.temp + new.datum$qpatch$can.shv = old.datum$qpatch$can.shv + new.datum$qpatch$gnd.shv = old.datum$qpatch$gnd.shv + new.datum$qpatch$can.vpd = old.datum$qpatch$can.vpd + new.datum$qpatch$can.co2 = old.datum$qpatch$can.co2 + new.datum$qpatch$can.prss = old.datum$qpatch$can.prss + new.datum$qpatch$cflxca = old.datum$qpatch$cflxca + new.datum$qpatch$cflxst = old.datum$qpatch$cflxst + new.datum$qpatch$nee = old.datum$qpatch$nee + new.datum$qpatch$hflxca = old.datum$qpatch$hflxca + new.datum$qpatch$hflxgc = old.datum$qpatch$hflxgc + new.datum$qpatch$qwflxca = old.datum$qpatch$qwflxca + new.datum$qpatch$wflxca = old.datum$qpatch$wflxca + new.datum$qpatch$wflxgc = old.datum$qpatch$wflxgc + new.datum$qpatch$ustar = old.datum$qpatch$ustar + new.datum$qpatch$albedo = old.datum$qpatch$albedo + new.datum$qpatch$rshortup = old.datum$qpatch$rshortup + new.datum$qpatch$rlongup = old.datum$qpatch$rlongup + new.datum$qpatch$parup = old.datum$qpatch$parup + new.datum$qpatch$rshort.gnd = old.datum$qpatch$rshort.gnd + new.datum$qpatch$par.gnd = old.datum$qpatch$par.gnd + new.datum$qpatch$rnet = old.datum$qpatch$rnet + new.datum$qpatch$sm.stress = old.datum$qpatch$sm.stress + new.datum$qpatch$leaf.temp = old.datum$qpatch$leaf.temp + new.datum$qpatch$leaf.water = old.datum$qpatch$leaf.water + new.datum$qpatch$leaf.water.im2 = old.datum$qpatch$leaf.water.im2 + new.datum$qpatch$leaf.vpd = old.datum$qpatch$leaf.vpd + new.datum$qpatch$wood.temp = old.datum$qpatch$wood.temp + new.datum$qpatch$par.leaf = old.datum$qpatch$par.leaf + new.datum$qpatch$par.leaf.beam = old.datum$qpatch$par.leaf.beam + new.datum$qpatch$par.leaf.diff = old.datum$qpatch$par.leaf.diff + new.datum$qpatch$leaf.gpp = old.datum$qpatch$leaf.gpp + new.datum$qpatch$leaf.gsw = old.datum$qpatch$leaf.gsw + new.datum$qpatch$leaf.par = old.datum$qpatch$leaf.par + new.datum$qpatch$leaf.par.beam = old.datum$qpatch$leaf.par.beam + new.datum$qpatch$leaf.par.diff = old.datum$qpatch$leaf.par.diff + new.datum$qpatch$assim.light = old.datum$qpatch$assim.light + new.datum$qpatch$assim.rubp = old.datum$qpatch$assim.rubp + new.datum$qpatch$assim.co2 = old.datum$qpatch$assim.co2 + new.datum$qpatch$gpp = old.datum$qpatch$gpp + new.datum$qpatch$npp = old.datum$qpatch$npp + new.datum$qpatch$plant.resp = old.datum$qpatch$plant.resp + new.datum$qpatch$reco = old.datum$qpatch$reco + new.datum$qpatch$hflxlc = old.datum$qpatch$hflxlc + new.datum$qpatch$hflxwc = old.datum$qpatch$hflxwc + new.datum$qpatch$wflxlc = old.datum$qpatch$wflxlc + new.datum$qpatch$wflxwc = old.datum$qpatch$wflxwc + new.datum$qpatch$transp = old.datum$qpatch$transp + new.datum$qpatch$soil.resp = old.datum$qpatch$soil.resp + new.datum$qpatch$rk4step = old.datum$qpatch$rk4step #---------------------------------------------------------------------------------------# #----- Cohort level, we save as lists because the dimensions vary. ---------------------# + new.datum$cohort$isi = old.datum$cohort$isi + new.datum$cohort$lsl = old.datum$cohort$lsl + new.datum$cohort$ntext = old.datum$cohort$ntext new.datum$cohort$ipa = old.datum$cohort$ipa new.datum$cohort$ico = old.datum$cohort$ico new.datum$cohort$area = old.datum$cohort$area @@ -2081,6 +2422,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$cohort$dimort = old.datum$cohort$dimort new.datum$cohort$ncbmort = old.datum$cohort$ncbmort new.datum$cohort$hydmort = old.datum$cohort$hydmort + new.datum$cohort$fire.lethal = old.datum$cohort$fire.lethal new.datum$cohort$recruit = old.datum$cohort$recruit new.datum$cohort$growth = old.datum$cohort$growth new.datum$cohort$agb.growth = old.datum$cohort$agb.growth @@ -2101,6 +2443,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$cohort$leaf.par.beam = old.datum$cohort$leaf.par.beam new.datum$cohort$leaf.par.diff = old.datum$cohort$leaf.par.diff new.datum$cohort$leaf.gpp = old.datum$cohort$leaf.gpp + new.datum$cohort$dmin.leaf.psi = old.datum$cohort$dmin.leaf.psi + new.datum$cohort$dmax.leaf.psi = old.datum$cohort$dmax.leaf.psi new.datum$cohort$phap.lpar = old.datum$cohort$phap.lpar new.datum$cohort$leaf.rshort = old.datum$cohort$leaf.rshort new.datum$cohort$leaf.rlong = old.datum$cohort$leaf.rlong diff --git a/R-utils/neon_utils.r b/R-utils/neon_utils.r new file mode 100644 index 000000000..3a6dd1a45 --- /dev/null +++ b/R-utils/neon_utils.r @@ -0,0 +1,1630 @@ +#----- List of flags for undetermined species. --------------------------------------------# +unknown_wildcard <<- c("aff","cf","deleteme","ind","indet","na","ni","sp","spp" + ,"spnov","unknown","unidentified" + ,paste0("sp" ,sequence(99)) + ,paste0("spb" ,sequence(99)) + ,paste0("spp" ,sequence(99)) + ,paste0("sp" ,sequence(99),"cay-atdn") + ,paste0("sp" ,sequence(99),"-cay" ) + ,paste0("sp" ,sequence(99),"guyafor" ) + ,paste0("spfg",sequence(99),"-holst" ) + )#end c +unknown_common <<- "unknown" +unk_liana_common <<- "liana" +unknown_phylum <<- "Ignotophyta" +unknown_class <<- "Ignotopsida" +unknown_order <<- "Ignotales" +unknown_family <<- "Ignotaceae" +unknown_genus <<- "Ignotum" +unknown_epithet <<- "indet" +unk_liana_phylum <<- "Lianophyta" +unk_liana_class <<- "Lianopsida" +unk_liana_order <<- "Lianales" +unk_liana_family <<- "Lianaceae" +unk_liana_genus <<- "Liana" +unknown_scientific <<- paste(unknown_genus,unknown_epithet) +unk_liana_scientific <<- paste(unk_liana_genus,unknown_epithet) +#------------------------------------------------------------------------------------------# + + + +#========================================================================================== +#========================================================================================== +# This function standardises the spelling of common names of trees. +#------------------------------------------------------------------------------------------ +standard_common_name_NEON <<- function(x){ + #---~--- + # Make sure common names are lower case. + #---~--- + x = tolower(x) + #---~--- + + + #---~--- + # Remove underscore marks. + #---~--- + x = gsub(pattern="_",replacement=" ",x=x) + #---~--- + + + + #---~--- + # General substitutions. These are very aggressive, so don't use it too much. + # Good things to put here are names that are often misspelt in a way that cannot occur + # in other words. For example, abiuarana instead of abiurana is a good case; replacing + # abiu with abiurana is a bad idea because abiurana would become abiuranarana. It's + # wise to use regexpr rules such as ^ and $ to make sure gsub won't substitute more + # than it is supposed to. + #---~--- + # x = gsub(pattern="^abiuarana" ,replacement="abiurana" ,x=x) + #---~--- + + + + #---~--- + # Specific substitutions. Most cases should come here. + #---~--- + sel = (x %in% "dense sedge" ); x[sel] = NA_character_ + #---~--- + + return(x) +}#end function standard.common.name +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# This function corrects scientific names and families that are not correctly typed, +# are synonyms or have become obsolete. +#------------------------------------------------------------------------------------------# + + + + + + +#========================================================================================== +#========================================================================================== +# This attributes scientific names based on common names for NEON surveys. +# It is NOT a good idea to use this anywhere else because common names may mean completely +# diferent things... +#------------------------------------------------------------------------------------------ +scientific_lookup_NEON <<- function(datum,lookup_path,site){ + + #---~--- + # Read in the look-up table. + #---~--- + lookup_file = file.path(lookup_path,"NEON_taxon_lookup.csv") + look_up = as.data.table(read.csv(file=lookup_file,stringsAsFactors=FALSE)) + look_up$common = tolower(trim(look_up$common )) + look_up$scientific = trim(look_up$scientific) + look_up$family = trim(look_up$family ) + #---~--- + + + #---~--- + # Keep only entries for this NEON site. + #---~--- + if (site %in% names(look_up)){ + look_up = look_up[look_up[[site]],,drop=FALSE] + }else{ + cat0("-------------------------------------------------------------------") + cat0(" ERROR! Site is not available at the look-up data base." ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" Site: ",site ) + cat0(" Data base file: ",lookup_file ) + cat0(" " ) + cat0(" Edit data base file, adding all the common names occurring at" ) + cat0(" your site, and add a column named site with the entries that" ) + cat0(" should be applicable to your site. Look for existing nearby" ) + cat0(" sites, it is fine to have the same common name valid for multiple" ) + cat0(" locations. If the common name already exists in the data base" ) + cat0(" but refers to a different species in your site, duplicate the" ) + cat0(" common name, make sure to set the new entry to TRUE for the new" ) + cat0(" site, and FALSE to all the other sites. Also set the new site to" ) + cat0(" FALSE in the existing entry." ) + cat0(" " ) + cat0("-------------------------------------------------------------------") + stop("Invalid site.") + }#end if (site %in% look_up) + #---~--- + + + + #---~--- + # Break into genus and epithet. + #---~--- + ge_list = sapply(X = tolower(look_up$scientific),FUN=strsplit,split=" ") + ge_length = sapply(X = ge_list, FUN = length) + ge_mat = cbind( mapply(FUN="[",ge_list,MoreArgs=list(1)) + , mapply(FUN="[",ge_list,MoreArgs=list(2)) + )#end cbind + g = capwords(ge_mat[,1],strict=TRUE) + e = tolower(ge_mat[,2]) + g_e = paste(g,e,sep=" ") + g_e[is.na(g) & is.na(e)] = NA_character_ + look_up$scientific = g_e + look_up$genus = g + #---~--- + + + + #---~--- + # Trim the common names, and simplify/replace some names. + #---~--- + datum$common = tolower(trim(datum$common)) + datum$common[is.na(datum$common)] = unknown_common + #---~--- + + + #---~--- + # Initialise column gf.scientific in case it is not available. + #---~--- + if (! "gf.scientific" %in% names(datum)){ + datum$gf.scientific = rep(NA_integer_,times=nrow(datum)) + }#end (! "gf.scientific" %in% names(datum)) + #---~--- + + + #---~--- + # Find all unique common names. + #---~--- + unique_common = unique(datum$common) + n_common = length(unique_common) + not_found = character(0L) + for (n in sequence(n_common)){ + #---~--- + # Find the trees that have the same common name as this one. + #---~--- + cat0(" - ",n,"/",n_common," -- ",unique_common[n],".") + w_dat = which(datum$common %in% unique_common[n]) + n_dat = length(w_dat) + #---~--- + + + #---~--- + # Find the trees in the look-up table with the same common name. + #---~--- + w_look = which(look_up$common %in% unique_common[n]) + n_look = length(w_look) + #---~--- + + + + #---~--- + # Check how many trees have the same common name in the look-up table. + #---~--- + if (n_look == 1){ + #---~--- + # Only one. Use it. + #---~--- + datum$scientific [w_dat] = look_up$scientific[w_look] + datum$genus [w_dat] = look_up$genus [w_look] + datum$gf.scientific[w_dat] = 1L + }else if (n_look > 1){ + datum$scientific [w_dat] = sample( x = look_up$scientific[w_look] + , size = n_dat + , replace = TRUE + )#end sample + datum$genus [w_dat] = look_up$genus [w_look] + datum$gf.scientific[w_dat] = 1 + }else{ + not_found = c(not_found,unique_common[n]) + datum$scientific [w_dat] = unknown_scientific + datum$genus [w_dat] = unknown_genus + datum$gf.scientific[w_dat] = 0 + }#end if + #---~--- + }#end for (n in sequence(n_common)) + #---~--- + + + #---~--- + # In case species were not found, list them so the user is aware. + #---~--- + not_found = not_found[! not_found %in% unknown_common] + if (length(not_found) %gt% 0L){ + #---~--- + # Report the unmatched names. + #---~--- + cat0(" " ) + cat0(" " ) + cat0("-------------------------------------------------------------------") + cat0(" WARNING! Some names were not found in the common name data base." ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" Site: ",site ) + cat0(" Data base file: ",lookup_file ) + cat0(" " ) + cat0(" Species not found:" ) + #---~--- + + #---~--- + # Loop through unmatched names. + #---~--- + for (n in seq_along(not_found)){ + cat0(" - ",not_found[n],"." ) + }#end for (n in seq_along(not_found)) + #---~--- + + #---~--- + # End report + #---~--- + cat0(" " ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" " ) + #---~--- + }#end if (length(not_found) %gt% 0L) + #---~--- + + #---~--- + # Return standardised data. + #---~--- + return(datum) + #---~--- +}#end function scientific_lookup_NEON +#==========================================================================================# +#==========================================================================================# + + + + + + +#========================================================================================== +#========================================================================================== +# Fill in the traits for all individuals. We do this in three stages, and save how +# the trait was determined. The numbers represent the flag given for each trait. +# 0 -- Individuals have full identification and the species is listed in the +# database; we used the reported density for that species. +# 1 -- The species/genus is identified but it isn't listed in the database, we use an +# average of all other species of that genus that exist in database. +# 2 -- We could not identify the individual to the genus level, but we know the +# family. We use the average wood density of all individuals of this census that +# belong to that family. +# 3 -- No taxonomic information could be retrieved for this individual, so we filled +# with random sampling. +# +# We also add 10 when the scientific name was gap filled. +# +# INPUT variables: +# +# - datum -- data frame with data. This is going to be the output as well +# - trait -- trait to fill +# - tdb.csv -- csv file containing the trait data base +# - country -- restrict attribution to these countries (NULL uses all countries) +# - continents -- restrict attribution to these continents (NULL uses all continents) +# - fsample -- use random sampling to fill unidentified individuals, or individuals +# with genus that is not available at the trait data base? +# If FALSE then it uses averages +# - weight -- A weighting factor to give either probability or to weight +# the average. This could be a vector with weights, or a character with +# the name of the variable in datum to use as the weight, or an integer +# with the column to be used as the weighting factor +# - verbose -- Flag to control the amount of information +#------------------------------------------------------------------------------------------ +find_trait_NEON <<- function( datum + , trait = c( "wood.dens", "SLA", "leaf.phen" + , "growth.form", "woodland") + , tdb.csv = file.path(srcdir,"NEON_trait_table.csv") + , country = NULL + , continent = NULL + , fsample = TRUE + , weight = NULL + , verbose = FALSE + ){ + + #---~--- + # Check that trait is valid. + #---~--- + trait = match.arg(trait) + n.trait = paste0("n." ,trait) + gf.trait = paste0("gf.",trait) + #---~--- + + + #---~--- + # Initialise gap filling flag and region in case they are not there. + #---~--- + if (! trait %in% names(datum)){ + if ( trait %in% c("leaf.phen","growth.form") ){ + datum[[trait]] = rep(NA_character_,times=nrow(datum)) + }else if ( trait %in% "woodland" ){ + datum[[trait]] = rep(NA_logical_ ,times=nrow(datum)) + }else{ + datum[[trait]] = rep(NA_real_ ,times=nrow(datum)) + }#end if ( trait %in% c("leaf.phen","growth.form") ) + }#end (! trait %in% names(datum)) + if (! gf.trait %in% names(datum)){ + datum[[gf.trait]] = rep(NA_integer_,times=nrow(datum)) + }#end (! gf.trait %in% names(datum)) + if (! "country" %in% names(datum)){ + datum$country = rep(NA_character_,times=nrow(datum)) + }#end (! "country" %in% names(datum)) + if (! "continent" %in% names(datum)){ + datum$continent = rep(NA_character_,times=nrow(datum)) + }#end (! "continent" %in% names(datum)) + #---~--- + + + #---~--- + # Check whether weight is a vector, or a character. Make them a vector here. + #---~--- + if (is.null(weight)){ + #---~--- + # No weight provided, use equal weights. + #---~--- + wgtfac = rep(x=1/nrow(datum),times=nrow(datum)) + #---~--- + }else if (is.character(weight) && (length(weight) == 1)){ + #---~--- + # Character with column name was provided. + #---~--- + if (weight %in% names(datum)){ + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) + }else{ + stop(paste0(" Weight Variable name (",weight,") not found in datum!")) + }#end if + #---~--- + }else if (is.numeric(weight) && (length(weight) == 1)){ + #---~--- + # Column index provided. + #---~--- + if (! (weight %wr% c(1,ncol(datum)))){ + stop(paste0(" Weight column index (",weight,") doesn't make sense")) + }else if (is.numeric(datum[,weight])){ + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) + }else{ + stop(paste0(" Column ",weight," of data frame is not numeric!")) + }#end if + #---~--- + }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ + wgtfac = ifelse(weight %gt% 0, weight, 0) + }else{ + stop("Variable weight is not properly set!") + }#end if (is.null(weight)) + #---~--- + + + + #---~--- + # Check that the weighting factor makes sense. + #---~--- + if (sum(wgtfac) > 0){ + wgtfac = wgtfac / sum(wgtfac) + }else{ + stop(" Invalid weighting variable. Most numbers should be positive...") + }#end if + #---~--- + + + + #---~--- + # Read data base to fill traits. + #---~--- + tdb = read.csv(file=tdb.csv,header=TRUE,stringsAsFactors=FALSE) + keep = ! is.na(tdb[[trait]]) + tdb = tdb[keep,,drop=FALSE] + #---~--- + + + + #---~--- + # Restrict data base to valid traits in selected regions, and make sure the data base + # can be used. + #---~--- + if (! (trait %in% names(tdb))){ + stop(paste0(" Trait ",trait," is not available in trait file \"" + ,basename(tdb.csv),"\".")) + }else if (! all(c("country","continent") %in% names(tdb))){ + stop(paste0(" \"country\" and/or \"continent\" missing in trait file \"" + ,basename(tdb.csv),"\".")) + }else{ + #---~--- + # Restrict species to regions of interest. + #---~--- + if (is.null(country)){ + sel.country = rep(x=TRUE,times=nrow(tdb)) + }else{ + sel.country = tdb$country %in% country + }#end if (is.null(country)) + if (is.null(continent)){ + sel.continent = rep(x=TRUE,times=nrow(tdb)) + }else{ + sel.continent = tdb$continent %in% continent + }#end if (is.null(continent)) + keep = (! is.na(tdb[[trait]]) ) & sel.country & sel.continent + ntdb = sum(keep) + if (ntdb == 0){ + cat0(" - Selected trait: ",trait) + if (! is.null(country)){ + cat0(" - Selected countries: " ,paste(country ,collapse="; ")) + }#end if (! is.null(country)) + if (! is.null(continent)){ + cat0(" - Selected continents: ",paste(continent,collapse="; ")) + }#end if (! is.null(continent)) + stop(paste0("No data available for trait ",trait," in file \"" + ,basename(tdb.csv),"\".")) + }else{ + tdb = tdb[keep,,drop=FALSE] + }#end if (ntdb == 0) + #---~--- + }#end if (! (trait %in% names(tdb))) + #---~--- + + + #======================================================================================= + #======================================================================================= + # First loop, fill in information to all individuals for which the genus is + # known. + #--------------------------------------------------------------------------------------- + #---~--- + # Separate all species. + #---~--- + species = unique(datum$scientific) + nspecies = length(species) + sci.genus.mean = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","genus","family"))) + sci.loose.mean = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","genus","family"))) + #---~--- + + + #---~--- + # Loop through species + #---~--- + for (s in sequence(nspecies)){ + if ((! is.na(species[s])) && length(grep(unknown_genus,species[s])) == 0){ + if (verbose) cat0(" - ",s,"/",nspecies," - ",species[s],".") + + #---~--- + # Get the genus and family of this species, in case we need it. + #---~--- + igen = which (datum$scientific %in% species[s]) + this.genus = unique(datum$genus[igen]) + this.family = unique(capwords(datum$family[igen],strict=TRUE)) + if (length(this.genus) != 1 || length(this.family) != 1){ + cat0(" - Perhaps a bastard genus?") + browser() + }#end if + #---~--- + + + + #---~--- + # Check whether we have biomass for this species. + #---~--- + if (species[s] %in% tdb$scientific){ + #---~--- + # Find the index of this species in the database, and assign the trait + # from there. + #---~--- + itrait = intersect( which(tdb$scientific %in% species[s] ) + , intersect( which(tdb$genus %in% this.genus ) + , which(tdb$family %in% this.family) ) ) + + if (length(itrait) != 1){ + #---~--- + # Intersection was zero! Misidentification, maybe? + #---~--- + loose = TRUE + cat0("Weird, length(itrait)=",length(itrait),"!") + browser() + #---~--- + }else{ + if (any(c(FALSE,! is.na(tdb[[trait]][itrait])),na.rm=TRUE)){ + sel = datum$scientific %in% species[s] + datum[[trait]] [sel] = tdb[[trait]][itrait] + datum[[gf.trait]][sel] = 0L + datum$country [sel] = tdb$country [itrait] + datum$continent [sel] = tdb$continent[itrait] + fill.genus = FALSE + loose = FALSE + }else{ + loose = TRUE + fill.genus = this.genus %in% tdb$genus + }#end if + #---~--- + }#end if + #---~--- + }else{ + loose = TRUE + fill.genus = this.genus %in% tdb$genus + }#end if + #---~--- + + + + #---~--- + # If this species is to be filled with genus average. + #---~--- + if (fill.genus){ + #---~--- + # Find all the plants from this genus, take the average, and attribute + # to this species. In this case, warn the user about the species, it may + # be a typo in the scientific name that is easy to fix. + #---~--- + itrait = intersect( which( tdb$genus %in% this.genus ) + , which( tdb$family %in% this.family) + )#end intersect + + #---~--- + # Find individuals that belong to this species. + #---~--- + sel = datum$scientific %in% species[s] + nsel = sum(sel) + #---~--- + + if (length(itrait) == 0){ + #---~--- + # Intersection was zero! Misidentification, maybe? + #---~--- + loose = TRUE + #---~--- + }else if (nsel > 0){ + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = tdb[[trait ]][itrait] + t.weight = tdb[[n.trait]][itrait] / sum(tdb[[n.trait]][itrait]) + t.continent = tdb$continent [itrait] + t.country = tdb$country [itrait] + t.idx = seq_along(t.value) + if (any(is.na(t.weight))) browser() + #---~--- + + + #---~--- + # Decide whether to use sample (non-numeric) or average (numeric). + #---~--- + if (fsample || ( trait %in% c("leaf.phen","growth.form","woodland") )){ + smp.idx = lit.sample(x=t.idx,size=nsel,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + #---~--- + # Fill in missing entries. + #---~--- + datum[[trait]] [sel] = smp.trait + datum[[gf.trait]][sel] = 1L + datum$country [sel] = smp.country + datum$continent [sel] = smp.continent + sci.genus.mean = rbind(sci.genus.mean + ,c(species[s],this.genus,this.family)) + if (verbose){ + cat0(" * Species ",species[s]," not found." + ," Use genus average instead.") + }#end if + loose = FALSE + #---~--- + }#end if + #---~--- + }#end if + #---~--- + + + #---~--- + # Append plants that have no family together. + #---~--- + if (loose){ + #---~--- + # The plant probably doesn't have any family. + #---~--- + sci.loose.mean = rbind(sci.loose.mean + ,c(species[s],this.genus,this.family)) + #---~--- + }#end if + #---~--- + }#end if + #---~--- + }#end for + #---~--- + + + + #---~--- + # List all genera that were not filled with species information. + #---~--- + sci.genus.mean = sci.genus.mean[order(sci.genus.mean[,"scientific"]),,drop=FALSE] + genus.only = grepl( pattern = " NA$" + , x = sci.genus.mean[,"scientific",drop=FALSE] + , ignore.case = TRUE + )#end grepl + if (verbose && (nrow(sci.genus.mean[!genus.only,,drop=FALSE]) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0(" Found species that were not in trait data base (check for synonyms)!") + print(sci.genus.mean[! genus.only,,drop=FALSE],quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if (verbose && nrow(sci.genus.mean[!genus.only,,drop=FALSE]) > 0) + if (verbose && (nrow(sci.genus.mean[genus.only,,drop=FALSE]) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0("Only genus was provided: filled with average genus value:") + print (sci.genus.mean[genus.only,,drop=FALSE],quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if (verbose && nrow(sci.genus.mean[genus.only,,drop=FALSE]) > 0) + #---~--- + + + #---~--- + # List all genera that didn't belong to any known family. + #---~--- + if (verbose && (nrow(sci.loose.mean) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0(" Found genera from families with no valid data in the trait data base!") + print(sci.loose.mean,quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if + #---~--- + #======================================================================================= + #======================================================================================= + + + + + + #======================================================================================= + #======================================================================================= + # Second loop: we list all families, and look for individuals that have no genus + # associated. We compute the mean trait of the known individuals for that family and + # use that as an estimate of the trait. + #--------------------------------------------------------------------------------------- + #---~--- + families = unique(datum$family) + nfamilies = length(families) + sci.family.sample = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","family",trait))) + #---~--- + + + #---~--- + # Loop over all families + #---~--- + for (f in sequence(nfamilies)){ + if (! (families[f] %in% unknown_family)){ + if (verbose) cat0(" - ",f,"/",nfamilies," - ",families[f],".") + + #---~--- + # Get the individuals that belong to this family. + #---~--- + ifam = which (datum$family %in% families[f] & (! is.na(datum[[trait]])) ) + imiss = which (datum$family %in% families[f] & is.na(datum[[trait]]) ) + nmiss = length(imiss) + #---~--- + + if (length(imiss) > 0 && length(ifam) > 0){ + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = datum[[trait]] [ifam] + t.weight = wgtfac [ifam] + t.continent = datum$continent[ifam] + t.country = datum$country [ifam] + t.idx = seq_along(t.value) + #---~--- + + + + #---~--- + # Decide whether to use sample or average. + #---~--- + if (fsample || ( trait %in% c("leaf.phen","growth.form","woodland") )){ + smp.idx = lit.sample(x=t.idx,size=nmiss,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + + #---~--- + # Fill in with the sample/mean. + #---~--- + datum[[trait]] [imiss] = smp.trait + datum[[gf.trait]][imiss] = 2L + datum$country [imiss] = smp.country + datum$continent [imiss] = smp.continent + gf2 = cbind(datum$scientific[imiss] + ,datum$family [imiss] + ,sprintf("%6.3f",smp.trait) + )#end cbind + sci.family.sample = rbind(sci.family.sample,gf2) + #---~--- + }#end if + #---~--- + }#end if + #---~--- + }#end for + #---~--- + + + #---~--- + # Stop if there was any genus that didn't belong to any known family. + #---~--- + if (nrow(sci.family.sample) > 0){ + if (verbose){ + cat0(" Found families with unidentified genera!") + print(sci.family.sample,quote=FALSE) + }#end if + }#end if + #---~--- + + + #---~--- + # Final block. We fill in the trait for unknown individuals, by randomly sampling + # from the individuals we know the density. + #---~--- + imiss = which(is.na(datum[[trait]])) + nmiss = length(imiss) + nvalid = nrow(datum) - nmiss + + if (nmiss > 0){ + if (verbose){ + cat0(" The following families are filled with global sampling: ") + fam.global.sampling = t(t(sort(unique(datum$family[imiss])))) + print(fam.global.sampling,quote=FALSE) + }#end if + #---~--- + + + #---~--- + # Check whether this is going to be a complete guess or something slightly more + # elegant. + #---~--- + if (nvalid == 0){ + #---~--- + # Use any data from the trait data base. + #---~--- + warning(" None of the trees are known! Trait-filling is going to be very crude!") + itrait = which(tdb$life.type %in% "T") + t.value = tdb[[trait ]][itrait] + t.weight = tdb[[n.trait]][itrait] / sum(tdb[[n.trait]][itrait]) + t.continent = tdb$continent [itrait] + t.country = tdb$country [itrait] + t.idx = seq_along(t.value) + #---~--- + }else{ + + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = datum[[trait]] [-imiss] + t.weight = wgtfac [-imiss] + t.continent = datum$continent[-imiss] + t.country = datum$country [-imiss] + t.idx = seq_along(t.value) + #---~--- + }#end if (nvalid == 0) + #---~--- + + + #---~--- + # Decide whether to use sample or averaged values. + #---~--- + if (fsample || ( trait %in% c("leaf.phen") )){ + smp.idx = lit.sample(x=t.idx,size=nmiss,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + #---~--- + # Fill the remaining gaps. + #---~--- + datum[[trait]] [imiss] = smp.trait + datum$country [imiss] = smp.country + datum$continent [imiss] = smp.continent + datum[[gf.trait]][imiss] = 3L + #---~--- + }#end if + #---~--- + + + #---~--- + # Adjust the gap-filling flag for trait by adding whether the scientific name + # itself was gap-filled. + #---~--- + if ("gf.scientific" %in% names(datum)){ + datum[[gf.trait]] = datum[[gf.trait]] + as.integer(10 * datum$gf.scientific) + }#end if ("gf.scientific" %in% names(datum)) + #---~--- + + + #---~--- + # Assign a plant functional type based on the wood density. + #---~--- + if (trait %in% "wood.dens"){ + pft.cut = cut(datum[[trait]],breaks=pft.breaks) + pft.levels = levels(pft.cut) + pft.idx = match(pft.cut,pft.levels) + datum$pft = mypfts[pft.idx] + }#end if (trait %in% "wood.dens") + #---~--- + return(datum) +}#end function find_trait_NEON +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# This function assigns a PFT given the genus and the full data set. This will +# use imputed data for those genera that do not have all traits. +#------------------------------------------------------------------------------------------ +assign_pft_NEON <<- function(datum,path=srcdir,refsites,verbose=FALSE,...){ + #---~--- + # Load the cluster analysis with the medoid matrix. + #---~--- + neon_lut = read.csv( file = file.path(srcdir,"NEON_taxon_lookup.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + #---~--- + + + #---~--- + # Select species from the sites of interest (it is fine to use more than one + # reference site, just mind that they should be somewhat similar. + #---~--- + sel = rep(FALSE,times=nrow(neon_lut)) + for (r in seq_along(refsites)){ + site = refsites[r] + sel = sel | neon_lut[[site]] + }#end for (r in seq_along(refsites)) + neon_lut = neon_lut[sel,,drop=FALSE] + #---~--- + + + + #---~--- + # Initialise genus with the actual one, but replace those not find in the + # look-up table. + #---~--- + if ("scientific.name" %in% names(datum)) datum$scientific = datum$scientific.name + if ("genus.name" %in% names(datum)) datum$genus = datum$genus.name + if ("family.name" %in% names(datum)) datum$family = datum$family.name + #---~--- + + + + #---~--- + # Initialise use.scientific with the actual scientific name. We will replace + # those that are not found in the look-up table for traits. + #---~--- + ans = rep(NA_integer_,times=nrow(datum)) + #---~--- + + + #---~--- + # First attempt, fill in the species that have an exact match. + #---~--- + idx = match(datum$scientific,neon_lut$scientific) + sel = ! is.na(idx) + ans[sel] = neon_lut$pft[idx[sel]] + #---~--- + + + #---~--- + # Second attempt, find genera that can be filled with existing data. + #---~--- + un_genus = sort(unique(datum$genus[is.na(ans)])) + un_genus = un_genus[un_genus %in% neon_lut$genus] + for (u in seq_along(un_genus)){ + #---~--- + # Handy alias. + #---~--- + genus_now = un_genus[u] + #---~--- + + + #---~--- + # Retrieve PFTs associated with this genus. + #---~--- + pft_pool = neon_lut$pft[neon_lut$genus %in% genus_now] + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$genus %in% genus_now ) & is.na(ans) + ans[sel] = lit.sample(x=pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_genus)) + #---~--- + + + #---~--- + # Third attempt, find families that can be filled with existing data. + #---~--- + un_family = sort(unique(datum$family[is.na(ans)])) + un_family = un_genus[un_family %in% neon_lut$family] + for (u in seq_along(un_family)){ + #---~--- + # Handy alias. + #---~--- + family_now = un_family[u] + #---~--- + + #---~--- + # Retrieve PFTs associated with this family. We include any existing data from + # this family that has been already filled, as families can be broad and it may + # be better to assume unidentified species are close to the identified species. + #---~--- + pft_pool = c( neon_lut$pft[neon_lut$family %in% family_now] + , ans[ ( datum$family %in% family_now ) & (! is.na(ans))] + )#end c + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$family %in% family_now ) & is.na(ans) + ans[sel] = lit.sample(x=pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_family)) + #---~--- + + + #---~--- + # Last attempt, sample from within the entries that have been identified. + #---~--- + sel = is.na(ans) + ans[sel] = lit.sample(x=ans[! sel],size=sum(sel),replace=TRUE) + + un_family = sort(unique(datum$family[is.na(ans)])) + un_family = un_genus[un_family %in% neon_lut$family] + for (u in seq_along(un_family)){ + #---~--- + # Handy alias. + #---~--- + family_now = un_family[u] + #---~--- + + #---~--- + # Retrieve PFTs associated with this genus. + #---~--- + pft_pool = neon_lut$pft[neon_lut$family %in% family_now] + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$family %in% family_now ) & is.na(ans) + ans[sel] = lit.sample(pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_family)) + #---~--- + + + + + #---~--- + # Assign PFT + #---~--- + return(ans) + #---~--- +}#end function assign_pft_NEON +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# Biomass allometry that is used for the NEON plots. Results are always in kgC/plant. +# +# References: +# +# Chojnacky DC, Heath LS , Jenkins JC. 2014. Updated generalized biomass equations for +# North American tree species. Forestry (Lond), 87: 129-151. +# doi:10.1093/forestry/cpt053. +# +# Lutz JA, Furniss TJ, Germain SJ, Becker KML, Blomdahl EM, Jeronimo SMA, Cansler CA, +# Freund JA, Swanson ME , Larson AJ. 2017. Shrub communities, spatial patterns, and +# shrub- mediated tree mortality following reintroduced fire in Yosemite National Park, +# California, USA. Fire Ecol., 13: 104-126. doi:10.4996/fireecology.1301104. +# +# Input: +# ---------------------------------------------------------------------------------------- +# dxh --- Diameter of reference (either DBH or basal diameter) [cm] +# wdens --- Wood density [g/cm3] +# scientific --- Species +# genus --- Genus +# family --- Family +# type --- Plant type: +# B - broadleaf tree +# N - needleleaf tree +# S - shrubs +# dead --- Life status: +# TRUE - plant is dead +# FALSE - plant is alive +# In case dead = NULL, all plants are assumed to be alive. +# eps.dbh --- Relative uncertainty for DBH [1 means 100%] +# eps.height --- Relative uncertainty for height [1 means 100%] +# eps.wdens --- Relative uncertainty for wood density [1 means 100%] +# out.err --- Output error in addition to the estimates of biomass/necromass? +# ---------------------------------------------------------------------------------------- +# +# +# +# ---------------------------------------------------------------------------------------- +# Output: +# ---------------------------------------------------------------------------------------- +# - In case out.err is FALSE, the function returns a vector with biomass for each entry. +# - In case out.err is TRUE, the output is a data frame with the following vectors +# with the same length as the entries: +# * agb -- biomass (necromass) [kgC] +# * ae.agb -- uncertainty in biomass due to allometry [kgC, not relative] +# * me.agb -- uncertainty in biomass due to measurement [kgC, not relative] +# * lnagb -- log(biomass), used for error propagation. +# * sd.lnagb -- standard error of log-biomass +#------------------------------------------------------------------------------------------ +agb_NEON <<- function( dbh + , ddh + , wdens + , scientific + , genus + , family + , type + , phenology + , woodland + , dead = NULL + , eps.dxh = 0.02 + , eps.height = 0.167 + , eps.wdens = 0.10 + , out.err = FALSE + ){ + #---~--- + # If variable "dead" is missing, assume all individuals are alive + #---~--- + if (is.null(dead)) dead = rep(FALSE,times=length(dbh)) + #---~--- + + + + #---~--- + # Make sure all terms have the same length and correct type. + #---~--- + lens = unique( c( length(dbh) , length(ddh) , length(wdens), length(scientific) + , length(genus) , length(family), length(type) , length(phenology) + , length(woodland), length(dead) ) ) + if ( length(lens) != 1 ){ + #---~--- + # Stop if any variable has a different length. + #---~--- + cat0("-----------------------------------------------------------") + cat0(" Variables don't have the same length." ) + cat0(" DBH = ",length(dbh) ) + cat0(" DDH = ",length(ddh) ) + cat0(" WDENS = ",length(wdens) ) + cat0(" SCIENTIFIC = ",length(scientific) ) + cat0(" GENUS = ",length(genus) ) + cat0(" FAMILY = ",length(family) ) + cat0(" TYPE = ",length(type) ) + cat0(" PHENOLOGY = ",length(phenology) ) + cat0(" WOODLAND = ",length(woodland) ) + cat0(" DEAD = ",length(dead) ) + cat0("-----------------------------------------------------------") + stop(" Incorrect input data.") + #---~--- + }else{ + fine.dbh = is.numeric (dbh) || all(is.na(dbh )) + fine.ddh = is.numeric (ddh) || all(is.na(ddh )) + fine.wdens = is.numeric (wdens) || all(is.na(wdens )) + fine.scientific = is.character(scientific) || all(is.na(scientific)) + fine.genus = is.character(genus) || all(is.na(genus )) + fine.family = is.character(family) || all(is.na(family )) + fine.type = is.character(type) || all(is.na(type )) + fine.phenology = is.character(phenology) || all(is.na(phenology )) + fine.woodland = is.logical (woodland) || all(is.na(woodland )) + fine.dead = is.logical (dead) || all(is.na(dead )) + all.fine = ( fine.dbh && fine.ddh && fine.wdens && fine.scientific + && fine.genus && fine.family && fine.type && fine.phenology + && fine.woodland && fine.dead + )#end all.fine + #---~--- + # Stop if anything is unexpected. + #---~--- + if (! all.fine){ + cat0("-----------------------------------------------------------") + cat0(" Not all variables have the correct type." ) + cat0(" DBH (numeric) = ",fine.dbh ) + cat0(" DDH (numeric) = ",fine.ddh ) + cat0(" WDENS (numeric) = ",fine.wdens ) + cat0(" SCIENTIFIC (character) = ",fine.scientific ) + cat0(" GENUS (character) = ",fine.genus ) + cat0(" FAMILY (character) = ",fine.family ) + cat0(" TYPE (character) = ",fine.type ) + cat0(" PHENOLOGY (character) = ",fine.phenology ) + cat0(" WOODLAND (logical) = ",fine.woodland ) + cat0(" DEAD (logical) = ",fine.dead ) + cat0("-----------------------------------------------------------") + stop(" Incorrect data types.") + }#end if (! all.fine) + #---~--- + }#end if ( length(lens) != 1) + #---~--- + + + + #---~--- + # Initialise the output. + #---~--- + a0.agb = NA_real_ * dbh + a1.agb = NA_real_ * dbh + #---~--- + + + + #---~--- + # Simplify phenology labels. + #---~--- + phenology = toupper(substr(phenology,1,1)) + #---~--- + + + #---~--- + # Link names to the equation sets. + #---~--- + bleaf = ( type %in% "B" ) & (! dead) + nleaf = ( type %in% "N" ) & (! dead) + shrub = ( type %in% "S" ) & (! dead) + tree = ( bleaf | nleaf ) & (! shrub) + wlnd = tree & woodland + multigroup.01 = family %in% c( "Cornaceae" , "Ericaceae", "Lauraceae" + , "Platanaceae", "Rosaceae" , "Ulmaceae" ) + multigroup.02 = family %in% c("Fabaceae","Juglandaceae") + multigroup.03 = family %in% c("Hippocastanaceae","Tiliaceae") + multigroup.04 = family %in% c("Fabaceae","Rosaceae") + #---~--- + + + + #---~--- + # Define generic diameter (useful for shrubs). + #---~--- + dxh = ifelse( test = shrub | wlnd + , yes = ifelse( test = is.finite(ddh), yes = ddh, no = dbh ) + , no = ifelse( test = is.finite(dbh), yes = dbh, no = ddh ) + )#end ifelse + #---~--- + + + #---~--- + # Handles for the tree equations + #---~--- + t.abies.lwr = (genus %in% "Abies" ) & (wdens %lt% 0.35 ) & tree + t.abies.upr = (genus %in% "Abies" ) & (wdens %ge% 0.35 ) & tree + t.cupressaceae.lwr = (family %in% "Cupressaceae" ) & (wdens %lt% 0.30 ) & tree + t.cupressaceae.mid = (family %in% "Cupressaceae" ) & (wdens %wl% c(0.30,0.40)) & tree + t.cupressaceae.upr = (family %in% "Cupressaceae" ) & (wdens %ge% 0.40 ) & tree + t.larix = (genus %in% "Larix" ) & tree + t.picea.lwr = (genus %in% "Picea" ) & (wdens %lt% 0.35 ) & tree + t.picea.upr = (genus %in% "Picea" ) & (wdens %ge% 0.35 ) & tree + t.pinus.lwr = (genus %in% "Pinus" ) & (wdens %lt% 0.45 ) & tree + t.pinus.upr = (genus %in% "Pinus" ) & (wdens %ge% 0.45 ) & tree + t.pseudotsuga = (genus %in% "Pseudotsuga" ) & tree + t.tsuga.lwr = (genus %in% "Tsuga" ) & (wdens %lt% 0.40 ) & tree + t.tsuga.upr = (genus %in% "Tsuga" ) & (wdens %ge% 0.40 ) & tree + t.aceraceae.lwr = (family %in% "Aceraceae" ) & (wdens %lt% 0.50 ) & tree + t.aceraceae.upr = (family %in% "Aceraceae" ) & (wdens %ge% 0.50 ) & tree + t.betulaceae.lwr = (family %in% "Betulaceae" ) & (wdens %lt% 0.40 ) & tree + t.betulaceae.lmd = (family %in% "Betulaceae" ) & (wdens %wl% c(0.40,0.50)) & tree + t.betulaceae.umd = (family %in% "Betulaceae" ) & (wdens %wl% c(0.50,0.60)) & tree + t.betulaceae.upr = (family %in% "Betulaceae" ) & (wdens %ge% 0.60 ) & tree + t.multigroup.01 = (family %in% multigroup.01 ) & tree + t.carya = (genus %in% "Carya" ) & tree + t.multigroup.02 = (family %in% multigroup.02 ) & ( ! genus %in% "Carya" ) & tree + t.fagaceae.dcd = (family %in% "Fagaceae" ) & (phenology %in% "D" ) & tree + t.fagaceae.evg = (family %in% "Fagaceae" ) & (phenology %in% "E" ) & tree + t.hamamelidaceae = (family %in% "Hamamelidaceae") & tree + t.multigroup.03 = (family %in% multigroup.03 ) & tree + t.magnoliaceae = (family %in% "Magnoliaceae" ) & tree + t.oleaceae.lwr = (family %in% "Oleaceae" ) & (wdens %lt% 0.55 ) & tree + t.oleaceae.upr = (family %in% "Oleaceae" ) & (wdens %ge% 0.55 ) & tree + t.salicaceae.lwr = (family %in% "Salicaceae" ) & (wdens %lt% 0.35 ) & tree + t.salicaceae.upr = (family %in% "Salicaceae" ) & (wdens %ge% 0.35 ) & tree + w.cupressaceae = (family %in% "Cupressaceae" ) & wlnd + w.multigroup.04 = (family %in% multigroup.04 ) & wlnd + w.fagaceae = (family %in% "Fagaceae" ) & wlnd + w.pinaceae = (family %in% "Pinaceae" ) & wlnd + #---~--- + + + #---~--- + # Handles for the shrub equations. + #---~--- + s.arctostaphylos = (genus %in% "Arctostaphylos") & shrub + s.ceanothus = (genus %in% "Ceanothus" ) & shrub + s.chrysolepis = (genus %in% "Chrysolepis" ) & shrub + s.corylus = (genus %in% "Corylus" ) & shrub + s.cornus = (genus %in% "Cornus" ) & shrub + s.leucothoe = (genus %in% "Leucothoe" ) & shrub + s.rhododendron = (genus %in% "Rhododendron" ) & shrub + s.ribes = (genus %in% "Ribes" ) & shrub + s.rosa = (genus %in% "Rosa" ) & shrub + s.rubus = (genus %in% "Rubus" ) & shrub + s.sambucus = (genus %in% "Sambucus" ) & shrub + s.symphoricarpos = (genus %in% "Symphoricarpos") & shrub + s.vaccinium = (genus %in% "Vaccinium" ) & shrub + #---~--- + + + + #---~--- + # Set coefficients. We initialise them with a generic equation that only + # distinguishes whether they are shrubs, broadleaf trees, or needleleaf trees. For + # trees, we currently used some common families, but this can be refined later. + # After the initial assignment, we update the coefficients if we find a better match + # for the tree/shrub. + #---~--- + #--- General coefficients + a0.agb[bleaf ] = -2.2118 ; a1.agb[bleaf ] = 2.4133 + a0.agb[nleaf ] = -2.6177 ; a1.agb[nleaf ] = 2.4638 + a0.agb[shrub ] = -3.1478 ; a1.agb[shrub ] = 2.3750 + #--- Specific coefficients + a0.agb[t.abies.lwr ] = -2.3123 ; a1.agb[t.abies.lwr ] = 2.3482 + a0.agb[t.abies.upr ] = -3.1774 ; a1.agb[t.abies.upr ] = 2.6426 + a0.agb[t.cupressaceae.lwr] = -1.9615 ; a1.agb[t.cupressaceae.lwr] = 2.1063 + a0.agb[t.cupressaceae.mid] = -2.7765 ; a1.agb[t.cupressaceae.mid] = 2.4195 + a0.agb[t.cupressaceae.upr] = -2.6327 ; a1.agb[t.cupressaceae.upr] = 2.4757 + a0.agb[t.larix ] = -2.3012 ; a1.agb[t.larix ] = 2.3853 + a0.agb[t.picea.lwr ] = -3.0300 ; a1.agb[t.picea.lwr ] = 2.5567 + a0.agb[t.picea.upr ] = -2.1364 ; a1.agb[t.picea.upr ] = 2.3233 + a0.agb[t.pinus.lwr ] = -2.6177 ; a1.agb[t.pinus.lwr ] = 2.4638 + a0.agb[t.pinus.upr ] = -3.0506 ; a1.agb[t.pinus.upr ] = 2.6465 + a0.agb[t.pseudotsuga ] = -2.4623 ; a1.agb[t.pseudotsuga ] = 2.4852 + a0.agb[t.tsuga.lwr ] = -2.3480 ; a1.agb[t.tsuga.lwr ] = 2.3876 + a0.agb[t.tsuga.upr ] = -2.9208 ; a1.agb[t.tsuga.upr ] = 2.5697 + a0.agb[t.aceraceae.lwr ] = -2.0470 ; a1.agb[t.aceraceae.lwr ] = 2.3852 + a0.agb[t.aceraceae.upr ] = -1.8011 ; a1.agb[t.aceraceae.upr ] = 2.3852 + a0.agb[t.betulaceae.lwr ] = -2.5932 ; a1.agb[t.betulaceae.lwr ] = 2.5349 + a0.agb[t.betulaceae.lmd ] = -2.2271 ; a1.agb[t.betulaceae.lmd ] = 2.4513 + a0.agb[t.betulaceae.umd ] = -1.8096 ; a1.agb[t.betulaceae.umd ] = 2.3480 + a0.agb[t.betulaceae.upr ] = -2.2652 ; a1.agb[t.betulaceae.upr ] = 2.5349 + a0.agb[t.multigroup.01 ] = -2.2118 ; a1.agb[t.multigroup.01 ] = 2.4133 + a0.agb[t.carya ] = -2.5095 ; a1.agb[t.carya ] = 2.6175 + a0.agb[t.multigroup.02 ] = -2.5095 ; a1.agb[t.multigroup.02 ] = 2.5437 + a0.agb[t.fagaceae.dcd ] = -2.0705 ; a1.agb[t.fagaceae.dcd ] = 2.4410 + a0.agb[t.fagaceae.evg ] = -2.2198 ; a1.agb[t.fagaceae.evg ] = 2.4410 + a0.agb[t.hamamelidaceae ] = -2.6390 ; a1.agb[t.hamamelidaceae ] = 2.5466 + a0.agb[t.multigroup.03 ] = -2.4108 ; a1.agb[t.multigroup.03 ] = 2.4177 + a0.agb[t.magnoliaceae ] = -2.5497 ; a1.agb[t.magnoliaceae ] = 2.5011 + a0.agb[t.oleaceae.lwr ] = -2.0314 ; a1.agb[t.oleaceae.lwr ] = 2.3524 + a0.agb[t.oleaceae.upr ] = -1.8384 ; a1.agb[t.oleaceae.upr ] = 2.3524 + a0.agb[t.salicaceae.lwr ] = -2.6863 ; a1.agb[t.salicaceae.lwr ] = 2.4561 + a0.agb[t.salicaceae.upr ] = -2.4441 ; a1.agb[t.salicaceae.upr ] = 2.4561 + a0.agb[w.cupressaceae ] = -2.7096 ; a1.agb[w.cupressaceae ] = 2.1942 + a0.agb[w.multigroup.04 ] = -2.9255 ; a1.agb[w.multigroup.04 ] = 2.4109 + a0.agb[w.fagaceae ] = -3.0304 ; a1.agb[w.fagaceae ] = 2.4982 + a0.agb[w.pinaceae ] = -3.2007 ; a1.agb[w.pinaceae ] = 2.5339 + a0.agb[s.arctostaphylos ] = -3.5892 ; a1.agb[s.arctostaphylos ] = 2.6846 + a0.agb[s.ceanothus ] = -3.2406 ; a1.agb[s.ceanothus ] = 2.6502 + a0.agb[s.chrysolepis ] = -3.0198 ; a1.agb[s.chrysolepis ] = 2.3110 + a0.agb[s.corylus ] = -3.3776 ; a1.agb[s.corylus ] = 2.3720 + a0.agb[s.cornus ] = -3.5928 ; a1.agb[s.cornus ] = 2.6470 + a0.agb[s.leucothoe ] = -4.1588 ; a1.agb[s.leucothoe ] = 2.3060 + a0.agb[s.rhododendron ] = -3.1478 ; a1.agb[s.rhododendron ] = 2.3750 + a0.agb[s.ribes ] = -3.1478 ; a1.agb[s.ribes ] = 2.3750 + a0.agb[s.rosa ] = -3.1478 ; a1.agb[s.rosa ] = 2.3750 + a0.agb[s.rubus ] = -3.1478 ; a1.agb[s.rubus ] = 2.3750 + a0.agb[s.sambucus ] = -3.3378 ; a1.agb[s.sambucus ] = 2.3720 + a0.agb[s.symphoricarpos ] = -3.1478 ; a1.agb[s.symphoricarpos ] = 2.3750 + a0.agb[s.vaccinium ] = -3.1478 ; a1.agb[s.vaccinium ] = 2.3750 + #---~--- + + + #---~--- + # Find biomass. + #---~--- + agb = exp(a0.agb + a1.agb * log(dxh)) / C2B + #---~--- + + + #---~--- + # Check whether to estimate associated errors (measurement and allometry), + # following: + # + # Chave, J., and co-authors, 2004: Error propagation and scaling for tropical forest + # biomass estimates. Phil. Trans. R. Soc. Lond. B., 359, 409-420. + # doi:10.1098/rstb.2003.1425 + #---~--- + if (out.err){ + #---~--- + # Find error associated with allometry. The papers do not present the actual error + # of each equation. For the time being, we use the same error as reported by + # Chave et al. (2014) as a zero-order guess. + # + # Chave, J., and co-authors, 2014: Improved allometric models to estimate the + # aboveground biomass of tropical trees. Glob. Change Biol., 20, 3177-3190 + # doi:10.1111/gcb.12629 + #---~--- + ae.agb = sqrt(exp(0.357^2)-1)*agb + #---~--- + + + + #---~--- + # Find error associated with measurements. + #---~--- + me.agb = agb * a1.agb * eps.dxh + #---~--- + + + #---~--- + # Save the standard error of the log scale: it will be useful for error analysis. + # The 0*agb term will ensure that sd.lnagb will be NA when agb is NA. + #---~--- + sd.lnagb = 0.357 + 0. * agb + #---~--- + + #---~--- + # Combine estimates and errors in a data frame. + #---~--- + ans = data.frame( agb = agb + , a0 = a0.agb + , a1 = a1.agb + , ae.agb = ae.agb + , me.agb = me.agb + , lnagb = log(agb) - 0.5 * sd.lnagb^2 + , sd.lnagb = sd.lnagb + )#end data.frame + #---~--- + + }else{ + #---~--- + # No error needed. Return estimate only. + #---~--- + ans = agb + #---~--- + }#end if + #---~--- + + return(ans) +}#end function agb_NEON +#========================================================================================== +#========================================================================================== + + + + + +#========================================================================================== +#========================================================================================== +# This function determines the plot aggregated error due to measurement and +# allometry for NEON. +# +# Input: +# ---------------------------------------------------------------------------------------- +# datum - a data frame with all trees in this plot (note, you can't run this for all +# plots at once, either use a for loop or mapply). The data frame must +# contain the following variables: +# * nplant - 1/area sampled if tree is alive, zero if tree is dead [1/m2] +# * ntotal - 1/area sampled [1/m2] +# For nplant/ntotal, if the sampled area was 2500 m2, the number should be +# 0.0004. In case a differential sampling effort was used, then nplant +# varies. For example, if trees with 10 <= DBH < 35 cm were measured in a +# 50x5 subplot and trees with DBH >= 35 cm were measured in the entire +# 2500m2 plots, then nplant should be 0.004 for the trees with DBH < 35cm +# and 0.0004 for trees with DBH >= 35cm. +# * AGC - above-ground carbon [ kgC] +# * ME.AGC - measurement uncertainty of above-ground carbon [ kgC] +# * LNAGC - log of above-ground carbon +# * SD.LNAGC - allometry uncertainty, using the log-scale +# * X - x position in the plot (used only if epsilon.smp is NULL) +# * Y - y position in the plot (used only if epsilon.smp is NULL) +# xmax - maximum size along the x axis (used only if epsilon.smp is NULL) +# ymax - maximum size along the y axis (used only if epsilon.smp is NULL) +# subalong - which axis has the subplot +# epsilon.smp - in case epsilon.smp is null, the function will try to estimate within-plot +# sampling uncertainty. This is unlikely to work unless you have large +# plots or at the very least have plots without sub-sampling. +# Alternatively, you may provide the number from previous studies. +# n.sub - number of subplot samples +# n.real - number of replicates for estimating uncertainty. Large numbers +# (10000 or more) are needed for stable results. +# ---------------------------------------------------------------------------------------- +# +# +# +# ---------------------------------------------------------------------------------------- +# Output: +# ---------------------------------------------------------------------------------------- +# A vector with 8 numbers: +# se.agb.xxxxx - uncertainties for plot estimate of biomass (no standing dead) [kgC/m2] +# se.acd.xxxxx - uncertainties for plot estimate of biomass+necromass [kgC/m2] +# se.xxx.measurement - contribution of measurement uncertainty to plot uncertainty +# se.xxx.allometry - contribution of allometry uncertainty to plot uncertainty +# se.xxx.sampling - contribution of sampling uncertainty to plot uncertainty +# se.xxx.census - total uncertainty (combining the three terms above). +#------------------------------------------------------------------------------------------ +find_agb_error_NEON <<- function(datum,xmax,ymax,subalong=c("x","y"),epsilon.smp=NULL + ,n.sub=25,n.real=10000){ + + #---~--- + # Standardise subalong. + #---~--- + subalong = match.arg(subalong) + #---~--- + + + #---~--- + # Number of data points. + #---~--- + ndatum = nrow(datum) + #---~--- + + + #---~--- + # First, find the combined error. + #---~--- + se.use = data.frame( measurement = sqrt(log(1+(datum$ME.AGC / datum$AGC)^2)) + , allometry = datum$SD.LNAGC + )#end datum + #---~--- + + + #---~--- + # Initialise answer. + #---~--- + se.agb = rep(x=NA_real_,length(se.use)+2) + names(se.agb) = c(names(se.use),"sampling","census") + #---~--- + + + + #---~--- + # Create a population matrix. + #---~--- + NPLANT = matrix( data = rep(datum$nplant,times=n.real), nrow=ndatum,ncol=n.real) + #---~--- + + + #---~--- + # Initialise answer. We will create the vector before and loop through the errors. + #---~--- + for (e in seq_along(se.use)){ + AGC = matrix( data = rlnorm( n = n.real*ndatum + , meanlog = rep(datum$LNAGC,times=n.real) + , sdlog = rep(se.use[[e]],times=n.real) + )#end rlnorm + , nrow = ndatum + , ncol = n.real + )#end matrix + AGB = colSums(NPLANT * AGC) + se.agb[e] = sd(AGB) + }#end for (e in seq_along(se.use)) + #---~--- + + + #---~--- + # Find total biomass, to be used by the within plot sampling error. + #---~--- + agb.bar = sum(datum$nplant * datum$AGC) + #---~--- + + + #---~--- + # Unless epsilon.smp is provided, we estimate the within-plot sampling error. + #---~--- + if (is.null(epsilon.smp)){ + #---~--- + # Split domain into smaller subsplots. + #---~--- + if (subalong %in% "x"){ + xbreaks = seq(from=0,to=xmax,length.out=n.sub+1) + xlwr = sqrt(.Machine$double.eps) * xmax + xupr = (1. - sqrt(.Machine$double.eps)) * xmax + xnow = pmax(xlwr,pmin(xupr,datum$X)) + isub = as.integer(cut(xnow,breaks=xbreaks)) + }else{ + ybreaks = seq(from=0,to=ymax,length.out=n.sub+1) + ylwr = sqrt(.Machine$double.eps) * ymax + yupr = (1. - sqrt(.Machine$double.eps)) * ymax + ynow = pmax(ylwr,pmin(yupr,datum$Y)) + isub = as.integer(cut(ynow,breaks=ybreaks)) + }#end if + #---~--- + + + #---~--- + # Find the AGB/ACD for each subplot. + #---~--- + agb.sub = rep(0.,times=n.sub) + acd.sub = rep(0.,times=n.sub) + agb.tmp = tapply(X=n.sub*datum$nplant*datum$AGC,INDEX=isub,FUN=sum) + acd.tmp = tapply(X=n.sub*datum$ntotal*datum$AGC,INDEX=isub,FUN=sum) + agb.idx = as.integer(names(agb.tmp)) + acd.idx = as.integer(names(acd.tmp)) + agb.sub[agb.idx] = agb.tmp + acd.sub[acd.idx] = acd.tmp + #---~--- + + + + + #---~--- + # Create replicates using bootstrap with replacement. + #---~--- + AGB = colMeans( matrix( data = sample(agb.sub,size=n.real*n.sub,replace=TRUE) + , nrow = n.sub + , ncol = n.real + )#end matrix + )#end colMeans + se.agb["sampling"] = sd(AGB) + #---~--- + }else{ + #---~--- + # Use pre-defined sampling error. + #---~--- + se.agb["sampling"] = epsilon.smp * agb.bar + #---~--- + }#end if (is.null(epsilon.smp)) + #---~--- + + + + #---~--- + # Find combined source of errors. + #---~--- + se.agb["census"] = sqrt(sum(se.agb[c("measurement","allometry","sampling")]^2)) + #---~--- + + + #---~--- + # Error is the standard deviation of all realisations. + #---~--- + ans = se.agb + names(ans) = paste0("se.agb.",names(se.agb)) + #---~--- + + + #---~--- + # Return answer. + #---~--- + return(ans) + #---~--- +}#end find_agb_error_NEON +#========================================================================================== +#========================================================================================== diff --git a/R-utils/nls.wgtfct.r b/R-utils/nls.wgtfct.r index 1236456ca..fbdbf21c7 100644 --- a/R-utils/nls.wgtfct.r +++ b/R-utils/nls.wgtfct.r @@ -126,7 +126,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. --------------------------------# - xysigma = ifelse(xysigma %>% 0 ,xysigma,NA) + xysigma = ifelse(xysigma %gt% 0 ,xysigma,NA) assign(x="xysigma",value=xysigma,envir=newEnv) #------------------------------------------------------------------------------------# }#end if (length(grep("xysigma", expr)) > 0) @@ -148,7 +148,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. --------------------------------# - yysigma = ifelse(yysigma %>% 0 ,yysigma,NA) + yysigma = ifelse(yysigma %gt% 0 ,yysigma,NA) assign(x="yysigma",value=yysigma,envir=newEnv) #------------------------------------------------------------------------------------# }#end if (length(grep("yysigma", expr)) > 0) @@ -207,7 +207,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. -----------------------------# - xrsigma = ifelse(xrsigma %>% 0 ,xrsigma,NA) + xrsigma = ifelse(xrsigma %gt% 0 ,xrsigma,NA) assign(x="xrsigma",value=xrsigma,envir=newEnv) #---------------------------------------------------------------------------------# }#end if (length(grep("xrsigma", expr)) > 0) @@ -229,7 +229,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. -----------------------------# - yrsigma = ifelse(yrsigma %>% 0 ,yrsigma,NA) + yrsigma = ifelse(yrsigma %gt% 0 ,yrsigma,NA) assign(x="yrsigma",value=yrsigma,envir=newEnv) #---------------------------------------------------------------------------------# }#end if (length(grep("yrsigma", expr)) > 0) @@ -243,7 +243,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ # values or negative numbers, if they somehow exist, replace them by zero. # #---------------------------------------------------------------------------------------# ans = eval(expr=parse(text = expr), envir = newEnv) - ans = ifelse(ans %>% 0, ans, 0) + ans = ifelse(ans %gt% 0, ans, 0) ans = c(ans) names(ans) = NULL #---------------------------------------------------------------------------------------# diff --git a/R-utils/normalise.r b/R-utils/normalise.r index 6845f4cb3..3ae20ad41 100644 --- a/R-utils/normalise.r +++ b/R-utils/normalise.r @@ -19,7 +19,7 @@ normalise <<- function(x,mu,sigma,distr=c("best","normal","lognormal","skewnorma #----- Exclude missing points. ---------------------------------------------------------# xfit = x[is.finite(x)] nxfit = length(xfit) - lntry = all(xfit %>% 0) + lntry = all(xfit %gt% 0) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# diff --git a/R-utils/numutils.r b/R-utils/numutils.r index 8444e5dc1..3cd30589b 100644 --- a/R-utils/numutils.r +++ b/R-utils/numutils.r @@ -15,6 +15,41 @@ cbrt <<- function(x){ +#==========================================================================================# +#==========================================================================================# +# Function that finds the integer divisors of an integer and positive number. # +#------------------------------------------------------------------------------------------# +divisors <<- function(x){ + #---- Do not attempt to find divisors for non-integer quantities. ----------------------# + xint = as.integer(x) + #---------------------------------------------------------------------------------------# + + #---- Find the results for each value. -------------------------------------------------# + if (length(x) > 1L){ + ans = mapply( FUN = divisors, x = as.list(x)) + }else if( xint %eq% x){ + #--- Vector of potential divisors. We stop at half to speed up the code. ------------# + ans = seq_len(ceiling(abs(x)/2)) + ans = c(ans[ (x %% ans) %eq% 0L],x) + #------------------------------------------------------------------------------------# + }else{ + #---- Number is not integer, return nothing. ----------------------------------------# + ans = integer(length=0L) + #------------------------------------------------------------------------------------# + }#end if(length(x) > 1L) + #---------------------------------------------------------------------------------------# + + #---- Return results. ------------------------------------------------------------------# + return(ans) + #---------------------------------------------------------------------------------------# +}#end function divisors +#==========================================================================================# +#==========================================================================================# + + + + + #==========================================================================================# #==========================================================================================# # Functions that finds round of the log of the number. # @@ -34,7 +69,21 @@ round.log2 <<- function(x,...) 2^(round(log2(x),...)) # Base 10 exponential. # #------------------------------------------------------------------------------------------# exp10 <<- function(x,...) 10^x +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# Negative log of negative numbers. # +#------------------------------------------------------------------------------------------# +neglog <<- function(x,...) -log(-x) +negexp <<- function(x,...) -exp(-x) +neglog10 <<- function(x,...) -log10(-x) +negexp10 <<- function(x,...) -10^(-x) #==========================================================================================# #==========================================================================================# @@ -54,11 +103,11 @@ bound <<- function(x,lwr=min(x,na.rm=TRUE),upr=max(x,na.rm=TRUE),buff=2^-23){ #---------------------------------------------------------------------------------------# # Don't let the bounds to be insane. # #---------------------------------------------------------------------------------------# - if (lwr %>% upr){ + if (lwr %gt% upr){ cat0(" - Lower limit: ",lwr) cat0(" - Upper limit: ",upr) stop(" Lower and upper limit must be finite and lower cannot be greater than upper.") - }#end if (lwr %>% upr) + }#end if (lwr %gt% upr) #---------------------------------------------------------------------------------------# @@ -68,7 +117,7 @@ bound <<- function(x,lwr=min(x,na.rm=TRUE),upr=max(x,na.rm=TRUE),buff=2^-23){ if (! (buff %wr% c(0,1-2^-23))){ cat0(" - buff: ",buff) stop(" Buffer must be between 0 (including) and 1 (excluding).") - }#end if (lwr %>% upr) + }#end if (! (buff %wr% c(0,1-2^-23))) #---------------------------------------------------------------------------------------# @@ -271,7 +320,7 @@ weighted.frac <<- function(x,w,na.rm=TRUE){ names(ans) = names(x) return(ans) #------------------------------------------------------------------------------------# - }else if (all(w %==% 0.)){ + }else if (all(w %eq% 0.)){ #----- Give equal chances in case all weights were zero. ----------------------------# w = rep(x=1.,times=nrow(x)) #------------------------------------------------------------------------------------# @@ -305,9 +354,9 @@ weighted.frac <<- function(x,w,na.rm=TRUE){ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FALSE){ #----- Delete the missing values if the user asked to do it. ---------------------------# - if (any(w <= 0, na.rm = TRUE) || any(is.infinite(w)) || any(is.na(w))){ + if (any(w %le% 0, na.rm = TRUE) || any(is.infinite(w)) || any(is.na(w))){ stop(" Weights (w) must be positive and finite, and entirely defined!") - }else if(qu < 0. || qu > 1.){ + }else if(qu %or% c(0,1.)){ stop(" Quantile (qu) must be between 0 and 1. ") }else if(na.rm){ keep = ! is.na(x) @@ -318,6 +367,14 @@ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FAL + #---------------------------------------------------------------------------------------# + # If nothing remains, return NA. # + #---------------------------------------------------------------------------------------# + if (length(x) == 0) return(NA_real_) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Define the probabilities by normalising the weights. # #---------------------------------------------------------------------------------------# @@ -341,18 +398,18 @@ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FAL #---------------------------------------------------------------------------------------# # Sort the values by the probability. # #---------------------------------------------------------------------------------------# - if (qu <= cum[1]){ + if (qu %le% cum[1]){ qout = x[1] case = "minimum" - }else if (qu >= cum[length(cum)]){ + }else if (qu %ge% cum[length(cum)]){ qout = x[length(cum)] case = "maximum" - }else if (any(cum == qu)){ - qout = x[which(cum == qu)] + }else if (any(cum %eq% qu)){ + qout = x[which(cum %eq% qu)] case = "exact" }else{ - below = qu - cum ; below[below < 0] = Inf - above = cum - qu ; above[above < 0] = Inf + below = qu - cum ; below[below %lt% 0] = Inf + above = cum - qu ; above[above %lt% 0] = Inf i.below = which.min(below) i.above = which.min(above) w.below = 1. / (below[i.below]^2) @@ -404,7 +461,7 @@ weighted.sd <<- function(x,w,M=NULL,na.rm=FALSE){ #---------------------------------------------------------------------------------------# # Check whether at least one weight is non-zero. # #---------------------------------------------------------------------------------------# - if (all(w %==% 0)){ + if (all(w %eq% 0)){ ans = NA }else{ xwm = weighted.mean(x=x,w=w) @@ -735,7 +792,7 @@ meansdcv <<- function (x, na.rm = FALSE){ nx = length(xx) mu = mean(xx) sigma = sd(xx) - cvar = ifelse(sigma %>% 0,mu/sigma,NA) + cvar = ifelse(sigma %gt% 0,mu/sigma,NA) ans = c( mean = mu , sd = sigma @@ -1086,7 +1143,7 @@ mean.se <<- function(x,...) sqrt(x = mean(x=x^2,...) / length(x[is.fini #==========================================================================================# # Mean of elements that are finite and above minimum. # #------------------------------------------------------------------------------------------# -mean.above <<- function(x,xlwr,xnot=xlwr) if(any(x%>=%xlwr)){mean(x[x%>=%xlwr])}else{xnot} +mean.above <<- function(x,xlwr,xnot=xlwr) if(any(x%ge%xlwr)){mean(x[x%ge%xlwr])}else{xnot} #==========================================================================================# #==========================================================================================# @@ -1646,6 +1703,32 @@ left.cumprod <<- function(x) c(0,cumprod(x)[-length(x)]) +#==========================================================================================# +#==========================================================================================# +# These functions are similar to cumsum, except that they ignore values above or below # +# a certain threshold (source: (https://stackoverflow.com/questions/63636052/ # +# calculate-cumulative-sum-cumsum-floored-at-zero). # +#------------------------------------------------------------------------------------------# +#----- cumulative sum floored at thresh. --------------------------------------------------# +floor.cumsum <<- function(x,thresh=0){ + cs = cumsum(x) + cn = cummin(cs) + ans = cs - pmin(cn,thresh) + return(ans) +}#end floor.cumsum +#----- cumulative sum capped at thresh. ---------------------------------------------------# +ceiling.cumsum <<- function(x,thresh=0){ + cs = cumsum(x) + cx = cummax(cs) + ans = cs - pmax(cx,thresh) + return(ans) +}#end ceiling.cumsum +#==========================================================================================# +#==========================================================================================# + + + + #==========================================================================================# #==========================================================================================# # This function calculates cumulative sum for data with gaps. It will treat NA as # @@ -1742,7 +1825,7 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #---------------------------------------------------------------------------------------# if (all(! (is.na(x) | is.nan(x)))){ #------------------------------------------------------------------------------------# - # Decide what to do based on whether to limit maximum (thmax=TRUE) or maximum # + # Decide what to do based on whether to limit maximum (thmax=TRUE) or minimum # # (thmax=FALSE) values. I couldn't think of a vector way to solve this, so for now # # I am using for loops. # #------------------------------------------------------------------------------------# @@ -1755,9 +1838,9 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #---------------------------------------------------------------------------------# }else{ #----- Threshold is the maximum allowed value. -----------------------------------# - ans[1] = max(c(thresh,x[1])) + ans[1] = max(c(xthresh,x[1])) for (i in sequence(nx)[-1]){ - ans[i] = max(thresh,ans[i-1]+x[i]) + ans[i] = max(xthresh,ans[i-1]+x[i]) }#end for (i in sequence(nx)[-1]) #---------------------------------------------------------------------------------# }#end if (thmax) @@ -1792,7 +1875,7 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #------------------------------------------------------------------------------------------# aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #----- Check that fmin makes sense. ----------------------------------------------------# - if (! (fmin %>=% 0.0 & fmin %<=% 1.0)){ + if (! (fmin %ge% 0.0 & fmin %le% 1.0)){ stop (paste0("fmin must be between 0 and 1! Yours is set to ",fmin,"...")) }#end if #---------------------------------------------------------------------------------------# @@ -1815,8 +1898,8 @@ aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #----- Use only valid points. -------------------------------------------------------# xuse = x[is.finite(x)] ans = fun(xuse,...) - discard = ! is.finite(ans) - ans[discard] = NA + is.bad = ! is.finite(ans) + ans[is.bad] = NA #------------------------------------------------------------------------------------# }else if (nkeep >= 1){ #----- Use only valid points. -------------------------------------------------------# @@ -1860,7 +1943,7 @@ aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #------------------------------------------------------------------------------------------# aggr.se <<- function(x,fmin=0.5,...){ #----- Check that fmin makes sense. ----------------------------------------------------# - if (! (fmin %>=% 0.0 & fmin %<=% 1.0)){ + if (! (fmin %ge% 0.0 & fmin %le% 1.0)){ stop (paste0("fmin must be between 0 and 1! Yours is set to ",fmin,"...")) }#end if #---------------------------------------------------------------------------------------# @@ -1879,8 +1962,8 @@ aggr.se <<- function(x,fmin=0.5,...){ xuse = x[is.finite(x)] nuse = length(xuse) ans = sqrt(mean(xuse^2)/nuse) - discard = ! is.finite(ans) - ans[discard] = NA + is.bad = ! is.finite(ans) + ans[is.bad] = NA #------------------------------------------------------------------------------------# }else{ #----- Return NA. -------------------------------------------------------------------# @@ -1912,18 +1995,44 @@ max.abs.diff <<- function(x,y,na.rm=TRUE) max(abs(x-y),na.rm=na.rm) #==========================================================================================# #==========================================================================================# -# This function counts the number of valid entries. # +# This function checks whether or not the values are valid. # #------------------------------------------------------------------------------------------# -count.valid <<- function(x,qq.rm=FALSE){ +is.valid <<- function(x,qq.rm=FALSE){ type.x = typeof(x) if (type.x %in% "logical"){ - ans = sum(! is.na(x)) + ans = ! is.na(x) }else if (type.x %in% "character"){ - ans = sum(! ( is.na(x) | ((x %in% "") & qq.rm))) + ans = ! ( is.na(x) | ((x %in% "") & qq.rm)) }else{ - ans = sum(is.finite(x)) + ans = ! is.finite(x) }#end if (type.x %in% c("logical","character")) return(ans) -}#end count.finite +}#end is.finite +#==========================================================================================# +#==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# This function counts the number of valid entries. # +#------------------------------------------------------------------------------------------# +count.valid <<- function(x,qq.rm=FALSE) sum(is.valid(x,qq.rm=qq.rm)) +#==========================================================================================# +#==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Error function and complementary error function. These are borrowed from package # +# pracma, use locally defined to avoid conflicts with many other functions. # +#------------------------------------------------------------------------------------------# +errfun <<- function(x){ pchisq(2 * x^2,1) * sign(x)} +errfunc <<- function(x){ 2. * pnorm(-sqrt(2.)*x)} #==========================================================================================# #==========================================================================================# diff --git a/R-utils/operators.r b/R-utils/operators.r index ea5278d88..cc92a5aa0 100644 --- a/R-utils/operators.r +++ b/R-utils/operators.r @@ -5,7 +5,7 @@ #----- Safe logical operators. These will always return FALSE if x or y are not finite. --# -'%==%' <<- function(x,y){ +'%eq%' <<- function(x,y){ if (any(c(FALSE,is.numeric(x) & is.numeric(y)),na.rm=TRUE)){ ans = is.finite(unlist(x)) & is.finite(unlist(y)) & x == y }else{ @@ -13,7 +13,7 @@ }#end if return(ans) }#end function -'%!=%' <<- function(x,y){ +'%ne%' <<- function(x,y){ if (any(c(FALSE,is.numeric(x) & is.numeric(y)),na.rm=TRUE)){ ans = is.finite(unlist(x)) & is.finite(unlist(y)) & x != y }else{ @@ -21,10 +21,10 @@ }#end if return(ans) }#end function -'%>%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x > y -'%<%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x < y -'%>=%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x >= y -'%<=%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x <= y +'%gt%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x > y +'%lt%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x < y +'%ge%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x >= y +'%le%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x <= y #------------------------------------------------------------------------------------------# diff --git a/R-utils/optim.gbm.r b/R-utils/optim.gbm.r index f60dd04ae..c1b89d481 100644 --- a/R-utils/optim.gbm.r +++ b/R-utils/optim.gbm.r @@ -137,6 +137,9 @@ optim.gbm <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) diff --git a/R-utils/optim.lsq.htscd.r b/R-utils/optim.lsq.htscd.r index 3f3eccdb3..e15b51aaf 100644 --- a/R-utils/optim.lsq.htscd.r +++ b/R-utils/optim.lsq.htscd.r @@ -619,7 +619,7 @@ optim.lsq.htscd <<- function( lsq.formula #---------------------------------------------------------------------------------# # Accept step only if it converged. # #---------------------------------------------------------------------------------# - success = opt.1st$convergence %==% 0 + success = opt.1st$convergence %eq% 0 #---------------------------------------------------------------------------------# }#end if ("try-error" %in% is(opt.1st)) #------------------------------------------------------------------------------------# @@ -734,7 +734,7 @@ optim.lsq.htscd <<- function( lsq.formula # solution, as the likelihood is a product of probabilities, which should be less # # than 1, hence the negative requirement. # #---------------------------------------------------------------------------------# - success = opt.hess$convergence %==% 0 + success = opt.hess$convergence %eq% 0 #---------------------------------------------------------------------------------# }#end if ("try-error" %in% is(opt.hess)) #------------------------------------------------------------------------------------# @@ -949,7 +949,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.boot$convergence %==% 0 + success = opt.boot$convergence %eq% 0 nsteps.now = opt.boot$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -1092,7 +1092,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.sxobs$convergence %==% 0 + success = opt.sxobs$convergence %eq% 0 nsteps.now = opt.sxobs$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -1232,7 +1232,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.syobs$convergence %==% 0 + success = opt.syobs$convergence %eq% 0 nsteps.now = opt.syobs$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -2389,7 +2389,7 @@ print.lsq.htscd <<- function(object){ coeff.table[,1] = sprintf("%g",signif(coeff.table[,1],5)) coeff.table[,2] = sprintf("%g",signif(coeff.table[,2],5)) coeff.table[,3] = sprintf("%g",signif(coeff.table[,3],4)) - coeff.table[,4] = ifelse( p.value %<% 1.e-16,"< 1e-16",sprintf("%g",signif(p.value,3))) + coeff.table[,4] = ifelse( p.value %lt% 1.e-16,"< 1e-16",sprintf("%g",signif(p.value,3))) #----- Append the significance test. ---------------------------------------------------# sig.brks = c(-Inf,0.001,0.01,0.05,0.1,Inf) diff --git a/R-utils/optim.pls.r b/R-utils/optim.pls.r index f8634bf5c..b11798a1d 100644 --- a/R-utils/optim.pls.r +++ b/R-utils/optim.pls.r @@ -67,7 +67,11 @@ optim.pls <<- function( formula #----- Run PLS. ------------------------------------------------------------------------# if (verbose) cat0( " > PLS (full model)") - ans = plsr(formula=form.now,data=data,verbose=verbose,...) + ans = plsr( formula = form.now + , data = data + , verbose = verbose + , ... + )#end plsr ans$orig.formula = formula ans$formula = form.now ans$yname = yname @@ -79,16 +83,18 @@ optim.pls <<- function( formula #----- Retrieve MSE in case back-transformation is sought. -----------------------------# - resnow = ans$residuals[,1,] - rsumsq = apply(X=resnow,MARGIN=2,FUN=sum2,na.rm=TRUE) - nnow = apply(X=resnow,MARGIN=2,FUN=function(x) sum(is.finite(x))) - msenow = MSEP(object=ans,"adjCV") - ans$mse = c(msenow$val[1,1,-1]) - ans$vary = if(ylog){var(log(data[yname]),na.rm=TRUE)}else{var(data[yname],na.rm=TRUE)} - ans$fve = 1 - ans$mse / ans$vary - max.fve = max(ans$fve,na.rm=TRUE) - rel.fve = ans$fve / max.fve - ans$ncomp = min(which(rel.fve >= fve.tolerance)) + msenow.t = MSEP(object=ans,"train")$val[,,] + msenow.a = MSEP(object=ans,"adjCV")$val[,,] + if (ylog){ + yvar = var(log(data[[yname]]),na.rm=TRUE) + }else{ + yvar = var(data[[yname]],na.rm=TRUE) + }#end if (ylog) + fve = 1. - msenow.a / yvar + max.fve = max(fve,na.rm=TRUE) + rel.fve = fve / max.fve + ans$ncomp = min(which(rel.fve %ge% fve.tolerance)) - 1L + ans$mse = apply(ans$residuals[,1,],MARGIN=2L,FUN=mean2) #---------------------------------------------------------------------------------------# @@ -106,7 +112,7 @@ optim.pls <<- function( formula ans$ln.pred = ypred ans$ln.sigma = sqrt(ans$mse[ans$ncomp]) ans$predicted = exp(ypred + 0.5 * ans$mse[ans$ncomp]) - ans$sigma = with(ans,sqrt(exp(mse[ncomp])-1)*exp(2.*ans$ln.pred + mse[ncomp])) + ans$sigma = with(ans,sqrt(exp(mse[ncomp])-1)*exp(2.*ln.pred + mse[ncomp])) plwr = 0.5 * (1.0 - ci.level) pupr = 0.5 * (1.0 + ci.level) ans$qlow = qlnorm(p=plwr,meanlog=ans$ln.pred,sdlog=ans$ln.sigma) @@ -139,7 +145,6 @@ optim.pls <<- function( formula dotdotdot = modifyList( x = dotdotdot , val = list( verbose = FALSE , model = FALSE - , ncomp = ans$ncomp )#end list )#end modifyList #---------------------------------------------------------------------------------------# @@ -228,6 +233,9 @@ optim.pls <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) @@ -248,8 +256,12 @@ optim.pls <<- function( formula #----- Call PLS. --------------------------------------------------------------------# - dotnow = modifyList(x=dotdotdot,val=list(data=boot.data)) - pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + dotnow = modifyList(x=dotdotdot,val=list(data=boot.data)) + pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + boot.fine = ! ("try-error" %in% is(pls.now)) + if (boot.fine){ + boot.fine = any(is.finite(pls.now$fitted.values)) + }#end if (boot.fine) #------------------------------------------------------------------------------------# @@ -257,12 +269,11 @@ optim.pls <<- function( formula #------------------------------------------------------------------------------------# # Check whether to append to the data set. # #------------------------------------------------------------------------------------# - if (! ("try-error" %in% is(pls.now))){ + if (boot.fine){ ib = ib + 1 #----- Retrieve MSE in case back-transformation is sought. -----------------------# - mse.now = MSEP(object=pls.now,"adjCV") - mse.now = c(mse.now$val[1,1,ans$ncomp+1]) + mse.now = mean2(pls.now$residuals[,1,ans$ncomp],na.rm=TRUE) #---------------------------------------------------------------------------------# @@ -288,7 +299,7 @@ optim.pls <<- function( formula #---------------------------------------------------------------------------------# }else if (verbose){ cat0(" > Bootstrap realisation failed, skip it.") - }#end if (! ("try-error" %in% is(pls.now))) + }#end if (boot.fine) #------------------------------------------------------------------------------------# }#end while (ib < n.boot) #---------------------------------------------------------------------------------------# @@ -363,17 +374,20 @@ optim.pls <<- function( formula #----- Call PLS. -----------------------------------------------------------------# dotnow = modifyList(x=dotdotdot,val=list(data=sim.data)) pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + syobs.fine = ! ("try-error" %in% is(pls.now)) + if (syobs.fine){ + syobs.fine = any(is.finite(pls.now$fitted.values)) + }#end if (boot.fine) #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# # Check whether to append to the data set. # #---------------------------------------------------------------------------------# - if (! ("try-error" %in% is(pls.now))){ + if (syobs.fine){ #----- Retrieve MSE in case back-transformation is sought. --------------------# - mse.now = MSEP(object=pls.now,"adjCV") - mse.now = c(mse.now$val[1,1,ans$ncomp+1]) + mse.now = mean2(pls.now$residuals[,1,ans$ncomp]) #------------------------------------------------------------------------------# @@ -405,7 +419,7 @@ optim.pls <<- function( formula #----- Show banner to entertain the bored user. -------------------------------# if (verbose) cat0(" > Sigma-y realisation failed, skip it.") #------------------------------------------------------------------------------# - }#end if (! ("try-error" %in% is(pls.now))) + }#end if (syobs.fine) #---------------------------------------------------------------------------------# diff --git a/R-utils/optim.randomforest.r b/R-utils/optim.randomforest.r index d73f55381..ba774f152 100644 --- a/R-utils/optim.randomforest.r +++ b/R-utils/optim.randomforest.r @@ -136,6 +136,9 @@ optim.randomForest <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) diff --git a/R-utils/optim.size.pft.bio.r b/R-utils/optim.size.pft.bio.r index 5c1865bb9..4a2d4b889 100644 --- a/R-utils/optim.size.pft.bio.r +++ b/R-utils/optim.size.pft.bio.r @@ -3,70 +3,209 @@ # This function finds the relative error of both the size structure and the basal # # area by species. # #------------------------------------------------------------------------------------------# -optim.size.pft.bio <<- function( logdbh.minus.min # Log of DBH above minimum - , obs.dbh.cnt # Frequency of each DBH class (dbh.bks) - , dbh.bks # DBH breaks for size evaluation - , dbh.table # DBH table by species - , census # Table with the full census - , datum # Table with the sought properties - , pft.var = "pft" # Variable to determine the PFT - , dbh.min = 10. # Minimum DBH - , tiny.off = 1.e-20 # Tiny offset +optim.size.pft.bio <<- function( logdbh.minus.min # Log of DBH above minimum + , obs.dbh.cnt # Frequency of each DBH class + # (dbh.cnt.bks) + , dbh.cnt.bks # DBH breaks for size + # evaluation + , dbh.table.obs # DBH table by species + , dbh.table.bks = dbh.cnt.bks # DBH breaks by species + , dbh.max = NULL # Maximum DBH by species + , bsa.summ = NULL # Basal area summary + , dbh.bsa.bks = dbh.cnt.bks # DBH breaks for basal area + , cnt.log = TRUE # Use log for count? + , bsa.log = FALSE # Use log for basal area? + , survey.area # Total surveyed area (m2) + , census # Table with the full census + , datum # Table with the sought + # properties + , pft.var = "pft" # Variable to determine the PFT + , dbh.min = 10. # Minimum DBH + , tiny.off = 1.e-7 # Tiny offset ){ #----- Revert back to DBH. -------------------------------------------------------------# dbh.now = dbh.min + exp(logdbh.minus.min) - pft.now = rownames(dbh.table) + pft.now = rownames(dbh.table.obs) #---------------------------------------------------------------------------------------# #----- Find the error due to size distribution. ----------------------------------------# - dbh.cut = cut(dbh.now,dbh.bks) - dbh.cnt = tiny.off + table(dbh.cut) - if (tiny.off == 0){ - rmse.size = ( sum((dbh.cnt/sum(dbh.cnt)-obs.dbh.cnt/sum(obs.dbh.cnt))^2) - / length(obs.dbh.cnt) ) + mod.dbh.cut = cut(dbh.now,dbh.cnt.bks) + mod.dbh.cnt = table(mod.dbh.cut) + obs.dbh.tot = sum(obs.dbh.cnt) + mod.dbh.cnt = mod.dbh.cnt / obs.dbh.tot + obs.dbh.cnt = obs.dbh.cnt / obs.dbh.tot + if (cnt.log){ + ln.obs.dbh.cnt = log(tiny.off + obs.dbh.cnt) + ln.mod.dbh.cnt = log(tiny.off + mod.dbh.cnt) + mse.size = ( sum( ( ln.obs.dbh.cnt - ln.mod.dbh.cnt )^2 ) + / length(ln.obs.dbh.cnt) ) }else{ - rmse.size = sum((log(dbh.cnt)-log(obs.dbh.cnt))^2) / length(obs.dbh.cnt) + mse.size = sum( ( mod.dbh.cnt - obs.dbh.cnt)^2 ) / length(obs.dbh.cnt) }#end if + wgt.size = length(mse.size) #---------------------------------------------------------------------------------------# + #----- Find the error due to size distribution. ----------------------------------------# - dbh.cut = cut(dbh.now,dbh.bks) - dbh.mod = tiny.off + table(census[[pft.var]],dbh.cut) - dbh.cnt = array(0,dim=dim(dbh.table),dimnames=dimnames(dbh.table)) - maponto = match(rownames(dbh.mod),rownames(dbh.cnt)) - dbh.cnt[maponto,] = dbh.mod - - use = ! is.na(dbh.table) - dbh.cnt = tiny.off + c(dbh.cnt [use]) - dbh.obs = tiny.off + c(dbh.table[use]) - - if (tiny.off == 0){ - rmse.class = ( sum((dbh.cnt/sum(dbh.cnt)-dbh.obs/sum(dbh.obs))^2) - / length(dbh.obs) ) + if (is.list(dbh.table.bks)){ + #----- Get dbh thresholds for each species. -----------------------------------------# + o = order(names(dbh.table.bks)) + dbh.table.cut = dbh.table.bks[o] + #------------------------------------------------------------------------------------# + + + #----- Get size count using species-specific thresholds. ----------------------------# + dbh.list = split(x=dbh.now,f=census[[pft.var]]) + dbh.table.tmp = t( mapply( FUN = function(dbh,dcut){ + dbh.cut = cut(dbh,dcut) + dbh.tbl = table(dbh.cut) + idx = match(names(dbh.tbl),levels(dbh.cut)) + ans = rep(0L,times=nlevels(dbh.cut)) + ans[idx] = dbh.tbl + return(ans) + }#end function + , dbh = dbh.list + , dcut = dbh.table.cut + )#end mapply + )#end t + #------------------------------------------------------------------------------------# + }else{ + #---- Get size count using global thresholds. ---------------------------------------# + dbh.table.cut = cut(dbh.now,dbh.table.bks) + dbh.table.tmp = table(census[[pft.var]],dbh.table.cut) + #------------------------------------------------------------------------------------# + }#end if (is.null(dbh.table.bks)) + #---------------------------------------------------------------------------------------# + + + + #----- Align results so it matches the reference table. --------------------------------# + dbh.table.mod = array( data = 0 + , dim = dim(dbh.table.obs) + , dimnames = dimnames(dbh.table.obs) + )#end array + idx = match(rownames(dbh.table.tmp),rownames(dbh.table.mod)) + dbh.table.mod[idx,] = dbh.table.tmp + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check for valid data, as sometimes PFT-specific distribution exists for a few # + # species only. Then normalise data for both observations and estimates # + #---------------------------------------------------------------------------------------# + dbh.table.use = ! is.na(dbh.table.obs) + dbh.table.tot = sum(dbh.table.obs[dbh.table.use]) + dbh.table.obs = dbh.table.obs[dbh.table.use] / dbh.table.tot + dbh.table.mod = dbh.table.mod[dbh.table.use] / dbh.table.tot + #---------------------------------------------------------------------------------------# + + if (cnt.log){ + ln.dbh.table.mod = log(tiny.off + dbh.table.mod) + ln.dbh.table.obs = log(tiny.off + dbh.table.obs) + mse.class = ( sum( ( ln.dbh.table.mod - ln.dbh.table.obs)^2 ) + / length(dbh.table.obs) ) }else{ - rmse.class = sum((log(dbh.cnt)-log(dbh.obs))^2) / length(dbh.obs) + mse.class = sum( (dbh.table.mod - dbh.table.obs)^2 ) / length(dbh.table.obs) }#end if + wgt.class = length(mse.class) #---------------------------------------------------------------------------------------# - #----- Find the error due to basal area by PFT. ----------------------------------------# - bsa.now = 0.25 * pi * dbh.now^2 - bsa.pft = tapply(X=bsa.now,INDEX=census[[pft.var]],FUN=sum,na.rm=TRUE) - idx = match(datum[[pft.var]],names(bsa.pft)) - rmse.bsa = sum((log(datum$bsa) - log(bsa.pft[idx]))^2) / length(datum$bsa) #---------------------------------------------------------------------------------------# + # Not every survey provides the basal area by species. In case it is missing, make a # + # dummy error and dummy length. # + #---------------------------------------------------------------------------------------# + if ("bsa" %in% names(datum)){ + + + #----- Find modelled basal area by PFT. ---------------------------------------------# + bsa.now = pio4 * dbh.now^2 / survey.area + bsa.pft.obs = datum$bsa + names(bsa.pft.obs) = datum[[pft.var]] + bsa.pft.mod = tapply(X=bsa.now,INDEX=census[[pft.var]],FUN=sum,na.rm=TRUE) + idx = match(names(bsa.pft.obs),names(bsa.pft.mod)) + bsa.pft.mod = bsa.pft.mod[idx] + #------------------------------------------------------------------------------------# + - rmse = sqrt( ( length(rmse.size ) * rmse.size^2 - + length(rmse.bsa ) * rmse.bsa^2 - + length(rmse.class) * rmse.class^2 ) - / ( length(rmse.size) + length(rmse.bsa) + length(rmse.class) ) ) + #----- Normalise basal area, taking observed total as the reference. ----------------# + bsa.pft.tot = sum(bsa.pft.obs) + bsa.pft.obs = bsa.pft.obs / bsa.pft.tot + bsa.pft.mod = bsa.pft.mod / bsa.pft.mod + #------------------------------------------------------------------------------------# + + + #----- Calculate error. -------------------------------------------------------------# + if (bsa.log){ + ln.bsa.pft.obs = log(tiny.off + bsa.pft.obs) + ln.bsa.pft.mod = log(tiny.off + bsa.pft.mod) + mse.bsa = sum( ( ln.bsa.pft.mod - ln.bsa.pft.obs )^2 ) / length(ln.bsa.pft.obs) + }else{ + mse.bsa = sum( ( bsa.pft.mod - bsa.pft.obs)^2 ) / length(bsa.pft.obs) + }#end if (bsa.log) + wgt.bsa = length(mse.bsa) + #------------------------------------------------------------------------------------# + }else{ + #----- Make dummy error. ------------------------------------------------------------# + mse.bsa = 0. + wgt.bsa = 0. + #------------------------------------------------------------------------------------# + }#end if + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case a general basal area by size class. # + #---------------------------------------------------------------------------------------# + if (is.null(bsa.summ)){ + #----- Make dummy error. ------------------------------------------------------------# + mse.bss = 0. + wgt.bss = 0. + #------------------------------------------------------------------------------------# + }else{ + #----- Find the total basal area by DBH class. --------------------------------------# + dbh.bsa.cut = cut(dbh.now,dbh.bsa.bks) + bsa.now = pio4 * dbh.now^2 / survey.area + dbh.bsa.mod = tapply(X=bsa.now,INDEX=dbh.bsa.cut,FUN=sum,na.rm=TRUE) + #------------------------------------------------------------------------------------# + + + #----- Normalise basal area distribution, using observations as reference. ----------# + dbh.bsa.tot = sum(bsa.summ) + dbh.bsa.obs = bsa.summ / dbh.bsa.tot + dbh.bsa.mod = dbh.bsa.mod / dbh.bsa.tot + #------------------------------------------------------------------------------------# + + + + #----- Find error associated with basal area size distribution. ---------------------# + if (bsa.log){ + ln.dbh.bsa.obs = log(tiny.off + dbh.bsa.obs) + ln.dbh.bsa.mod = log(tiny.off + dbh.bsa.mod) + mse.bss = ( sum( ( ln.dbh.bsa.mod - ln.dbh.bsa.obs )^2 ) + / length(ln.dbh.bsa.obs) ) + }else{ + mse.bss = sum( ( dbh.bsa.mod - dbh.bsa.obs )^2 ) / length(dbh.bsa.obs) + }#end if (bsa.log) + wgt.bss = length(mse.bss) + #------------------------------------------------------------------------------------# + }#end if (is.null(bsa.summ)) + #---------------------------------------------------------------------------------------# + + #----- Find total error. ---------------------------------------------------------------# + rmse = sqrt( ( wgt.size * mse.size + wgt.class * mse.class + + wgt.bsa * mse.bsa + wgt.bss * mse.bss ) + / ( wgt.size + wgt.class + wgt.bsa + wgt.bss ) ) + #---------------------------------------------------------------------------------------# return(rmse) }#end function diff --git a/R-utils/pcomp_varlist.r b/R-utils/pcomp_varlist.r index bbbae70fe..77c569c46 100644 --- a/R-utils/pcomp_varlist.r +++ b/R-utils/pcomp_varlist.r @@ -3443,7 +3443,7 @@ , plog = FALSE , plog.dbh = FALSE , plt = TRUE - , qf.miss = "ifelse(lai$ts %>% 0, gpp$ts/lai$ts, 0.)" + , qf.miss = "ifelse(lai$ts %gt% 0, gpp$ts/lai$ts, 0.)" , pslwr = NA_real_ , psupr = NA_real_ )#end list @@ -4171,35 +4171,35 @@ )#end list scen.xyz$yvar = scen.xyz$xvar scen.xyz$zvar = list( list( vname = "agb" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "wood.dens" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.ecue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list )#end list @@ -4578,67 +4578,67 @@ )#end list panel.xyz$yvar = panel.xyz$xvar panel.xyz$zvar = list( list( vname = "agb" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "f.bstorage" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.dcbadt" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.ecue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.etue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.gpp" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.npp" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.plresp" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.rue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.transp" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "wood.dens" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = FALSE )#end list )#end list @@ -4738,23 +4738,23 @@ )#end list panel.map$yvar = panel.map$xvar panel.map$zvar = list( list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.map = TRUE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = TRUE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.map = FALSE )#end list )#end list diff --git a/R-utils/petutils.r b/R-utils/petutils.r index 9a61ca0c3..73d553363 100644 --- a/R-utils/petutils.r +++ b/R-utils/petutils.r @@ -157,7 +157,7 @@ pet.penmon <<- function( rnet #----- Find the potential ET (kgW/m2/s). -----------------------------------------------# anom = ( eslope * (rnet - fgnd) + rhos * cpdry * vpdef / ra ) aden = splat * (eslope + psycho * (1. + rc / ra)) - ans = ifelse( test = aden %!=% 0., yes = anom / aden, no = NA_real_) + ans = ifelse( test = aden %ne% 0., yes = anom / aden, no = NA_real_) #---------------------------------------------------------------------------------------# return(ans) }#end function pet.penmon @@ -233,7 +233,7 @@ pet.prtay <<- function( rnet #----- Find the potential ET (kgW/m2/s). -----------------------------------------------# anom = alpha * eslope * ( rnet - fgnd ) aden = splat * (eslope + psycho) - ans = ifelse( test = aden %!=% 0., yes = anom / aden, no = NA_real_) + ans = ifelse( test = aden %ne% 0., yes = anom / aden, no = NA_real_) #---------------------------------------------------------------------------------------# return(ans) }#end function pet.prtay diff --git a/R-utils/pft.coms.r b/R-utils/pft.coms.r index ac246f4fd..4a3a5f152 100644 --- a/R-utils/pft.coms.r +++ b/R-utils/pft.coms.r @@ -102,7 +102,7 @@ par.twilight.min <<- 0.5 * Watts.2.Ein # Minimum non-nocturnal PAR. #----- This is a flag for the maximum representable number in R. --------------------------# -discard <<- 2^1023 +huge.num <<- 2^1023 #------------------------------------------------------------------------------------------# @@ -333,9 +333,9 @@ wdr.fs <<- 0.30 #------------------------------------------------------------------------------------------# # Define reference heights for tropical allometry. # #------------------------------------------------------------------------------------------# -# IALLOM ........ 0, 1, 2, 3, 4..............................# -hgt.ref.trop = c(NA_real_,NA_real_, 61.7,NA_real_,NA_real_)[iallom+1] -hgt.max.trop = c( 35., 35., 35., 46., 46.)[iallom+1] +# IALLOM ........ 0, 1, 2, 3, 4, 5.....................# +hgt.ref.trop = c(NA_real_,NA_real_, 61.7,NA_real_,NA_real_,NA_real_)[iallom+1] +hgt.max.trop = c( 35., 35., 35., 46., 46., 46.)[iallom+1] #------------------------------------------------------------------------------------------# @@ -366,7 +366,7 @@ hgt.max.trop = c( 35., 35., 35., 46., 46.)[iallom+1] # Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). # # # #------------------------------------------------------------------------------------------# -c14f15.bl.xx = c(0.46769540,0.6410495) # c(0.09747026,0.7587000) +c14f15.bl.xx = c(0.23384770,0.6410495) # c(0.09747026,0.7587000) c14f15.bs.tf = c(0.06080334,1.0044785) # c(0.08204475,0.9814422) c14f15.bs.sv = c(0.05602791,1.0093501) # c(0.08013971,0.9818603) c14f15.bs.gr = c(1.e-5,1.0) * c14f15.bl.xx @@ -1093,6 +1093,12 @@ pft = as.data.frame(pft,stringsAsFactors=FALSE) +#----- Create flag to identify PFTs that should use the D^2*H allometry. ------------------# +pft$ddh.allom = (iallom %in% c(3,4,5)) & pft$tropical & (! pft$liana) +#------------------------------------------------------------------------------------------# + + + #----- Adjust Vm0 based on settings and to make units consistent. -------------------------# pft$vm0 = ifelse( test = pft$pathway == 4 , yes = pft$vm0 * vmfact.c4 @@ -1521,7 +1527,7 @@ if (iallom %in% c(0,1)){ pft$b1Ht[tropical] = 0.0352 pft$b2Ht[tropical] = 0.694 #---------------------------------------------------------------------------------------# -}else if (iallom %in% c(3)){ +}else if (iallom %in% c(3,5)){ #---------------------------------------------------------------------------------------# # Allometric equation based on the fitted curve using the Sustainable Landscapes # # data set (L16) and the size- and site-dependent stratified sampling and aggregation # @@ -1595,15 +1601,15 @@ pft$hgt.show = pft$hgt.min + 0.015 * (pft$hgt.max - pft$hgt.min) pft$qsw = pft$SLA / sapwood.ratio.orig for (ipft in sequence(npft+1)){ #---- Check PFT and allometry. ---------------------------------------------------------# - if (pft$tropical[ipft] && pft$conifer[ipft] && iallom %in% c(3)){ + if (pft$tropical[ipft] && pft$conifer[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = pft$SLA[ipft] * pft$rho[ipft] / sapwood.factor["aa"] - }else if (pft$tropical[ipft] && pft$grass[ipft] && iallom %in% c(3)){ + }else if (pft$tropical[ipft] && pft$grass[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = 1.0e-5 - }else if (pft$tropical[ipft] && iallom %in% c(3)){ + }else if (pft$tropical[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = pft$SLA[ipft] * pft$rho[ipft] / sapwood.factor["bl"] }else{ pft$qsw[ipft] = pft$SLA[ipft] / sapwood.ratio.orig - }#end if (pft$tropical[ipft] && is.finite(pft$rho[ipft]) && iallom %in% c(3,4)) + }#end if (pft$tropical[ipft] && is.finite(pft$rho[ipft]) && iallom %in% c(3,5)) #---------------------------------------------------------------------------------------# }#end for (ipft in sequence(npft)) #------------------------------------------------------------------------------------------# @@ -1717,7 +1723,9 @@ pft$b1Xs = 0.315769481 pft$b1Xb = 0. pft$qbark = 0. for (ipft in sequence(npft+1)){ - skip = pft$grass[ipft] || pft$liana[ipft] || (! pft$tropical[ipft]) || ( iallom != 3 ) + skip = ( pft$grass[ipft] || pft$liana[ipft] || (! pft$tropical[ipft]) + || ( ! (iallom %in% c(3,5) ) ) + )#end skip if (! skip){ #------------------------------------------------------------------------------------# # Variable b1Xs is the ratio between sapwood thickness and DBH. It is currently # @@ -1763,7 +1771,7 @@ pft$dbh.min = rep(NA,times=npft+1) pft$dbh.crit = rep(NA,times=npft+1) for (ipft in sequence(npft+1)){ if (pft$tropical[ipft]){ - if (iallom %in% c(0,1,3,4)){ + if (iallom %in% c(0,1,3,4,5)){ pft$dbh.min [ipft] = exp((log(pft$hgt.min[ipft])-pft$b1Ht[ipft])/pft$b2Ht[ipft]) pft$dbh.crit [ipft] = exp((log(pft$hgt.max[ipft])-pft$b1Ht[ipft])/pft$b2Ht[ipft]) }else if (iallom %in% c(2)){ @@ -1842,7 +1850,7 @@ for (ipft in sequence(npft+1)){ pft$b2Bs.small[ipft] = ndead.small[2] pft$b1Bs.large[ipft] = C2B * exp(ndead.large[1]) * pft$rho[ipft] / ndead.large[3] pft$b2Bs.large[ipft] = ndead.large[2] - }else if (iallom %in% c(3,4)){ + }else if (iallom %in% c(3,4,5)){ if (pft$grass[ipft]){ c14f15.bs.xx = c14f15.bs.gr }else if (pft$savannah[ipft]){ @@ -1871,7 +1879,7 @@ for (ipft in sequence(npft+1)){ }else if (iallom %in% c(2)){ pft$b1Ca[ipft] = exp(ncrown.area[1]) pft$b2Ca[ipft] = ncrown.area[2] - }else if (iallom %in% c(3,4)){ + }else if (iallom %in% c(3,4,5)){ #---------------------------------------------------------------------------------# # Allometry using the Sustainable Landscapes data. # #---------------------------------------------------------------------------------# @@ -1918,7 +1926,7 @@ for (ipft in sequence(npft+1)){ # R2 = 0.673 # # RMSE = 2.29 # #------------------------------------------------------------------------------------# - if (iallom %in% c(3,4) && (! pft$grass[ipft])){ + if (iallom %in% c(3,4,5) && (! pft$grass[ipft])){ pft$b1Cl[ipft] = 0.29754 pft$b2Cl[ipft] = 1.0324 }#end if @@ -1943,10 +1951,10 @@ for (ipft in sequence(npft+1)){ }else if(iallom %in% c(2)){ pft$b1Bl[ipft] = C2B * exp(nleaf[1]) * pft$rho[ipft] / nleaf[3] pft$b2Bl[ipft] = nleaf[2] - }else if(iallom %in% c(3)){ + }else if(iallom %in% c(3,5)){ #---------------------------------------------------------------------------------# # Leaf allometry, use the individual leaf area allometry derived from the BAAD # - # data base (F15), scaled by the specific leaf area. # + # data base (F15), scaled by the specific leaf area, and described in L20. # # # # Reference: # # # @@ -1955,8 +1963,15 @@ for (ipft in sequence(npft+1)){ # database for woody plants. Ecology, 96 (5):1445-1445. # # doi:10.1890/14-1889.1 (F15). # # # + # Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, # + # Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, # + # energy, and carbon cycling of the Amazon tropical forests. # + # J. Geophys. Res.-Biogeosci., 125: e2020JG005677. # + # doi:10.1029/2020JG005677 (L20). # + # # #---------------------------------------------------------------------------------# - pft$b1Bl[ipft] = c14f15.bl.xx[1] / pft$SLA[ipft] + # pft$b1Bl[ipft] = C2B * c14f15.bl.xx[1] / pft$SLA[ipft] + pft$b1Bl[ipft] = c14f15.bl.xx[1] pft$b2Bl[ipft] = c14f15.bl.xx[2] #---------------------------------------------------------------------------------# }else{ @@ -2108,9 +2123,9 @@ if (iallom %in% c(0)){ , no = 0.4223014 )#end ifelse #---------------------------------------------------------------------------------------# -}else if (iallom %in% c(3)){ +}else if (iallom %in% c(4,5)){ #----- Test allometry based on excavation data in Panama, using height as predictor. ---# - pft$b1Rd [sequence(npft+1)] = -0.609 + pft$b1Rd [sequence(npft+1)] = -0.609 * 2 pft$b2Rd [sequence(npft+1)] = 0.580 #---------------------------------------------------------------------------------------# }#end if @@ -2125,34 +2140,34 @@ if (iallom %in% c(0)){ # BDead -> DBH parameters. These are calculated a posteriori because they are just # # the inverse of size->BDead allometry. # #------------------------------------------------------------------------------------------# -pft$d2DBH.small = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d2DBH.small = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bs.small ) , no = 1. / pft$b2Bs.small )#end ifelse -pft$d1DBH.small = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d1DBH.small = ifelse( test = pft$ddh.allom , yes = ( C2B / ( pft$b1Bs.small * exp(pft$b1Ht*pft$b2Bs.small) ) ) ^ pft$d2DBH.small , no = ( C2B / pft$b1Bs.small ) ^ pft$d2DBH.small )#end ifelse -pft$d2DBH.large = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d2DBH.large = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bs.large ) , no = 1. / pft$b2Bs.large )#end ifelse -pft$d1DBH.large = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d1DBH.large = ifelse( test = pft$ddh.allom , yes = ( C2B / ( pft$b1Bs.large * exp(pft$b1Ht*pft$b2Bs.large) ) ) ^ pft$d2DBH.large , no = ( C2B / pft$b1Bs.large ) ^ pft$d2DBH.large )#end ifelse -pft$l2DBH = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$l2DBH = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bl ) , no = 1. / pft$b2Bl )#end ifelse -pft$l1DBH = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) - , yes = ( C2B / ( pft$b1Bl * exp(pft$b1Ht*pft$b2Bl) ) ) +pft$l1DBH = ifelse( test = pft$ddh.allom + , yes = ( 1. / ( pft$b1Bl * exp(pft$b1Ht*pft$b2Bl) ) ) ^ pft$l2DBH , no = ( C2B / pft$b1Bl ) ^ pft$l2DBH )#end ifelse -pft$bdead.crit = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$bdead.crit = ifelse( test = pft$ddh.allom , yes = pft$b1Bs.small / C2B * ( pft$dbh.crit * pft$dbh.crit * pft$hgt.max) ^ pft$b2Bs.small @@ -2214,8 +2229,7 @@ pft$b2Efrd = rep(x=0.1822,times=npft+1) #------------------------------------------------------------------------------------------# pft$b1WAI = ifelse( test = pft$grass , yes = 0.0 - , no = ifelse( test = pft$tropical & (! pft$liana) - & (iallom %in% c(3,4)) + , no = ifelse( test = pft$ddh.allom , yes = ifelse( test = pft$conifer , yes = 0.01148449 , no = 0.00378399 @@ -2228,8 +2242,7 @@ pft$b1WAI = ifelse( test = pft$grass )#end ifelse pft$b2WAI = ifelse( test = pft$grass , yes = 0.0 - , no = ifelse( test = pft$tropical & (! pft$liana) - & (iallom %in% c(3,4)) + , no = ifelse( test = pft$ddh.allom , yes = ifelse( test = pft$conifer , yes = 0.77075160 , no = 0.81667933 @@ -2352,6 +2365,12 @@ pft$kplastic.ltor = -1 * with(pft,kplastic.vm0*eplastic.vm0+kplastic.sla*eplasti +#------ Fire survivorship parameters for when using the old models. -----------------------# +pft$fire.s.efac = -0.12 +pft$fire.s.max = ifelse(test = pft$grass,yes = 0.1, no = 0.9) +#------------------------------------------------------------------------------------------# + + #----- Make it global. --------------------------------------------------------------------# pft <<- pft #------------------------------------------------------------------------------------------# diff --git a/R-utils/plot.rgb.r b/R-utils/plot.rgb.r index 52bdf3804..51e184f80 100644 --- a/R-utils/plot.rgb.r +++ b/R-utils/plot.rgb.r @@ -271,8 +271,8 @@ plot.rgb <<- function( x green.l = seq(from=0,to=1-red.span[n],by=0.5*delta) blue.l = seq(from=0,to=1-red.span[n],by=0.5*delta) rgb.l = expand.grid(red=red.span[n],green=green.l,blue=blue.l) - keep = ( rowSums(rgb.l) %>=% (1-sqrt(.Machine$double.eps)) - & rowSums(rgb.l) %<=% (1+sqrt(.Machine$double.eps)) ) + keep = ( rowSums(rgb.l) %ge% (1-sqrt(.Machine$double.eps)) + & rowSums(rgb.l) %le% (1+sqrt(.Machine$double.eps)) ) rgb.l = rgb.l[keep,] / rowSums(rgb.l[keep,]) #---------------------------------------------------------------------------------# diff --git a/R-utils/plotutils.r b/R-utils/plotutils.r index 9144630d9..5fd56c5d3 100644 --- a/R-utils/plotutils.r +++ b/R-utils/plotutils.r @@ -24,7 +24,7 @@ open.plot <<- function( fichier #----- Fichier must be provided unless we are plotting on screen. ----------------------# - if (missing(fichier) && (! outform %in% c("x11","quartz","windows"))){ + if (missing(fichier) && (! outform %in% c("x11","quartz","windows","default"))){ stop("Output file (\"fichier\") must be provided when plotting on file!") }#end if (missing(fichier) && (! outform %in% c("x11","quartz","windows"))) #---------------------------------------------------------------------------------------# @@ -77,7 +77,7 @@ open.plot <<- function( fichier , paper = size$paper , ... )#end postscript - }else if (outform[o] %in% "pdf"){ + }else if (outform %in% "pdf"){ pdf ( file = fichier , onefile = FALSE , width = size$width @@ -85,6 +85,9 @@ open.plot <<- function( fichier , pointsize = ptsz , paper = size$paper )#end pdf + }else if (outform %in% "default"){ + # Don't open any device, let the script open at the default location. + dev.new() }#end if #---------------------------------------------------------------------------------------# @@ -111,12 +114,11 @@ close.plot <<- function( outform = switch( EXPR = get.os() if (outform %in% c("x11","quartz","windows")){ locator(n=n) dev.off() + }else if (outform %in% "default"){ }else{ dev.off() }#end if dummy = clean.tmp() - - invisible() }#end close.plot #==========================================================================================# diff --git a/R-utils/pmonthly_varlist.r b/R-utils/pmonthly_varlist.r index 746b3275f..2f42736b5 100644 --- a/R-utils/pmonthly_varlist.r +++ b/R-utils/pmonthly_varlist.r @@ -422,6 +422,32 @@ tspftdbh[[n]] = list( vnam = "leaf.gsw" , scsout = TRUE )#end list n = n + 1 +tspftdbh[[n]] = list( vnam = "dmin.leaf.psi" + , desc = "Midday leaf water potential" + , e.unit = untab$mpa + , i.unit = untab$mpa + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 +tspftdbh[[n]] = list( vnam = "dmax.leaf.psi" + , desc = "Pre-dawn leaf water potential" + , e.unit = untab$mpa + , i.unit = untab$mpa + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 tspftdbh[[n]] = list( vnam = "leaf.gbw" , desc = "Leaf boundary layer conductance" , e.unit = untab$kgwom2loday @@ -542,6 +568,19 @@ tspftdbh[[n]] = list( vnam = "dimort" , scsout = TRUE )#end list n = n + 1 +tspftdbh[[n]] = list( vnam = "fire.lethal" + , desc = "Fire lethality rate" + , e.unit = untab$pcpopoyr + , i.unit = untab$pcpopoyr + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 tspftdbh[[n]] = list( vnam = "recr" , desc = "Recruitment rate" , e.unit = untab$pcpopoyr @@ -1447,7 +1486,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gpp" , desc = "Gross Primary productivity" , unit = untab$kgcom2oyr - , col.scheme = "atlas" + , col.scheme = "brbg" , fco.mmean = TRUE , fco.qmean = FALSE , box.plot = FALSE @@ -1456,7 +1495,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "npp" , desc = "Net Primary productivity" , unit = untab$kgcom2oyr - , col.scheme = "atlas" + , col.scheme = "brbg" , fco.mmean = TRUE , fco.qmean = FALSE , box.plot = FALSE @@ -1465,7 +1504,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1474,7 +1513,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "het.resp" , desc = "Heterotrophic respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1483,7 +1522,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "fgc.resp" , desc = "Surface litter respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1492,7 +1531,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "fsc.resp" , desc = "Sub-surface litter respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1501,7 +1540,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "stgc.resp" , desc = "Surface woody debris respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1510,7 +1549,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "stsc.resp" , desc = "Sub-surface woody debris respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1519,7 +1558,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "msc.resp" , desc = "Microbial soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1528,7 +1567,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "ssc.resp" , desc = "Humified soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1537,7 +1576,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "psc.resp" , desc = "Passive soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1582,7 +1621,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "nep" , desc = "Net ecosystem production" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1591,7 +1630,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1600,7 +1639,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = untab$wom2 - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1609,7 +1648,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxca" , desc = "Water flux" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1618,7 +1657,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxgc" , desc = "Ground evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1627,7 +1666,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxlc" , desc = "Leaf evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1636,7 +1675,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxwc" , desc = "Wood evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1645,7 +1684,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "evap" , desc = "Evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1654,7 +1693,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "transp" , desc = "Transpiration" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1663,7 +1702,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "nee" , desc = "Net ecosystem exchange" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1672,7 +1711,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "cflxca" , desc = "CO2 flux" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1681,7 +1720,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "cflxst" , desc = "CO2 flux" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1690,7 +1729,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.temp" , desc = "Canopy air temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1699,7 +1738,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.temp" , desc = "Atmospheric temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1708,7 +1747,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.temp" , desc = "Leaf temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1717,7 +1756,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wood.temp" , desc = "Wood temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1726,7 +1765,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gnd.temp" , desc = "Ground temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1735,7 +1774,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.shv" , desc = "Atmospheric specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1744,7 +1783,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.shv" , desc = "Canopy air specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1753,7 +1792,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gnd.shv" , desc = "Ground specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1762,7 +1801,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.co2" , desc = "Atmospheric CO2 mixing ratio" , unit = untab$molcomol - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1771,7 +1810,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.co2" , desc = "Canopy air CO2 mixing ratio" , unit = untab$molcomol - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1780,7 +1819,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rain" , desc = "Total monthly precipitation" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1789,7 +1828,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "runoff" , desc = "Total monthly runoff" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1798,7 +1837,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "intercepted" , desc = "Total monthly interception" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1807,7 +1846,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wshed" , desc = "Total monthly dripping" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1816,7 +1855,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "sm.stress" , desc = "Fraction of open stomata" , unit = untab$empty - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1825,7 +1864,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.gbw" , desc = "Leaf boundary layer conductance" , unit = untab$kgwom2loday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1834,7 +1873,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = untab$kgwom2loday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1843,7 +1882,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshort" , desc = "Downward shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1852,7 +1891,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshort.gnd" , desc = "Abs. gnd. shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1861,7 +1900,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshortup" , desc = "Outgoing shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1870,7 +1909,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlong" , desc = "Downward longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1879,7 +1918,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlong.gnd" , desc = "Abs. gnd. longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1888,7 +1927,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlongup" , desc = "Outgoing longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1897,7 +1936,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "albedo" , desc = "Shortwave albedo" , unit = untab$empty - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1906,7 +1945,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "ustar" , desc = "Friction velocity" , unit = untab$mos - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1915,7 +1954,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "paw" , desc = "Potential available water" , unit = untab$pcsat - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1924,7 +1963,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "smpot" , desc = "Integrated matric potential" , unit = untab$mpa - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1944,8 +1983,8 @@ theme[[n]] = list( vnam = c( "gpp", "plant.resp", "het.resp", , "npp", "nep") , desc = c( "GPP","Plant resp.","Het. resp.","Ecos. Resp." , "NPP", "NEP") - , colour = c( "darkgreen", "gold", "purple3", "orangered" - ,"chartreuse3","dodgerblue3") + , colour = c( "#009E73", "#F0E442", "#332288", "#882255" + , "#56B4E9", "#0072B2") , lwd = c( 2.5, 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -1958,6 +1997,7 @@ theme[[n]] = list( vnam = c( "gpp", "plant.resp", "het.resp", , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -1968,8 +2008,8 @@ theme[[n]] = list( vnam = c( "rshort", "rlong","rshort.gnd", "qwf , "hflxca") , desc = c( "Down SW", "Down LW", "Abs. Grnd", "'Latent'" , "Sensible") - , colour = c("goldenrod","chartreuse4", "purple4","dodgerblue3" - ,"firebrick") + , colour = c( "#E69F00", "#56B4E9", "#332288", "#0072B2" + , "#882255") , lwd = c( 2.5, 2.5, 2.5, 2.5 ,2.5) , type = "o" @@ -1982,6 +2022,7 @@ theme[[n]] = list( vnam = c( "rshort", "rlong","rshort.gnd", "qwf , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -1992,8 +2033,8 @@ theme[[n]] = list( vnam = c( "wflxgc", "wflxca", "wfl , "wflxwc", "transp") , desc = c("Ground->Canopy", "Canopy->Atm", "Leaf->Canopy" , "Wood->Canopy", "Transpiration") - , colour = c( "#3B24B3", "#2996CC", "#A3CC52" - , "#990F0F", "#306614") + , colour = c( "#332288", "#0072B2", "#56B4E9" + , "#882255", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2006,8 +2047,9 @@ theme[[n]] = list( vnam = c( "wflxgc", "wflxca", "wfl , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) - , mmean.lim = c(0,5.0) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list @@ -2016,8 +2058,8 @@ theme[[n]] = list( vnam = c( "hflxgc", "hflxca", "hfl , "hflxwc") , desc = c("Ground->Canopy", "Canopy->Atm", "Leaf->Canopy" , "Wood->Canopy") - , colour = c( "#3B24B3", "#2996CC", "#A3CC52" - , "#990F0F") + , colour = c( "#332288", "#0072B2", "#56B4E9" + , "#882255", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5) , type = "o" @@ -2030,6 +2072,7 @@ theme[[n]] = list( vnam = c( "hflxgc", "hflxca", "hfl , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2040,8 +2083,8 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" , "wood.temp", "gnd.temp") , desc = c( "Atmosphere","Canopy air", "Leaf" , "Wood", "Ground") - , colour = c( "deepskyblue", "grey45","chartreuse4" - ,"darkgoldenrod", "orangered") + , colour = c( "#56B4E9", "grey45", "#009E73" + , "#882255", "#332288") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2054,6 +2097,7 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2062,7 +2106,7 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" n = n + 1 theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") , desc = c( "Atmosphere","Canopy air", "Ground") - , colour = c("deepskyblue", "slateblue","darkgoldenrod") + , colour = c( "#56B4E9", "#0072B2", "#332288") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2074,6 +2118,7 @@ theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2082,7 +2127,7 @@ theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") n = n + 1 theme[[n]] = list( vnam = c( "atm.co2", "can.co2") , desc = c( "Atmosphere", "Canopy air") - , colour = c("deepskyblue", "slateblue") + , colour = c( "#56B4E9", "#0072B2") , lwd = c(2.5,2.5) , type = "o" , plog = FALSE @@ -2094,6 +2139,7 @@ theme[[n]] = list( vnam = c( "atm.co2", "can.co2") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2102,7 +2148,7 @@ theme[[n]] = list( vnam = c( "atm.co2", "can.co2") n = n + 1 theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", "wshed") , desc = c("Precipitation","Total runoff","Interception","Dripping") - , colour = c( "royalblue4", "orangered", "chartreuse4", "purple2") + , colour = c( "#0072B2", "#E69F00", "#009E73", "#332288") , lwd = c( 2.5, 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2114,6 +2160,7 @@ theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2122,7 +2169,7 @@ theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", n = n + 1 theme[[n]] = list( vnam = c("npat.global") , desc = c("Patch count") - , colour = c( "orangered") + , colour = c( "#D55E00") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2134,6 +2181,7 @@ theme[[n]] = list( vnam = c("npat.global") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2142,7 +2190,7 @@ theme[[n]] = list( vnam = c("npat.global") n = n + 1 theme[[n]] = list( vnam = c( "ncoh.global") , desc = c("Cohort count") - , colour = c( "chartreuse4") + , colour = c( "#009E73") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2154,6 +2202,7 @@ theme[[n]] = list( vnam = c( "ncoh.global") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2162,7 +2211,7 @@ theme[[n]] = list( vnam = c( "ncoh.global") n = n + 1 theme[[n]] = list( vnam = c( "workload", "specwork") , desc = c("RK4 steps (Total)","Avg. RK4 steps per patch") - , colour = c( "purple3", "chartreuse2") + , colour = c( "#56B4E9", "#009E73") , lwd = c( 2.5, 2.5) , type = "o" , plog = TRUE @@ -2174,6 +2223,7 @@ theme[[n]] = list( vnam = c( "workload", "specwork") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2182,7 +2232,7 @@ theme[[n]] = list( vnam = c( "workload", "specwork") n = n + 1 theme[[n]] = list( vnam = c( "rk4step") , desc = c("Thermodynamic time step") - , colour = c( "deepskyblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = TRUE @@ -2194,20 +2244,17 @@ theme[[n]] = list( vnam = c( "rk4step") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "plant.resp", "leaf.resp", "stem.resp" - , "root.resp") - , desc = c( "Autotrophic", "Leaf", "Stem" - , "Root") - , colour = c( "#143305", "#A3CC52", "#E65C17" - , "#990F0F") - , lwd = c( 2.5, 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "root.resp", "stem.resp", "leaf.resp") + , desc = c( "Root", "Stem", "Leaf") + , colour = c( "#332288", "#E69F00", "#009E73") + , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE , prefix = "pltissueresp" @@ -2218,20 +2265,17 @@ theme[[n]] = list( vnam = c( "plant.resp", "leaf.resp", "stem.re , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) - , mmean.lim = c(0.,4.5) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) - , ymean.lim = c(0.,4.5) + , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "plant.resp", "aerobic.resp", "growth.resp" - , "storage.resp") - , desc = c( "Autotrophic", "Aerobic", "Growth" - , "Storage") - , colour = c( "#143305", "#2996CC", "#3B24B3" - , "#B49ED2") - , lwd = c( 2.5, 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "aerobic.resp", "growth.resp", "storage.resp") + , desc = c( "Aerobic", "Growth", "Storage") + , colour = c( "#0072B2", "#E69F00", "#785EF0") + , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE , prefix = "plprocresp" @@ -2242,24 +2286,25 @@ theme[[n]] = list( vnam = c( "plant.resp", "aerobic.resp", "growth.re , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(0.,4.5) , qmean.lim = c(NA,NA) , ymean.lim = c(0.,4.5) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "het.resp", "fgc.resp", "fsc.resp" - , "stgc.resp", "stsc.resp", "msc.resp" - , "ssc.resp", "psc.resp") - , desc = c( "Heterotrophic", "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris", "Microbial" - , "Humified soil", "Passive soil") - , colour = c( "#143305", "#A3CC52", "#E65C17" - , "#990F0F", "#3B24B3", "#2996CC" - , "#B49ED2", "#F1BD3B") +theme[[n]] = list( vnam = c( "psc.resp", "ssc.resp", "stsc.resp" + , "msc.resp", "fsc.resp", "stgc.resp" + , "fgc.resp") + , desc = c( "Passive soil", "Humified soil","BG Woody Debris" + , "Microbial", "BG Litter","AG Woody Debris" + , "AG Litter") + , colour = c( "#811F9E", "#1BA2F7", "#880D32" + , "#CCCA3D", "#107C92", "#F87856" + , "#2BD2DB") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5, 2.5 - , 2.5, 2.5) + , 2.5) , type = "o" , plog = FALSE , prefix = "hetresp" @@ -2270,18 +2315,19 @@ theme[[n]] = list( vnam = c( "het.resp", "fgc.resp", "fsc , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) - , mmean.lim = c(0.,4.5) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) - , ymean.lim = c(0.,4.5) + , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" - , "stgc.in", "stsc.in") - , desc = c( "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris") - , colour = c( "#A3CC52", "#E65C17" - , "#990F0F", "#3B24B3") +theme[[n]] = list( vnam = c( "stsc.in", "fsc.in" + , "stgc.in", "fgc.in") + , desc = c("BG Woody Debris", "BG Litter" + ,"AG Woody Debris", "AG Litter") + , colour = c( "#880D32", "#107C92" + , "#F87856", "#2BD2DB") , lwd = c( 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2294,6 +2340,7 @@ theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2302,7 +2349,7 @@ theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" n = n + 1 theme[[n]] = list( vnam = c( "atm.vels", "ustar") , desc = c("Wind speed","Friction velocity") - , colour = c("deepskyblue", "slateblue") + , colour = c( "#56B4E9", "#332288") , lwd = c( 2.5, 2.5) , type = "o" , plog = FALSE @@ -2314,28 +2361,25 @@ theme[[n]] = list( vnam = c( "atm.vels", "ustar") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "fast.grnd.c", "fast.soil.c" - , "struct.grnd.c", "struct.soil.c" - , "microbe.soil.c", "slow.soil.c" - , "passive.soil.c") - , desc = c( "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris" - , "Microbial", "Humified" - , "Passive") - , colour = c( "#A3CC52", "#1E4C08" - , "#E65C17", "#990F0F" - , "#2996CC", "#3B24B3" - , "#F1BD3B") - , lwd = c( 2.5, 2.5 - , 2.5, 2.5 - , 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "passive.soil.c", "slow.soil.c", "microbe.soil.c" + , "struct.soil.c", "fast.soil.c", "struct.grnd.c" + , "fast.grnd.c") + , desc = c( "Passive", "Humified", "Microbial" + ,"BG Woody Debris", "BG Litter","AG Woody Debris" + , "AG Litter") + , colour = c( "#811F9E", "#1BA2F7", "#880D32" + , "#CCCA3D", "#107C92", "#F87856" + , "#2BD2DB") + , lwd = c( 2.5, 2.5, 2.5 + , 2.5, 2.5, 2.5 + , 2.5) , type = "o" , plog = FALSE , prefix = "soil_carbon" @@ -2346,6 +2390,7 @@ theme[[n]] = list( vnam = c( "fast.grnd.c", "fast.soil.c" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2356,8 +2401,8 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" , "logging.harvest", "combusted.fuel") , desc = c( "Crop (Seeds)", "Crop (Other)" , "Logging Harvest","Combusted Biomass") - , colour = c( "chartreuse3", "dodgerblue3" - , "orangered", "firebrick") + , colour = c( "#009E73", "#0072B2" + , "#E69F00", "#882255") , lwd = c( 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2370,6 +2415,7 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2378,7 +2424,7 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" n = n + 1 theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") , desc = c( "Atmosphere", "Canopy air", "Leaf") - , colour = c("deepskyblue","dodgerblue4","chartreuse3") + , colour = c( "#56B4E9", "#0072B2", "#009E73") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2390,6 +2436,7 @@ theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2398,7 +2445,7 @@ theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") n = n + 1 theme[[n]] = list( vnam = c( "paw") , desc = c("Pot.Av.Water") - , colour = c( "steelblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2410,6 +2457,7 @@ theme[[n]] = list( vnam = c( "paw") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2418,7 +2466,7 @@ theme[[n]] = list( vnam = c( "paw") n = n + 1 theme[[n]] = list( vnam = c( "smpot") , desc = c("Neg. Potential") - , colour = c( "royalblue4") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2430,6 +2478,7 @@ theme[[n]] = list( vnam = c( "smpot") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2438,7 +2487,7 @@ theme[[n]] = list( vnam = c( "smpot") n = n + 1 theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") , desc = c( "ED-2.2","Malhi et al. (2009)") - , colour = c( "orangered", "gold") + , colour = c( "#882255", "#E69F00") , lwd = c( 2.5, 2.5) , type = "o" , plog = FALSE @@ -2450,6 +2499,7 @@ theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2458,7 +2508,7 @@ theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") n = n + 1 theme[[n]] = list( vnam = c( "nee", "cflxca", "cflxst") , desc = c( "NEE", "CO2 Flux","CO2 Storage") - , colour = c("chartreuse4","steelblue", "orangered") + , colour = c( "#009E73", "#56B4E9", "#E69F00") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2470,6 +2520,7 @@ theme[[n]] = list( vnam = c( "nee", "cflxca", "cflxst") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2480,8 +2531,8 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" , "rshort.gnd", "rshortup") , desc = c("Down Top canopy", "Beam", "Diffuse" , "Abs. Ground","Up Top canopy") - , colour = c( "deepskyblue","darkgoldenrod", "grey45" - , "firebrick", "royalblue3") + , colour = c( "#56B4E9", "#E69F00", "grey45" + , "#882255", "#0072B2") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2494,6 +2545,7 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2502,7 +2554,7 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" n = n + 1 theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") , desc = c("Down Top canopy","Upward LW", "Abs. Ground") - , colour = c( "deepskyblue","orangered","darkgoldenrod") + , colour = c( "#56B4E9", "#E69F00", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2514,6 +2566,7 @@ theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2522,7 +2575,7 @@ theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") n = n + 1 theme[[n]] = list( vnam = c( "albedo", "albedo.par","albedo.nir") , desc = c("SW Albedo (Net)", "PAR Albedo","NIR Albedo") - , colour = c( "deepskyblue","chartreuse3", "orangered") + , colour = c( "#56B4E9", "#009E73", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2534,6 +2587,7 @@ theme[[n]] = list( vnam = c( "albedo", "albedo.par","albedo.nir") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2544,8 +2598,8 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" , "par.gnd", "parup") , desc = c("Down Top canopy", "Beam", "Diffuse" , "Abs. Ground","Up Top canopy") - , colour = c( "deepskyblue", "firebrick","slateblue" - , "darkgoldenrod", "chartreuse3") + , colour = c( "#56B4E9", "#882255", "#332288" + , "#E69F00", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2558,6 +2612,7 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2566,7 +2621,7 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" n = n + 1 theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "wood.gbw") , desc = c( "Leaf (Stomata)","Leaf (Bnd. Lyr.)","Wood (Bnd. Lyr.)") - , colour = c( "chartreuse4", "steelblue", "sienna") + , colour = c( "#009E73", "#56B4E9", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2578,6 +2633,7 @@ theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "w , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2586,7 +2642,7 @@ theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "w n = n + 1 theme[[n]] = list( vnam = c( "vm0") , desc = c( "Max. Carboxylation") - , colour = c( "dodgerblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2596,8 +2652,9 @@ theme[[n]] = list( vnam = c( "vm0") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2606,7 +2663,7 @@ theme[[n]] = list( vnam = c( "vm0") n = n + 1 theme[[n]] = list( vnam = c( "sla") , desc = c( "Specific leaf area") - , colour = c( "forestgreen") + , colour = c( "#009E73") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2616,8 +2673,9 @@ theme[[n]] = list( vnam = c( "sla") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2626,7 +2684,7 @@ theme[[n]] = list( vnam = c( "sla") n = n + 1 theme[[n]] = list( vnam = c( "llspan") , desc = c( "Leaf longevity") - , colour = c( "purple2") + , colour = c( "#332288") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2636,8 +2694,9 @@ theme[[n]] = list( vnam = c( "llspan") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2650,9 +2709,9 @@ theme[[n]] = list( vnam = c( "veg.height", "can.depth" , desc = c( "Vegetation height", "Canopy depth" , "Displacement height","Vegetation Roughness" , "Net roughness") - , colour = c( "deepskyblue", "firebrick" - , "slateblue", "darkgoldenrod" - , "chartreuse3") + , colour = c( "#56B4E9", "#882255" + , "#332288", "#E69F00" + , "#009E73") , lwd = c(2.5,2.5,2.5,2.5,2.5) , type = "o" , plog = FALSE @@ -2664,6 +2723,157 @@ theme[[n]] = list( vnam = c( "veg.height", "can.depth" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.intensity") + , desc = c( "Fire intensity") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.intensity" + , title = "Fire intensity" + , unit = untab$kwom + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.density") + , desc = c("Fire count density") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.density" + , title = "Fire count density" + , unit = untab$oneokm2 + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.ignition") + , desc = c( "Fire ignition") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.ignition" + , title = "Fire ignition rate" + , unit = untab$oneokm2omo + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c("fire.extinction") + , desc = c("Fire extinction") + , colour = c( "#0072B2") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.extinction" + , title = "Fire extinction rate" + , unit = untab$pcoday + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.spread") + , desc = c( "Fire spread") + , colour = c( "#332288") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.spread" + , title = "Fire spread rate" + , unit = untab$momin + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.f.bherb", "fire.f.bwoody" + , "fire.f.fgc", "fire.f.stgc") + , desc = c( "Herbaceous", "Woody (live)" + , "Fine litter","Structural litter") + , colour = c( "#009E73", "#E69F00" + , "#56B4E9", "#332288") + , lwd = c(2.5,2.5,2.5,2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.consumption" + , title = "Relative fuel consumption" + , unit = untab$pc + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "burnt.area") + , desc = c( "Burnt area") + , colour = c( "#D55E00") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "burnt.area" + , title = "Burnt area" + , unit = untab$pc + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -3220,7 +3430,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.water" , desc = "Soil moisture" , unit = untab$m3wom3 - , csch = "ipanoply" + , csch = "rdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE @@ -3231,7 +3441,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.temp" , desc = "Soil temperature" , unit = untab$degC - , csch = "panoply" + , csch = "irdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE @@ -3242,7 +3452,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.mstpot" , desc = "(Negative) Soil moisture potential" , unit = untab$mpa - , csch = "panoply" + , csch = "irdbu" , pnlog = TRUE , mmean = TRUE , emean = TRUE @@ -3253,7 +3463,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.extracted" , desc = "Water extraction by plants" , unit = untab$kgwom3oday - , csch = "ipanoply" + , csch = "rdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE diff --git a/R-utils/polar.periodogram.r b/R-utils/polar.periodogram.r index 5e9494d6b..69f8efae3 100644 --- a/R-utils/polar.periodogram.r +++ b/R-utils/polar.periodogram.r @@ -55,7 +55,7 @@ polar.periodogram <<- function( X nn = ncol (X) FF = fft(Xp) / mm / nn II = abs(FF) * abs(FF) * mm * nn - sig2 = var(c(X)) + sig2 = var(c(Xp),na.rm=TRUE) #---------------------------------------------------------------------------------------# @@ -113,25 +113,28 @@ polar.periodogram <<- function( X #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Find the variance of the retained spectrum. # + #---------------------------------------------------------------------------------------# + sig2p = sum(II.keep) + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Decide how to aggregate data. # #---------------------------------------------------------------------------------------# if (which.bin %in% "radius"){ m.II = tapply(X=II.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=R.cut,FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% c("theta","angle")){ m.II = tapply(X=II.keep,INDEX=TH.cut,FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=TH.cut,FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% "both"){ m.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% "length"){ - m.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + m.II = tapply(X=II.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) + ans = m.II / sig2p len = tapply(X=LL.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) names(ans) = len }else if (which.bin %in% "none"){ @@ -148,3 +151,58 @@ polar.periodogram <<- function( X }#end polar.periodogram #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# This function is a wrapper for the FOTO package, when using matrices as opposed to # +# rasters. It internally creates a raster that is then sent to the package function. This # +# copies part of the steps in the function "foto" because the package by default applies # +# the principal component analysis and this is done separately. # +#------------------------------------------------------------------------------------------# +foto.periodogram <<- function(X){ + #------ Create a temporary raster to send to the FOTO function. ------------------------# + myenv = environment() + nx = nrow(X) + ny = ncol(X) + yswap = rev(sequence(ny)) + Xt = t(X[,yswap]) + img = raster(Xt) + wsize = min(nx,ny)/1 + N = ceiling(img@nrows/wsize) + M = ceiling(img@ncols/wsize) + cells = N * M + #---------------------------------------------------------------------------------------# + + + + #------ Run the FOTO function for this raster. Single window using the entire image. ---# + Imat = matrix(img,wsize,wsize) + fftim = Mod(stats::fft(Imat))^2 + offfft = ceiling(dim(Imat)[1]/2) + r = sqrt((col(Imat) - offfft)^2 + (row(Imat) - offfft)^2) + rzonal = raster::zonal( x = raster::raster(fftim) + , z = raster::raster(r) + , fun = "mean" + , na.rm = TRUE + )#end raster::zonal + rspec = rev(rzonal[, 2]) + names(rspec) = rev(rzonal[, 1]) + sigma = sd(Imat,na.rm=TRUE) + rscal = rspec / sigma + + iuse = rev(sequence(wsize/2)[-c(1,2)]) + ans = rscal[iuse] + #---------------------------------------------------------------------------------------# + + + #----- Return answer. ------------------------------------------------------------------# + return(ans) + #---------------------------------------------------------------------------------------# +}#end foto.periodogram +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/poly.clockwise.r b/R-utils/poly.clockwise.r index 7a44bb09f..159008649 100644 --- a/R-utils/poly.clockwise.r +++ b/R-utils/poly.clockwise.r @@ -19,11 +19,11 @@ poly.clockwise <<- function(x,y=NULL){ #------ Make sure this is a closed path. -----------------------------------------------# nxy = length(x) - if (! ( x[1] %==% x[nxy] && y[1] %==% y[nxy] ) ){ + if (! ( x[1] %eq% x[nxy] && y[1] %eq% y[nxy] ) ){ x = c(x,x[1]) y = c(y,y[1]) nxy = nxy + 1 - }#end if (! ( x[1] %==% x[nxy] && y[1] %==% y[nxy] ) ) + }#end if (! ( x[1] %eq% x[nxy] && y[1] %eq% y[nxy] ) ) #---------------------------------------------------------------------------------------# diff --git a/R-utils/pop.interp.r b/R-utils/pop.interp.r index dd2f6d38d..4ffbb49a1 100644 --- a/R-utils/pop.interp.r +++ b/R-utils/pop.interp.r @@ -33,7 +33,7 @@ pop.interp <<- function( p #---------------------------------------------------------------------------------------# #----- For the prediction step, we only keep entries with actual population. -----------# - keep = p %>% 0 + keep = p %gt% 0 #---------------------------------------------------------------------------------------# diff --git a/R-utils/pop.loess.r b/R-utils/pop.loess.r index e19259ae4..baeec7333 100644 --- a/R-utils/pop.loess.r +++ b/R-utils/pop.loess.r @@ -16,7 +16,7 @@ pop.loess <<- function(p,z=seq_along(p),pfill=1e-6,zinf=1.25*max(z),...){ #---------------------------------------------------------------------------------------# #----- For the prediction step, we only keep entries with actual population. -----------# - keep = p %>% 0 + keep = p %gt% 0 #---------------------------------------------------------------------------------------# diff --git a/R-utils/pretty.log.r b/R-utils/pretty.log.r index 7c8e0770d..aa8f91997 100644 --- a/R-utils/pretty.log.r +++ b/R-utils/pretty.log.r @@ -14,15 +14,15 @@ pretty.log = function(x,base=10,n=5,forcelog=FALSE){ # gives a more legible scale. # #---------------------------------------------------------------------------------------# if (base == 10 && dlog.neat %wr% c(0.1,0.5) && (! forcelog)){ - sel = abs(log.neat - as.integer(log.neat)) %<% (0.5 * dlog.neat) + sel = abs(log.neat - as.integer(log.neat)) %lt% (0.5 * dlog.neat) tens = sort(c(neat[sel],base^(c(floor(min(log.neat)),ceiling(max(log.neat)))))) #------------------------------------------------------------------------------------# # Fix scale so it looks nicer if dtens is 2 or 3. # #------------------------------------------------------------------------------------# - if (dlog.neat %<% 0.15){ + if (dlog.neat %lt% 0.15){ mult = c(1,2,3,5,7) - }else if (dlog.neat %<% 0.35){ + }else if (dlog.neat %lt% 0.35){ mult = c(1,2,5) }else{ mult = c(1,3) @@ -33,7 +33,7 @@ pretty.log = function(x,base=10,n=5,forcelog=FALSE){ vlevels = vlevels[aa:zz] still.log = TRUE #------------------------------------------------------------------------------------# - }else if(dlog.neat %<% 0.1 && (! forcelog)){ + }else if(dlog.neat %lt% 0.1 && (! forcelog)){ #----- The plot is hardly log, use normal units instead. ---------------------------# vlevels = pretty(x=x,n=n) still.log = FALSE diff --git a/R-utils/pretty.time.r b/R-utils/pretty.time.r index 05e1aab3e..56dec6c3b 100644 --- a/R-utils/pretty.time.r +++ b/R-utils/pretty.time.r @@ -327,21 +327,21 @@ pretty.elapsed <<- function(x,base,n=5,...){ #---------------------------------------------------------------------------------------# # Re-scale data based on the pretty limits. # #---------------------------------------------------------------------------------------# - if (diff.base %<=% 0.075 || diff.base %>=% 0.75){ + if (diff.base %le% 0.075 || diff.base %ge% 0.75){ dbase = diff.base * base - }else if (diff.base %<% 0.15){ + }else if (diff.base %lt% 0.15){ if (base == 30){ dbase = base / 15 }else{ dbase = base / 12 }#end if (base == 30) - }else if (diff.base %<% 0.35){ + }else if (diff.base %lt% 0.35){ if (base == 30){ dbase = base / 6 }else{ dbase = base / 4 }#end if (base == 30) - }else if (diff.base %<% 0.50){ + }else if (diff.base %lt% 0.50){ dbase = base / 3 }else{ dbase = base / 2 diff --git a/R-utils/pretty.xylim.r b/R-utils/pretty.xylim.r index 3140e148f..e6f942136 100644 --- a/R-utils/pretty.xylim.r +++ b/R-utils/pretty.xylim.r @@ -36,7 +36,7 @@ pretty.xylim <<- function(u,fracexp=0.00,is.log=FALSE){ #----- Select the data that we consider for the range. ---------------------------------# vec.u = c(u) - if (is.log) vec.u[! (vec.u %>% 0)] = NA + if (is.log) vec.u[! (vec.u %gt% 0)] = NA ulimit = range(vec.u,finite=TRUE) #---------------------------------------------------------------------------------------# diff --git a/R-utils/ptcloud.2.patch.r b/R-utils/ptcloud.2.patch.r index b9610a17f..1e135a436 100644 --- a/R-utils/ptcloud.2.patch.r +++ b/R-utils/ptcloud.2.patch.r @@ -284,8 +284,8 @@ ptcloud.2.patch <<- function( pt.cloud hgt.cutoff = dbh2h(dbh=dbh0.min ,ipft=pft.def) hgt.bottom = hgt.cutoff }#end if (cstep %in% "calibration") - k.sel = which(hgtprof[ipk] %>=% hgt.cutoff) - k.bot = which(hgtprof[ipk] %>=% hgt.bottom) + k.sel = which(hgtprof[ipk] %ge% hgt.cutoff) + k.bot = which(hgtprof[ipk] %ge% hgt.bottom) #---------------------------------------------------------------------------------# @@ -305,15 +305,15 @@ ptcloud.2.patch <<- function( pt.cloud }else if (length(k.sel) == 0){ #----- Tallest cohort is outside range of DBH. Don't constrain. --------------# k.idx = ibnd[max(k.bot) + 1] - sel = hgtprof %>=% hgtprof[k.idx] + sel = hgtprof %ge% hgtprof[k.idx] bel = sel #------------------------------------------------------------------------------# }else{ #----- Keep only cohorts whose peak is above minimum DBH. ---------------------# k.idx = ibnd[max(k.sel) + 1] b.idx = ibnd[max(k.bot) + 1] - sel = hgtprof %>=% hgtprof[k.idx] - bel = hgtprof %>=% hgtprof[b.idx] + sel = hgtprof %ge% hgtprof[k.idx] + bel = hgtprof %ge% hgtprof[b.idx] #------------------------------------------------------------------------------# }#end if ((length(k.sel) == 0) && (length(k.bot) == 0)) #---------------------------------------------------------------------------------# @@ -341,7 +341,7 @@ ptcloud.2.patch <<- function( pt.cloud #------ Selected data. --------------------------------------------------------# ulai = sapply(X=c.ulai,FUN=sum ) uipk = sapply(X=c.uipk,FUN=commonest) - keep = ulai %>% 0. + keep = ulai %gt% 0. if (any(keep)){ ulai = c(ulai [keep],0) uipk = uipk [keep] @@ -360,7 +360,7 @@ ptcloud.2.patch <<- function( pt.cloud #------ Total data. -----------------------------------------------------------# blai = sapply(X=b.ulai,FUN=sum ) bipk = sapply(X=b.uipk,FUN=commonest) - beep = blai %>% 0. + beep = blai %gt% 0. if (any(beep)){ blai = c(blai [beep],0) bipk = bipk [beep] @@ -472,7 +472,7 @@ ptcloud.2.patch <<- function( pt.cloud ipft.bft = rep(mypfts , each = bcoh ) + 0L * bpft wdns.bft = rep(pft$rho[mypfts], each = bcoh ) + 0. * bpft sla.bft = rep(pft$SLA[mypfts], each = bcoh ) + 0. * bpft - bleaf.bft = ( size2bl(dbh=dbh.bft,hgt=hgt.bft,sla=sla.pft,ipft=ipft.bft) + bleaf.bft = ( size2bl(dbh=dbh.bft,hgt=hgt.bft,sla=sla.bft,ipft=ipft.bft) + 0. * bpft )#end bleaf.bft bdead.bft = size2bd(dbh=dbh.bft,hgt=hgt.bft,ipft=ipft.bft) + 0. * bpft @@ -603,7 +603,7 @@ ptcloud.2.patch <<- function( pt.cloud #----- Check for degenerate solution. -----------------------------------------# - suspicious = (sum(lai.pft*f.net) %>% 12) + suspicious = (sum(lai.pft*f.net) %gt% 12) #------------------------------------------------------------------------------# @@ -613,11 +613,11 @@ ptcloud.2.patch <<- function( pt.cloud # This indicates that most of the returns are coming from below the # # calibration layer (DBH > 10cm) so it is really unconstrained. # #------------------------------------------------------------------------------# - x.bsa = (f.bsa %>=% f.max.oth) && (b.bsa %<=% b.min.oth) - x.lai = (f.lai %>=% f.max.oth) && (b.lai %<=% b.min.oth) - x.agb = (f.agb %>=% f.max.oth) && (b.agb %<=% b.min.oth) - x.npl = (f.npl %>=% f.max.npl) && (b.npl %<=% b.min.npl) - x.net = (f.net %>=% f.max.oth) && (b.net %<=% b.min.oth) + x.bsa = (f.bsa %ge% f.max.oth) && (b.bsa %le% b.min.oth) + x.lai = (f.lai %ge% f.max.oth) && (b.lai %le% b.min.oth) + x.agb = (f.agb %ge% f.max.oth) && (b.agb %le% b.min.oth) + x.npl = (f.npl %ge% f.max.npl) && (b.npl %le% b.min.npl) + x.net = (f.net %ge% f.max.oth) && (b.net %le% b.min.oth) x.any = x.npl || x.bsa || x.lai || x.agb || x.net f.bsa = ifelse(test=x.any,yes=f.net.def,no=f.bsa) f.lai = ifelse(test=x.any,yes=f.net.def,no=f.lai) @@ -724,7 +724,7 @@ ptcloud.2.patch <<- function( pt.cloud #----- Check for degenerate solution. -----------------------------------------# - suspicious = suspicious || (pssnow$lai %>% 12) + suspicious = suspicious || (pssnow$lai %gt% 12) if (suspicious){ if (nidx > 0){ #----- Aggregate information of the suspicious patch. -------------------# @@ -737,7 +737,7 @@ ptcloud.2.patch <<- function( pt.cloud + css.agf * ( css.bsap + css.bbark + cssnow$bdead ) )#end css.agb css.bsa = 0.25 * pi * cssnow$dbh * cssnow$dbh - css.use = cssnow$dbh %>=% 10.0 + css.use = cssnow$dbh %ge% 10.0 npl.show = 10000. * sum(cssnow$n[css.use]) lai.show = sum(cssnow$lai) agb.show = sum(cssnow$n[css.use]*css.agb[css.use]) diff --git a/R-utils/qapply.r b/R-utils/qapply.r index b05ceca20..b9606058a 100644 --- a/R-utils/qapply.r +++ b/R-utils/qapply.r @@ -8,6 +8,15 @@ #------------------------------------------------------------------------------------------# qapply <<- function(X,INDEX,DIM,FUN,...){ + #---------------------------------------------------------------------------------------# + # Find out whether X is a data frame. If so, we return the same variable types and # + # names. # + #---------------------------------------------------------------------------------------# + X.df = is.data.frame(X) + if (missing(DIM) && X.df) DIM = 1 + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Find the number of dimensions. # #---------------------------------------------------------------------------------------# @@ -86,6 +95,18 @@ qapply <<- function(X,INDEX,DIM,FUN,...){ }#end if #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # If the original data was a data frame and DIM was 1 (or missing), make sure the # + # output is also a data frame. # + #---------------------------------------------------------------------------------------# + if (X.df && (DIM == 1)){ + eout = as.data.frame(eout) + names(eout) = names(X) + }#end if (X.df && (DIM == 1)) + #---------------------------------------------------------------------------------------# + + return(eout) }#end function qapply #==========================================================================================# diff --git a/R-utils/radiation_profile_utils.r b/R-utils/radiation_profile_utils.r index 28322c49d..d908a12c9 100644 --- a/R-utils/radiation_profile_utils.r +++ b/R-utils/radiation_profile_utils.r @@ -74,7 +74,7 @@ layer.absorption <<- function(ipaco,down,up){ rel.last <<- function(x){ if (length(x) == 0){ ans = NA - }else if (x[1] %==% 0){ + }else if (x[1] %eq% 0){ ans = NA }else{ ans = x[length(x)] /x[1] diff --git a/R-utils/rain.downscale.r b/R-utils/rain.downscale.r index 3b538417c..47092c4cc 100644 --- a/R-utils/rain.downscale.r +++ b/R-utils/rain.downscale.r @@ -63,7 +63,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 #----- Find the ratio following Ryan's thesis. -----------------------------------------# - g.mu.lut = ifelse(test=g.rho.lut %>% 0,yes=g.rbar.lut/g.rho.lut,no=0.) + g.mu.lut = ifelse(test=g.rho.lut %gt% 0,yes=g.rbar.lut/g.rho.lut,no=0.) #---------------------------------------------------------------------------------------# @@ -72,7 +72,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 mu.in = mu.in.lut [idx] g.rbar = g.rbar.lut[idx] g.mu = g.mu.lut [idx] - sg.mu = ifelse(test = g.mu %>% 0., yes = mu.in / g.mu, no = 0.) + sg.mu = ifelse(test = g.mu %gt% 0., yes = mu.in / g.mu, no = 0.) #---------------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 SG.MU = matrix( data = sg.mu , nrow = ndat.in, ncol = nsub) G.RBAR = matrix( data = g.rbar , nrow = ndat.in, ncol = nsub) PRATE.IN = matrix( data = prate.in, nrow = ndat.in, ncol = nsub) - WGT.OUT = ifelse( test = SG.MU %>% 0. & PRATE.IN %>% 0. + WGT.OUT = ifelse( test = SG.MU %gt% 0. & PRATE.IN %gt% 0. , yes = PRATE.IN / SG.MU * log(1.0/(1.0 - CDF.MAT)) , no = 1 / nsub )#end ifelse @@ -126,21 +126,21 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 #---------------------------------------------------------------------------------------# if (mask.low){ ptotal.out = sum(prate.out) - prate.mask = ifelse(prate.out %>=% rain.min, prate.out, 0.) + prate.mask = ifelse(prate.out %ge% rain.min, prate.out, 0.) ptotal.mask = sum(prate.mask) - if (ptotal.mask %>=% rain.min){ + if (ptotal.mask %ge% rain.min){ prate.out = prate.mask * ptotal.out / ptotal.mask - }#end if (ptotal.mask %>=% rain.min) + }#end if (ptotal.mask %ge% rain.min) }#end if (mask.low) #---------------------------------------------------------------------------------------# #------ Make sure the average output rainfall matches the average input rainfall. ------# prate.out.bar = mean(prate.out,na.rm=TRUE) - if (prate.out.bar %>=% rain.min){ + if (prate.out.bar %ge% rain.min){ prate.in.bar = mean(prate.in,na.rm=TRUE) prate.out = prate.out * prate.in.bar / prate.out.bar - }#end if (prate.out.bar %>=% rain.min) + }#end if (prate.out.bar %ge% rain.min) #---------------------------------------------------------------------------------------# return(prate.out) diff --git a/R-utils/rconstants.r b/R-utils/rconstants.r index b1f65e8a0..478f76792 100644 --- a/R-utils/rconstants.r +++ b/R-utils/rconstants.r @@ -38,6 +38,7 @@ golden <<- 0.5*(1+sqrt(5.)) # Golden ratio [ #------------------------------------------------------------------------------------------# stefan <<- 5.6696e-8 # Stefan-Boltzmann constant [ W/m2/K4] boltzmann <<- 1.3806503e-23 # Boltzmann constant [m2 kg/s2/K] +astro <<- 149597870700 # One astronomical unit (as of 2012) [ m] t00 <<- 273.15 # 0 degC [ degC] rmol <<- 8.314510 # Molar gas constant [ J/mol/K] volmol <<- 0.022710980 # Molar volume at STP [ m3] @@ -46,6 +47,38 @@ clight <<- 299792458 # Speed of light [ #------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# General Earth properties # +#------------------------------------------------------------------------------------------# +vonk <<- 0.40 # Von Karman constant [ ---] +grav <<- 9.80665 # Gravity acceleration [ m/s2] +gg <<- .5 * grav # Half of grav [ m/s2] +erad <<- 6370997. # Earth radius [ m] +sunrad <<- 695508000. # Sun radius [ m] +spcon <<- pio180*erad # One degree of latitude [ m] +spconkm <<- spcon*0.001 # One degree of latitude [ km] +eradi <<- 1./erad # Inverse of Earth radius [ 1/m] +erad2 <<- erad*2 # Earth diameter [ m] +eprjarea <<- pi*erad^2 # Earth's projected area [ m2] +ausphere <<- 4*pi*astro^2 # Sphere area for one astronomical unit [ m2] +ehgt <<- 8500. # Earth's scale height (~ RT/g) [ m] +esolid <<- pi*sunrad^2/astro^2 # Solar angle of Earth's interception [ sr] +ss60 <<- 1.8663 # Polar stereo conversion to 60 deg [ ] +omega <<- 7.292e-5 # Earth's rotation speed [ rad/s] +viscos <<- .15e-4 # Viscosity coefficient [ ] +tsun <<- 5778 # Sun temperature [ K] +radsol <<- stefan*tsun^4/pi # Extraterrestrial solar irradiance [ W/m2] +solar <<- radsol*esolid # Solar constant [ W/m2] +p00 <<- 1.e5 # Reference pressure [ Pa] +prefsea <<- 101325. # Reference sea level pressure [ Pa] +p00i <<- 1. / p00 # 1/p00 [ 1/Pa] +o2.ref <<- 0.209 # Nominal O2 concentration [ mol/mol] +capri <<- -23.44 * pio180 # Tropic of Capricornium latitude [ rad] +shsummer <<- -10 # Day of year of S.Hemisphere summer solstice [ day] +#------------------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------------------# # Molar masses and derived variables # #------------------------------------------------------------------------------------------# @@ -64,46 +97,112 @@ mmh2oi <<- 1./mmh2o # 1./mmh2o [ #------------------------------------------------------------------------------------------# -# Time conversion units # +# Conversion factors for time units. # #------------------------------------------------------------------------------------------# -yr.day <<- 365.2425 # # of days in a year [ day/yr] -yr.ftnight <<- 26 # # of fornights in a year [ftnight/yr] -yr.mon <<- 12 # # of months in a year [ mon/yr] -day.sec <<- 86400. # # of seconds in a day [ s/day] -day.sec2 <<- day.sec^2 # # Square of day.sec [ s2/day2] -day.mon <<- yr.day/yr.mon # # of days in a month [ day/mon] -day.min <<- 1440. # # of minutes in a day [ min/day] -day.hr <<- 24. # # of hours in a day [ hr/day] -hr.sec <<- 3600. # # of seconds in an hour [ s/hr] -hr.min <<- 60. # # of minutes in an hour [ min/hr] -min.sec <<- 60. # # of seconds in a minute [ s/min] -yr.sec <<- yr.day * day.sec # # of seconds in a year [ s/yr] -kg2g <<- 1000. # # of grams in a kilogram [ g/kg] +min.sec <<- 60. # # of seconds in a minute [ s/min] +hr.min <<- 60. # # of minutes in an hour [ min/hr] +day.hr <<- 24. # # of hours in a day [ hr/day] +day.week <<- 7. # # of days in a week [ day/wk] +yr.day <<- 365.2425 # # of days in a year [ day/yr] +yr.ftnight <<- 26 # # of fortnights in a year [ftnight/yr] +yr.mon <<- 12 # # of months in a year [ mon/yr] +#----- Derived quantities. ----------------------------------------------------------------# +hr.sec <<- hr.min * min.sec # # of seconds in an hour [ s/hr] +day.min <<- day.hr * hr.min # # of minutes in a day [ min/day] +day.sec <<- day.hr * hr.sec # # of seconds in a day [ s/day] +day.sec2 <<- day.sec^2 # # Square of day.sec [ s2/day2] +day.mon <<- yr.day/yr.mon # # of days in a month [ day/mon] +yr.sec <<- yr.day * day.sec # # of seconds in a year [ s/yr] +yr.week <<- yr.day / day.week # # of weeks in a year [ wk/yr] #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# General Earth properties # +# Conversion factors for mass units. # #------------------------------------------------------------------------------------------# -vonk <<- 0.40 # Von Karman constant [ ---] -grav <<- 9.80665 # Gravity acceleration [ m/s2] -gg <<- .5 * grav # Half of grav [ m/s2] -erad <<- 6370997. # Earth radius [ m] -spcon <<- pio180*erad # One degree of latitude [ m] -spconkm <<- spcon*0.001 # One degree of latitude [ km] -eradi <<- 1./erad # Inverse of Earth radius [ 1/m] -erad2 <<- erad*2 # Earth diameter [ m] -ss60 <<- 1.8663 # Polar stereo conversion to 60 deg [ ] -omega <<- 7.292e-5 # Earth's rotation speed [ rad/s] -viscos <<- .15e-4 # Viscosity coefficient [ ] -solar <<- 1.3533e3 # Solar constant [ W/m2] -p00 <<- 1.e5 # Reference pressure [ Pa] -prefsea <<- 101325. # Reference sea level pressure [ Pa] -p00i <<- 1. / p00 # 1/p00 [ 1/Pa] -o2.ref <<- 0.209 # Nominal O2 concentration [ mol/mol] -capri <<- -23.44 * pio180 # Tropic of Capricornium latitude [ rad] -shsummer <<- -10 # Day of year of S.Hemisphere summer solstice [ day] +kg2g <<- 1000. # # of grams in a kilogram [ g/kg] +g2kg <<- 1. / kg2g # # of kilograms in a gram [ kg/g] +g2mg <<- 1000. # # of milligrams in a gram [ mg/g] +mg2g <<- 1. / g2mg # # of grams in a milligram [ g/mg] +mg2ug <<- 1000. # # of micrograms in a milligram [ ug/mg] +ug2mg <<- 1. / mg2ug # # of milligrams in a microgram [ mg/ug] +kg2mg <<- kg2g * g2mg # # of milligrams in a kilogram [ mg/kg] +mg2kg <<- 1. / kg2g # # of kilograms in a milligram [ kg/mg] +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Miscellaneous convertion factors. # +#------------------------------------------------------------------------------------------# +mol.2.mmol <<- 1.e3 # mol => mmol +mmol.2.mol <<- 1. / mol.2.mmol # mmol => mol +mol.2.umol <<- 1.e6 # mol => umol +umol.2.mol <<- 1. / mol.2.umol # umol => mol +umol.2.mmol <<- umol.2.mol * mol.2.mmol # umol => mmol +mmol.2.umol <<- 1. / umol.2.mmol # umol => mmol +umol.2.kgC <<- 1.20107e-8 # umol(CO2) => kg(C) +Watts.2.Ein <<- 4.6e-6 # W/m2 => mol/m2/s +Ein.2.Watts <<- 1./Watts.2.Ein # mol/m2/s => W/m2 +kgC.2.umol <<- 1. / umol.2.kgC # kg(C) => umol(CO2) +kgom2.2.tonoha <<- 10. # kg(C)/m2 => ton(C)/ha +tonoha.2.kgom2 <<- 0.1 # ton(C)/ha => kg(C)/m2 +umols.2.kgCyr <<- umol.2.kgC * yr.sec # umol(CO2)/s => kg(C)/yr +umols.2.kgWday <<- umol.2.mol*mmh2o*day.sec # umol (H2O)/s => kg (H2O) / day +mols.2.kgCyr <<- mol.2.umol * umols.2.kgCyr # umol(CO2)/s => kg(C)/yr +mols.2.kgWday <<- mol.2.umol * umols.2.kgWday # umol (H2O)/s => kg (H2O) / day +kgCyr.2.umols <<- 1. / umols.2.kgCyr # kg(C)/yr => umol(CO2)/s +kgCday.2.umols <<- kgC.2.umol / day.sec # kg(C)/day => umol(CO2)/s +kgWday.2.umols <<- 1. / umols.2.kgWday # kg (H2O) / day => umol (H2O)/s +Torr.2.Pa <<- prefsea / 760. # Torr => Pa +Pa.2.Torr <<- 1. / Torr.2.Pa # Pa => Torr +hPa.2.Pa <<- 100. # hPa => Pa +Pa.2.hPa <<- 1. / hPa.2.Pa # Pa => hPa +kPa.2.Pa <<- 1000. # kPa => Pa +Pa.2.kPa <<- 1. / kPa.2.Pa # Pa => kPa +kPa.2.hPa <<- kPa.2.Pa * Pa.2.hPa # kPa => hPa +hPa.2.kPa <<- 1. / kPa.2.hPa # hPa => kPa +MPa.2.Pa <<- 1.e6 # MPa => Pa +Pa.2.MPa <<- 1. / MPa.2.Pa # Pa => MPa +kt.2.mos <<- 1852 / hr.sec # knots => m/s +mos.2.kt <<- 1. / kt.2.mos # m/s => knots +frac2pc <<- 100. # fraction => percent +pc2frac <<- 1. / frac2pc # percent => fraction +cm.2.m <<- 0.01 # cm => m +m.2.cm <<- 1. / cm.2.m # m => cm +mm.2.m <<- 0.001 # mm => m +m.2.mm <<- 1. / mm.2.m # m => mm +dm.2.cm <<- 10. # mm => dm +cm.2.dm <<- 1. / dm.2.cm # dm => mm +mm.2.cm <<- 0.1 # mm => cm +cm.2.mm <<- 1. / mm.2.cm # cm => mm +um.2.mm <<- 0.001 # um => mm +mm.2.um <<- 1. / um.2.mm # mm => um +um.2.cm <<- um.2.mm * mm.2.cm # um => cm +cm.2.um <<- 1. / um.2.mm # cm => um +in.2.cm <<- 2.54 # in => cm +cm.2.in <<- 1. / in.2.cm # cm => in +in.2.m <<- in.2.cm * cm.2.m # in => m +m.2.in <<- 1. / in.2.m # m => in +ft.2.cm <<- 30.48 # ft => cm +cm.2.ft <<- 1. / ft.2.cm # cm => ft +ft.2.m <<- ft.2.cm * cm.2.m # ft => m +m.2.ft <<- 1. / ft.2.m # m => ft +ha.2.m2 <<- 10000. # hectare => m2 +m2.2.ha <<- 1./ha.2.m2 # m2 => hectare +m2.2.cm2 <<- m.2.cm^2 # cm2 => m2 +cm2.2.m2 <<- 1./m2.2.cm2 # m2 => cm2 +cm2.2.mm2 <<- cm.2.mm^2 # cm2 => mm2 +mm2.2.cm2 <<- 1./cm2.2.mm2 # mm2 => cm2 +m2.2.mm2 <<- m2.2.cm2 * cm2.2.mm2 # m2 => mm2 +mm2.2.m2 <<- 1. / m2.2.mm2 # mm2 => m2 +MJ.2.J <<- 1.e6 # MJ => J +J.2.MJ <<- 1./MJ.2.J # J => MJ +kJ.2.J <<- 1000. # kJ => J +J.2.kJ <<- 1./kJ.2.J # J => kJ +W.2.MJoday <<- J.2.MJ * day.sec # W (J/s) => MJ/day +MJoday.2.W <<- 1. / W.2.MJoday # MJ/day => W (J/s) #------------------------------------------------------------------------------------------# @@ -192,6 +291,20 @@ cliqi <<- 1./cliq # Inverse of water heat capacity +#------------------------------------------------------------------------------------------# +# Soil matric potential unit conversion. # +#------------------------------------------------------------------------------------------# +m.2.mpa <<- grav * wdns * 1.e-6 # Matric potential convesion [ mPa/m] +mpa.2.m <<- 1. / m.2.mpa # Matric potential convesion [ m/mPa] +mm.2.mpa <<- grav * wdns * 1.e-9 # Matric potential convesion [ mPa/mm] +mpa.2.mm <<- 1. / mm.2.mpa # Matric potential convesion [ mm/mPa] +um.2.mpa <<- grav * wdns * 1.e-12 # Matric potential convesion [ mPa/um] +mpa.2.um <<- 1. / um.2.mpa # Matric potential convesion [ um/mPa] +#------------------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------------------# # Ice properties # #------------------------------------------------------------------------------------------# @@ -278,26 +391,6 @@ htripoli <<- cpdry*ttripoli # Sensible enthalpy at T=Ttr htripolii <<- 1./htripoli # 1./htripoli [ kg/J] #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Unit conversion, it must be defined locally even for coupled runs. # -#------------------------------------------------------------------------------------------# -mol.2.umol <<- 1.e6 # mol => umol -umol.2.mol <<- 1.e-6 # umol => mol -umol.2.kgC <<- 1.20107e-8 # umol(CO2) => kg(C) -Watts.2.Ein <<- 4.6e-6 # W/m2 => mol/m2/s -Ein.2.Watts <<- 1./Watts.2.Ein # mol/m2/s => W/m2 -kgC.2.umol <<- 1. / umol.2.kgC # kg(C) => umol(CO2) -kgom2.2.tonoha <<- 10. # kg(C)/m2 => ton(C)/ha -tonoha.2.kgom2 <<- 0.1 # ton(C)/ha => kg(C)/m2 -umols.2.kgCyr <<- umol.2.kgC * yr.sec # umol(CO2)/s => kg(C)/yr -kgCyr.2.umols <<- 1. / umols.2.kgCyr # kg(C)/yr => umol(CO2)/s -kgCday.2.umols <<- kgC.2.umol / day.sec # kg(C)/day => umol(CO2)/s -Torr.2.Pa <<- prefsea / 760. # Torr => Pa -Pa.2.Torr <<- 1. / Torr.2.Pa # Pa => Torr -kt.2.mos <<- 1852 / hr.sec # knots => m/s -mos.2.kt <<- 1. / kt.2.mos # m/s => knots -#------------------------------------------------------------------------------------------# - #------------------------------------------------------------------------------------------# @@ -354,8 +447,14 @@ almost.one <<- 1.-almost.zero #------------------------------------------------------------------------------------------# # Default NA for chron objects. # #------------------------------------------------------------------------------------------# -NA_dates_ <<- chron(dates=NA) -NA_times_ <<- chron(times=NA) -NA_chron_ <<- chron(dates=NA,times=NA) +if ("chron" %in% rownames(installed.packages())){ + NA_dates_ <<- chron::chron(dates=NA) + NA_times_ <<- chron::chron(times=NA) + NA_chron_ <<- chron::chron(dates=NA,times=NA) +}#end if ("chron" %in% rownames(installed.packages())) +#------------------------------------------------------------------------------------------# + + +#---- Default NA for logical objects. -----------------------------------------------------# NA_logical_ <<- as.logical(NA) #------------------------------------------------------------------------------------------# diff --git a/R-utils/read.q.files.r b/R-utils/read.q.files.r index dfc756644..d586142ca 100644 --- a/R-utils/read.q.files.r +++ b/R-utils/read.q.files.r @@ -24,21 +24,17 @@ read.q.files <<- function( datum nzg = datum$nzg nzs = datum$nzs ndcycle = datum$ndcycle - isoilflg = datum$isoilflg slz = datum$slz slt = c(datum$slz[-1],0) - slxsand = datum$slxsand - slxclay = datum$slxclay - ntext = datum$ntext soil.prop = datum$soil.prop dslz = datum$dslz soil.depth = datum$soil.depth soil.dry = datum$soil.dry soil.poro = datum$soil.poro soilcp = datum$soil.prop$soilcp - slmsts = datum$soil.prop$slmsts - ka = datum$ka - kz = datum$kz + soilpo = datum$soil.prop$soilpo + kasi = datum$ka + kzsi = datum$kz #---------------------------------------------------------------------------------------# @@ -72,6 +68,7 @@ read.q.files <<- function( datum lu = datum$lu qmean = datum$qmean qmsqu = datum$qmsqu + site = datum$site patch = datum$patch qpatch = datum$qpatch cohort = datum$cohort @@ -110,15 +107,18 @@ read.q.files <<- function( datum h5file.bz2 = paste(datum$input[m],"bz2",sep=".") h5file.gz = paste(datum$input[m],"gz" ,sep=".") if (file.exists(h5file)){ + dummy = touch(h5file) mymont = hdf5load(file=h5file,load=FALSE,verbosity=0,tidy=TRUE) }else if(file.exists(h5file.bz2)){ + dummy = touch(h5file.bz2) temp.file = file.path(tempdir(),basename(h5file)) dummy = bunzip2(filename=h5file.bz2,destname=temp.file,remove=FALSE) mymont = hdf5load(file=temp.file,load=FALSE,verbosity=0,tidy=TRUE) dummy = file.remove(temp.file) }else if(file.exists(h5file.gz)){ + dummy = touch(h5file.gz) temp.file = file.path(tempdir(),basename(h5file)) dummy = gunzip(filename=h5file.gz,destname=temp.file,remove=FALSE) mymont = hdf5load(file=temp.file,load=FALSE,verbosity=0,tidy=TRUE) @@ -354,6 +354,21 @@ read.q.files <<- function( datum mymont$MMEAN.LLSPAN.CO = 12. / pft$leaf.turnover.rate[mymont$PFT] mymont$MMEAN.VM.BAR.CO = pft$vm0[mymont$PFT] }#end if (! "SLA" %in% names(mymont)) + #----- Patch-level mean diel for canopy temperature and density may be missing. -----# + if (mean(c(mymont$QMEAN.CAN.TEMP.PA)) %eq% 0.){ + mymont$QMEAN.CAN.EXNER.PA = press2exner ( pres = mymont$QMEAN.CAN.PRSS.PA ) + mymont$QMEAN.CAN.TEMP.PA = extheta2temp( exner = mymont$QMEAN.CAN.EXNER.PA + , theta = mymont$QMEAN.CAN.THETA.PA + )#end extheta2temp + mymont$QMEAN.CAN.RHOS.PA = idealdenssh ( pres = mymont$QMEAN.CAN.PRSS.PA + , temp = mymont$QMEAN.CAN.TEMP.PA + , qvpr = mymont$QMEAN.CAN.SHV.PA + )#end idealdenssh + mymont$QMEAN.CAN.DMOL.PA = idealdmolsh ( pres = mymont$QMEAN.CAN.PRSS.PA + , temp = mymont$QMEAN.CAN.TEMP.PA + , qvpr = mymont$QMEAN.CAN.SHV.PA + )#end idealdenssh + }#end if (mean(c(mymont$QMEAN.CAN.TEMP.PA)) %eq% 0.) #------------------------------------------------------------------------------------# @@ -365,6 +380,56 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# + #---- Read in the site-level area. --------------------------------------------------# + isi = sequence(mymont$NSITES.GLOBAL) + areasi = mymont$AREA.SI + nsites = mymont$PYSI.N + npatches = mymont$SIPA.N + nsites.tot = sum(nsites) + npatches.tot = sum(npatches) + #------------------------------------------------------------------------------------# + + + #----- Read a few patch-level variables. --------------------------------------------# + ntextsi = mymont$NTEXT.SOIL[,nzg] + ntextpa = rep(x=ntextsi,times=npatches) + areapa = mymont$AREA * rep(areasi,times=npatches) + areapa = areapa / sum(areapa) + isipa = rep(isi,times=npatches) + ipa = sequence(mymont$NPATCHES.GLOBAL) + lupa = mymont$DIST.TYPE + agepa = mymont$AGE + lslsi = mymont$LSL + lslpa = rep(x=lslsi,times=npatches) + kapa = rep(x=kasi ,times=npatches) + #------------------------------------------------------------------------------------# + + + #----- Create table for a few soil profile properties at patch level. ---------------# + dslz.pa = matrix(data=dslz ,nrow=npatches.tot,ncol=nzg,byrow=TRUE ) + soilcp.pa = matrix(data=soilcp[ntextpa],nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soilpo.pa = matrix(data=soilpo[ntextpa],nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.area = matrix(data=areapa ,nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.lsl = matrix(data=lslpa ,nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.valid = as.numeric(col(soil.lsl) >= soil.lsl) + 0 * soil.lsl + soil.mask = ifelse(test=col(soil.lsl) >= soil.lsl,yes=1.,no=NA_real_) + 0 * soil.lsl + soil.area = apply(X=soil.area*soil.valid, MARGIN=2,FUN=reweight.valid) + #------------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------------# + # Weighting factors for top/bottom soil averages, which accounts for maximum # + # soil depth by site. # + #------------------------------------------------------------------------------------# + p.tt.wgtz = matrix(tt.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.tm.wgtz = matrix(tm.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.bm.wgtz = matrix(bm.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.tt.wgtz = t(apply(X=p.tt.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + p.tm.wgtz = t(apply(X=p.tm.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + p.bm.wgtz = t(apply(X=p.bm.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# # Find the mean latent heat of vaporisation. Because we assume it to be a # @@ -448,6 +513,7 @@ read.q.files <<- function( datum emean$gnd.shv [m] = mymont$MMEAN.GND.SHV.PY * kg2g emean$leaf.temp [m] = mymont$MMEAN.LEAF.TEMP.PY - t00 emean$leaf.water [m] = mymont$MMEAN.LEAF.WATER.PY + emean$leaf.water.im2 [m] = mymont$MMEAN.LEAF.WATER.IM2.PY emean$leaf.vpd [m] = mymont$MMEAN.LEAF.VPDEF.PY * 0.01 emean$wood.temp [m] = mymont$MMEAN.WOOD.TEMP.PY - t00 emean$hflxca [m] = - mymont$MMEAN.SENSIBLE.AC.PY @@ -510,6 +576,26 @@ read.q.files <<- function( datum emean$leaf.gbw [m] = mymont$MMEAN.LEAF.GBW.PY * day.sec emean$leaf.gsw [m] = mymont$MMEAN.LEAF.GSW.PY * day.sec emean$wood.gbw [m] = mymont$MMEAN.WOOD.GBW.PY * day.sec + #----- Snowpack/flooding variables. -------------------------------------------------# + emean$sfcw.mass [m] = mymont$MMEAN.SFCW.MASS.PY + emean$sfcw.temp [m] = mymont$MMEAN.SFCW.TEMP.PY - t00 + emean$sfcw.fliq [m] = mymont$MMEAN.SFCW.FLIQ.PY + emean$sfcw.depth [m] = mymont$MMEAN.SFCW.DEPTH.PY + emean$sfcw.cover [m] = mymont$MMEAN.SNOWFAC.PY + #----- Fire variables. --------------------------------------------------------------# + emean$fire.density [m] = mymont$MMEAN.FIRE.DENSITY.PY * 1.e6 + emean$fire.intensity [m] = mymont$MMEAN.FIRE.INTENSITY.PY * 1.e-3 + emean$fire.ignition [m] = mymont$MMEAN.IGNITION.RATE.PY * 1.e6 * mondays * day.sec + emean$fire.extinction [m] = 100. * (1. - exp(-mymont$MMEAN.FIRE.EXTINCTION.PY)) + emean$fire.spread [m] = mymont$MMEAN.FIRE.SPREAD.PY * min.sec + emean$fire.tlethal [m] = mymont$MMEAN.FIRE.TLETHAL.PY / min.sec + emean$fire.f.bherb [m] = mymont$MMEAN.FIRE.F.BHERB.PY * 100. + emean$fire.f.bwoody [m] = mymont$MMEAN.FIRE.F.BWOODY.PY * 100. + emean$fire.f.fgc [m] = mymont$MMEAN.FIRE.F.FGC.PY * 100. + emean$fire.f.stgc [m] = mymont$MMEAN.FIRE.F.STGC.PY * 100. + emean$burnt.area [m] = weighted.mean( x = mymont$BURNT.AREA * 100. + , w = areasi + )#end weigthed.mean #------------------------------------------------------------------------------------# @@ -532,13 +618,51 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # For soil properties, we must integrate across all patches, skipping layers # + # that were not solved by the model. This implies different weights across patches # + # for different layers (unused layers had weight set to zero). We do not set na.rm # + # to TRUE because we may have layers that were not resolved at all, and they shall # + # remain undefined. # + #------------------------------------------------------------------------------------# + soil.temp.lyr = apply( X = ( mymont$MMEAN.SOIL.TEMP.PA - t00 ) * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.water.lyr = apply( X = mymont$MMEAN.SOIL.WATER.PA * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.mstpot.lyr = apply( X = mymont$MMEAN.SOIL.MSTPOT.PA * soil.area + * (-1.) * grav * wdns * 1.e-6 + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.extracted.lyr = apply( X = mymont$MMEAN.TRANSLOSS.PA * soil.area / dslz.pa + * day.sec + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.wetness.lyr = ( ( mymont$MMEAN.SOIL.WATER.PA - soilcp.pa) + / ( soilpo.pa - soilcp.pa) ) + soil.wetness.lyr = apply( X = soil.wetness.lyr * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + #------------------------------------------------------------------------------------# + #------ Read in soil properties. ----------------------------------------------------# - emean$soil.temp [m,] = mymont$MMEAN.SOIL.TEMP.PY - t00 - emean$soil.water [m,] = mymont$MMEAN.SOIL.WATER.PY - emean$soil.mstpot [m,] = - mymont$MMEAN.SOIL.MSTPOT.PY * grav * wdns * 1.e-6 - emean$soil.extracted[m,] = - mymont$MMEAN.TRANSLOSS.PY * day.sec / dslz + emean$soil.temp [m,] = soil.temp.lyr + emean$soil.water [m,] = soil.water.lyr + emean$soil.mstpot [m,] = soil.mstpot.lyr + emean$soil.extracted[m,] = soil.extracted.lyr #------------------------------------------------------------------------------------# @@ -546,9 +670,6 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Find average near-surface soil temperature. # #------------------------------------------------------------------------------------# - soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PY - t00 - soil.water.lyr = mymont$MMEAN.SOIL.WATER.PY - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) emean$soil.temp.top [m] = sum(soil.temp.lyr * tt.wgtz) emean$soil.water.top [m] = sum(soil.water.lyr * tm.wgtz) * wdns * dz.msttop emean$soil.water.bot [m] = sum(soil.water.lyr * bm.wgtz) * wdns * dz.mstbot @@ -559,12 +680,22 @@ read.q.files <<- function( datum #----- Find averaged soil properties. -----------------------------------------------# - swater.now = rev(cumsum(rev(mymont$MMEAN.SOIL.WATER.PY * wdns * dslz))) - smoist.avg = swater.now / (wdns * soil.depth) - emean$paw [m] = 100. * ( ( swater.now[ka] - soil.dry [ka] ) - / ( soil.poro [ka] - soil.dry [ka] ) ) - emean$smpot[m] = ( - smoist2mpot(smoist=smoist.avg[ka],mysoil=soil.prop) - * 0.001 * grav ) + emean$paw [m] = 0. + emean$smpot[m] = 0. + for (p in sequence(npatches.tot)){ + ntext = ntextpa[p] + ka = kapa [p] + swater.now = rev(cumsum(rev(mymont$MMEAN.SOIL.WATER.PA[p,] * wdns * dslz))) + smoist.now = swater.now / (wdns * soil.depth) + paw.now = ( 100. * ( ( swater.now - soil.dry [,ntext] ) + / ( soil.poro [,ntext] - soil.dry [,ntext] ) ) + )#end paw.now + smpot.now = ( smoist2mpot(smoist=smoist.now,mysoil=soil.prop[ntext,]) + * (-1.) * grav * wdns * 1.e-6 + )#end smpot.now + emean$paw [m] = emean$paw [m] + paw.now [ka] * areapa[p] + emean$smpot[m] = emean$smpot[m] + smpot.now[ka] * areapa[p] + }#end for (p in sequence(nsites)) #------------------------------------------------------------------------------------# @@ -613,107 +744,156 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Read the mean diurnal cycle and the mean sum of the squares. # #------------------------------------------------------------------------------------# - qmean$gpp [m,] = mymont$QMEAN.GPP.PY - qmean$npp [m,] = mymont$QMEAN.NPP.PY - qmean$het.resp [m,] = mymont$QMEAN.RH.PY - qmean$fgc.resp [m,] = mymont$QMEAN.FGC.RH.PY - qmean$fsc.resp [m,] = mymont$QMEAN.FSC.RH.PY - qmean$stgc.resp [m,] = mymont$QMEAN.STGC.RH.PY - qmean$stsc.resp [m,] = mymont$QMEAN.STSC.RH.PY - qmean$msc.resp [m,] = mymont$QMEAN.MSC.RH.PY - qmean$ssc.resp [m,] = mymont$QMEAN.SSC.RH.PY - qmean$psc.resp [m,] = mymont$QMEAN.PSC.RH.PY - qmean$assim.light [m,] = mymont$QMEAN.A.LIGHT.PY - qmean$assim.rubp [m,] = mymont$QMEAN.A.RUBP.PY - qmean$assim.co2 [m,] = mymont$QMEAN.A.CO2.PY - qmean$assim.ratio [m,] = ( mymont$QMEAN.A.LIGHT.PY - / pmax(1e-6, pmin( mymont$QMEAN.A.RUBP.PY - , mymont$QMEAN.A.CO2.PY ))) - qmean$nee [m,] = ( mymont$QMEAN.CARBON.ST.PY - - mymont$QMEAN.CARBON.AC.PY ) - qmean$reco [m,] = mymont$QMEAN.PLRESP.PY + mymont$QMEAN.RH.PY - qmean$cflxca [m,] = - mymont$QMEAN.CARBON.AC.PY - qmean$cflxst [m,] = - mymont$QMEAN.CARBON.ST.PY - qmean$hflxca [m,] = - mymont$QMEAN.SENSIBLE.AC.PY - qmean$hflxlc [m,] = mymont$QMEAN.SENSIBLE.LC.PY - qmean$hflxwc [m,] = mymont$QMEAN.SENSIBLE.WC.PY - qmean$hflxgc [m,] = mymont$QMEAN.SENSIBLE.GC.PY - qmean$wflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * day.sec - qmean$qwflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * qmean.can.alvli.py - qmean$wflxlc [m,] = mymont$QMEAN.VAPOR.LC.PY * day.sec - qmean$wflxwc [m,] = mymont$QMEAN.VAPOR.WC.PY * day.sec - qmean$wflxgc [m,] = mymont$QMEAN.VAPOR.GC.PY * day.sec - qmean$runoff [m,] = ( mymont$QMEAN.RUNOFF.PY - + mymont$QMEAN.DRAINAGE.PY ) * day.sec - qmean$intercepted [m,] = ( mymont$QMEAN.INTERCEPTED.AL.PY - + mymont$QMEAN.INTERCEPTED.AW.PY ) * day.sec - qmean$wshed [m,] = ( mymont$QMEAN.WSHED.LG.PY - + mymont$QMEAN.WSHED.WG.PY ) * day.sec - qmean$evap [m,] = ( mymont$QMEAN.VAPOR.GC.PY - + mymont$QMEAN.VAPOR.WC.PY - + mymont$QMEAN.VAPOR.LC.PY ) * day.sec - qmean$transp [m,] = mymont$QMEAN.TRANSP.PY * day.sec - qmean$atm.temp [m,] = mymont$QMEAN.ATM.TEMP.PY - t00 - qmean$can.temp [m,] = mymont$QMEAN.CAN.TEMP.PY - t00 - qmean$leaf.temp [m,] = mymont$QMEAN.LEAF.TEMP.PY - t00 - qmean$leaf.water [m,] = mymont$QMEAN.LEAF.WATER.PY - qmean$wood.temp [m,] = mymont$QMEAN.WOOD.TEMP.PY - t00 - qmean$gnd.temp [m,] = mymont$QMEAN.GND.TEMP.PY - t00 - qmean$atm.shv [m,] = mymont$QMEAN.ATM.SHV.PY * kg2g - qmean$can.shv [m,] = mymont$QMEAN.CAN.SHV.PY * kg2g - qmean$gnd.shv [m,] = mymont$QMEAN.GND.SHV.PY * kg2g - qmean$atm.vpd [m,] = mymont$QMEAN.ATM.VPDEF.PY * 0.01 - qmean$can.vpd [m,] = mymont$QMEAN.CAN.VPDEF.PY * 0.01 - qmean$leaf.vpd [m,] = mymont$QMEAN.LEAF.VPDEF.PY * 0.01 - qmean$atm.co2 [m,] = mymont$QMEAN.ATM.CO2.PY - qmean$can.co2 [m,] = mymont$QMEAN.CAN.CO2.PY - qmean$atm.vels [m,] = mymont$QMEAN.ATM.VELS.PY - qmean$ustar [m,] = mymont$QMEAN.USTAR.PY - qmean$atm.prss [m,] = mymont$QMEAN.ATM.PRSS.PY * 0.01 - qmean$can.prss [m,] = mymont$QMEAN.CAN.PRSS.PY * 0.01 - qmean$sm.stress [m,] = 1. - mymont$QMEAN.FS.OPEN.PY - qmean$rain [m,] = mymont$QMEAN.PCPG.PY * day.sec - qmean$rshort [m,] = mymont$QMEAN.ATM.RSHORT.PY - qmean$rshort.beam [m,] = ( mymont$QMEAN.ATM.RSHORT.PY - - mymont$QMEAN.ATM.RSHORT.DIFF.PY ) - qmean$rshort.diff [m,] = mymont$QMEAN.ATM.RSHORT.DIFF.PY - qmean$rshort.gnd [m,] = mymont$QMEAN.RSHORT.GND.PY - qmean$rshortup [m,] = mymont$QMEAN.RSHORTUP.PY - qmean$rlong [m,] = mymont$QMEAN.ATM.RLONG.PY - qmean$rlong.gnd [m,] = mymont$QMEAN.RLONG.GND.PY - qmean$rlongup [m,] = mymont$QMEAN.RLONGUP.PY - qmean$par.tot [m,] = mymont$QMEAN.ATM.PAR.PY * Watts.2.Ein * 1.e6 - qmean$par.beam [m,] = ( mymont$QMEAN.ATM.PAR.PY - - mymont$QMEAN.ATM.PAR.DIFF.PY ) * Watts.2.Ein * 1.e6 - qmean$par.diff [m,] = mymont$QMEAN.ATM.PAR.DIFF.PY * Watts.2.Ein * 1.e6 - qmean$par.gnd [m,] = mymont$QMEAN.PAR.GND.PY * Watts.2.Ein * 1.e6 - qmean$parup [m,] = mymont$QMEAN.PARUP.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf [m,] = mymont$QMEAN.PAR.L.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf.beam[m,] = mymont$QMEAN.PAR.L.BEAM.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf.diff[m,] = mymont$QMEAN.PAR.L.DIFF.PY * Watts.2.Ein * 1.e6 - qmean$rnet [m,] = mymont$QMEAN.RNET.PY - qmean$albedo [m,] = mymont$QMEAN.ALBEDO.PY + qmean$gpp [m,] = mymont$QMEAN.GPP.PY + qmean$npp [m,] = mymont$QMEAN.NPP.PY + qmean$het.resp [m,] = mymont$QMEAN.RH.PY + qmean$fgc.resp [m,] = mymont$QMEAN.FGC.RH.PY + qmean$fsc.resp [m,] = mymont$QMEAN.FSC.RH.PY + qmean$stgc.resp [m,] = mymont$QMEAN.STGC.RH.PY + qmean$stsc.resp [m,] = mymont$QMEAN.STSC.RH.PY + qmean$msc.resp [m,] = mymont$QMEAN.MSC.RH.PY + qmean$ssc.resp [m,] = mymont$QMEAN.SSC.RH.PY + qmean$psc.resp [m,] = mymont$QMEAN.PSC.RH.PY + qmean$assim.light [m,] = mymont$QMEAN.A.LIGHT.PY + qmean$assim.rubp [m,] = mymont$QMEAN.A.RUBP.PY + qmean$assim.co2 [m,] = mymont$QMEAN.A.CO2.PY + qmean$assim.ratio [m,] = ( mymont$QMEAN.A.LIGHT.PY + / pmax(1e-6, pmin( mymont$QMEAN.A.RUBP.PY + , mymont$QMEAN.A.CO2.PY ))) + qmean$nee [m,] = ( mymont$QMEAN.CARBON.ST.PY + - mymont$QMEAN.CARBON.AC.PY ) + qmean$reco [m,] = mymont$QMEAN.PLRESP.PY + mymont$QMEAN.RH.PY + qmean$cflxca [m,] = - mymont$QMEAN.CARBON.AC.PY + qmean$cflxst [m,] = - mymont$QMEAN.CARBON.ST.PY + qmean$hflxca [m,] = - mymont$QMEAN.SENSIBLE.AC.PY + qmean$hflxlc [m,] = mymont$QMEAN.SENSIBLE.LC.PY + qmean$hflxwc [m,] = mymont$QMEAN.SENSIBLE.WC.PY + qmean$hflxgc [m,] = mymont$QMEAN.SENSIBLE.GC.PY + qmean$wflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * day.sec + qmean$qwflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * qmean.can.alvli.py + qmean$wflxlc [m,] = mymont$QMEAN.VAPOR.LC.PY * day.sec + qmean$wflxwc [m,] = mymont$QMEAN.VAPOR.WC.PY * day.sec + qmean$wflxgc [m,] = mymont$QMEAN.VAPOR.GC.PY * day.sec + qmean$runoff [m,] = ( mymont$QMEAN.RUNOFF.PY + + mymont$QMEAN.DRAINAGE.PY ) * day.sec + qmean$intercepted [m,] = ( mymont$QMEAN.INTERCEPTED.AL.PY + + mymont$QMEAN.INTERCEPTED.AW.PY ) * day.sec + qmean$wshed [m,] = ( mymont$QMEAN.WSHED.LG.PY + + mymont$QMEAN.WSHED.WG.PY ) * day.sec + qmean$evap [m,] = ( mymont$QMEAN.VAPOR.GC.PY + + mymont$QMEAN.VAPOR.WC.PY + + mymont$QMEAN.VAPOR.LC.PY ) * day.sec + qmean$transp [m,] = mymont$QMEAN.TRANSP.PY * day.sec + qmean$atm.temp [m,] = mymont$QMEAN.ATM.TEMP.PY - t00 + qmean$can.temp [m,] = mymont$QMEAN.CAN.TEMP.PY - t00 + qmean$leaf.temp [m,] = mymont$QMEAN.LEAF.TEMP.PY - t00 + qmean$leaf.water [m,] = mymont$QMEAN.LEAF.WATER.PY + qmean$leaf.water.im2[m,] = mymont$QMEAN.LEAF.WATER.IM2.PY + qmean$wood.temp [m,] = mymont$QMEAN.WOOD.TEMP.PY - t00 + qmean$gnd.temp [m,] = mymont$QMEAN.GND.TEMP.PY - t00 + qmean$atm.shv [m,] = mymont$QMEAN.ATM.SHV.PY * kg2g + qmean$can.shv [m,] = mymont$QMEAN.CAN.SHV.PY * kg2g + qmean$gnd.shv [m,] = mymont$QMEAN.GND.SHV.PY * kg2g + qmean$atm.vpd [m,] = mymont$QMEAN.ATM.VPDEF.PY * 0.01 + qmean$can.vpd [m,] = mymont$QMEAN.CAN.VPDEF.PY * 0.01 + qmean$leaf.vpd [m,] = mymont$QMEAN.LEAF.VPDEF.PY * 0.01 + qmean$atm.co2 [m,] = mymont$QMEAN.ATM.CO2.PY + qmean$can.co2 [m,] = mymont$QMEAN.CAN.CO2.PY + qmean$atm.vels [m,] = mymont$QMEAN.ATM.VELS.PY + qmean$ustar [m,] = mymont$QMEAN.USTAR.PY + qmean$atm.prss [m,] = mymont$QMEAN.ATM.PRSS.PY * 0.01 + qmean$can.prss [m,] = mymont$QMEAN.CAN.PRSS.PY * 0.01 + qmean$sm.stress [m,] = 1. - mymont$QMEAN.FS.OPEN.PY + qmean$rain [m,] = mymont$QMEAN.PCPG.PY * day.sec + qmean$rshort [m,] = mymont$QMEAN.ATM.RSHORT.PY + qmean$rshort.beam [m,] = ( mymont$QMEAN.ATM.RSHORT.PY + - mymont$QMEAN.ATM.RSHORT.DIFF.PY ) + qmean$rshort.diff [m,] = mymont$QMEAN.ATM.RSHORT.DIFF.PY + qmean$rshort.gnd [m,] = mymont$QMEAN.RSHORT.GND.PY + qmean$rshortup [m,] = mymont$QMEAN.RSHORTUP.PY + qmean$rlong [m,] = mymont$QMEAN.ATM.RLONG.PY + qmean$rlong.gnd [m,] = mymont$QMEAN.RLONG.GND.PY + qmean$rlongup [m,] = mymont$QMEAN.RLONGUP.PY + qmean$par.tot [m,] = mymont$QMEAN.ATM.PAR.PY * Watts.2.Ein * 1.e6 + qmean$par.beam [m,] = ( mymont$QMEAN.ATM.PAR.PY + - mymont$QMEAN.ATM.PAR.DIFF.PY ) * Watts.2.Ein * 1.e6 + qmean$par.diff [m,] = mymont$QMEAN.ATM.PAR.DIFF.PY * Watts.2.Ein * 1.e6 + qmean$par.gnd [m,] = mymont$QMEAN.PAR.GND.PY * Watts.2.Ein * 1.e6 + qmean$parup [m,] = mymont$QMEAN.PARUP.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf [m,] = mymont$QMEAN.PAR.L.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf.beam [m,] = mymont$QMEAN.PAR.L.BEAM.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf.diff [m,] = mymont$QMEAN.PAR.L.DIFF.PY * Watts.2.Ein * 1.e6 + qmean$rnet [m,] = mymont$QMEAN.RNET.PY + qmean$albedo [m,] = mymont$QMEAN.ALBEDO.PY if (all(c("QMEAN.ALBEDO.PAR.PY","QMEAN.ALBEDO.NIR.PY") %in% names(mymont))){ - qmean$albedo.par[m,] = mymont$QMEAN.ALBEDO.PAR.PY - qmean$albedo.nir[m,] = mymont$QMEAN.ALBEDO.NIR.PY + qmean$albedo.par [m,] = mymont$QMEAN.ALBEDO.PAR.PY + qmean$albedo.nir [m,] = mymont$QMEAN.ALBEDO.NIR.PY }else{ - qmean$albedo.par[m,] = ifelse( mymont$QMEAN.ATM.PAR.PY > 0.5 - , mymont$QMEAN.PARUP.PY / mymont$QMEAN.ATM.PAR.PY - , mymont$QMEAN.ALBEDO.PY - )#end ifelse - qmean$albedo.nir[m,] = ifelse( mymont$QMEAN.ATM.NIR.PY > 0.5 - , mymont$QMEAN.NIRUP.PY / mymont$QMEAN.ATM.NIR.PY - , mymont$QMEAN.ALBEDO.PY - )#end ifelse + qmean$albedo.par [m,] = ifelse( mymont$QMEAN.ATM.PAR.PY > 0.5 + , mymont$QMEAN.PARUP.PY / mymont$QMEAN.ATM.PAR.PY + , mymont$QMEAN.ALBEDO.PY + )#end ifelse + qmean$albedo.nir [m,] = ifelse( mymont$QMEAN.ATM.NIR.PY > 0.5 + , mymont$QMEAN.NIRUP.PY / mymont$QMEAN.ATM.NIR.PY + , mymont$QMEAN.ALBEDO.PY + )#end ifelse }#end if - qmean$rlong.albedo [m,] = mymont$QMEAN.RLONG.ALBEDO.PY - qmean$leaf.gbw [m,] = mymont$QMEAN.LEAF.GBW.PY * day.sec - qmean$leaf.gsw [m,] = mymont$QMEAN.LEAF.GSW.PY * day.sec - qmean$wood.gbw [m,] = mymont$QMEAN.WOOD.GBW.PY * day.sec - qmean$rk4step [m,] = mymont$QMEAN.RK4STEP.PY - qmean$soil.water [m,,] = mymont$QMEAN.SOIL.WATER.PY - qmean$soil.temp [m,,] = mymont$QMEAN.SOIL.TEMP.PY - t00 - qmean$soil.mstpot [m,,] = - mymont$QMEAN.SOIL.MSTPOT.PY * grav * wdns * 1.e-6 + qmean$rlong.albedo [m,] = mymont$QMEAN.RLONG.ALBEDO.PY + qmean$leaf.gbw [m,] = mymont$QMEAN.LEAF.GBW.PY * day.sec + qmean$leaf.gsw [m,] = mymont$QMEAN.LEAF.GSW.PY * day.sec + qmean$wood.gbw [m,] = mymont$QMEAN.WOOD.GBW.PY * day.sec + qmean$rk4step [m,] = mymont$QMEAN.RK4STEP.PY + #------------------------------------------------------------------------------------# + + + + #------ For soils, we must account for different soil depths. -----------------------# + for (h in sequence(ndcycle)){ + odim = dim(mymont$QMEAN.SOIL.TEMP.PA)[-2] + soil.temp.pa = mymont$QMEAN.SOIL.TEMP.PA [,h,] - t00 + soil.water.pa = mymont$QMEAN.SOIL.WATER.PA[,h,] + soil.temp.pa = array(soil.temp.pa ,dim=odim) + soil.water.pa = array(soil.water.pa,dim=odim) + soil.mstpot.pa = soil.water.pa * (-1.) * grav * wdns * 1.e-6 + soil.wetness.pa = ( ( soil.water.pa - soilcp.pa) + / ( soilpo.pa - soilcp.pa) ) + + + #----- Populate data structure by hour of the day. -------------------------------# + soil.temp.lyr = apply( X = soil.temp.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.water.lyr = apply( X = soil.water.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.mstpot.lyr = apply( X = soil.mstpot.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.wetness.lyr = apply( X = soil.wetness.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + #---------------------------------------------------------------------------------# + + + #----- Copy results for the hour. ------------------------------------------------# + qmean$soil.temp [m,h,] = soil.temp.lyr + qmean$soil.water [m,h,] = soil.water.lyr + qmean$soil.mstpot [m,h,] = soil.mstpot.lyr + qmean$soil.temp.top [m,h ] = sum(soil.temp.lyr * tt.wgtz) + qmean$soil.water.top [m,h ] = sum(soil.water.lyr * tm.wgtz) * wdns * dz.msttop + qmean$soil.water.bot [m,h ] = sum(soil.water.lyr * bm.wgtz) * wdns * dz.mstbot + qmean$soil.wetness.top[m,h ] = sum(soil.wetness.lyr * tm.wgtz) + qmean$soil.wetness.bot[m,h ] = sum(soil.wetness.lyr * bm.wgtz) + #---------------------------------------------------------------------------------# + }#end for (h in sequence(ndcycle)) #------------------------------------------------------------------------------------# @@ -751,36 +931,6 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# - - #------------------------------------------------------------------------------------# - # Find average soil temperature and water content at specific layers. # - #------------------------------------------------------------------------------------# - soil.temp.lyr = mymont$QMEAN.SOIL.TEMP.PY [1,,] - t00 - soil.water.lyr = mymont$QMEAN.SOIL.WATER.PY[1,,] - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) - qmean$soil.temp.top [m,] = rowSums(soil.temp.lyr * q.tt.wgtz) - qmean$soil.water.top [m,] = rowSums(soil.water.lyr * q.tm.wgtz) * wdns * dz.msttop - qmean$soil.water.bot [m,] = rowSums(soil.water.lyr * q.bm.wgtz) * wdns * dz.mstbot - qmean$soil.wetness.top[m,] = rowSums(soil.wetness.lyr * q.tm.wgtz) - qmean$soil.wetness.bot[m,] = rowSums(soil.wetness.lyr * q.bm.wgtz) - #------------------------------------------------------------------------------------# - - - #---- Read in the site-level area. --------------------------------------------------# - areasi = mymont$AREA.SI - npatches = mymont$SIPA.N - #------------------------------------------------------------------------------------# - - - #----- Read a few patch-level variables. --------------------------------------------# - areapa = mymont$AREA * rep(areasi,times=npatches) - areapa = areapa / sum(areapa) - ipa = sequence(mymont$NPATCHES.GLOBAL) - lupa = mymont$DIST.TYPE - agepa = mymont$AGE - #------------------------------------------------------------------------------------# - - #------------------------------------------------------------------------------------# # Get the water deficit, and the estimate using Malhi's ET (100mm/month). # #------------------------------------------------------------------------------------# @@ -819,7 +969,10 @@ read.q.files <<- function( datum # Get the total number of cohorts. # #------------------------------------------------------------------------------------# ncohorts = mymont$PACO.N - ipaconow = rep(sequence(mymont$NPATCHES.GLOBAL),times=mymont$PACO.N) + isiconow = rep( x = isipa , times = mymont$PACO.N) + lslconow = rep( x = lslpa , times = mymont$PACO.N) + ntextconow = rep( x = ntextpa, times = mymont$PACO.N) + ipaconow = rep( x = ipa , times = mymont$PACO.N) q.ipaconow = matrix( data = ipaconow , nrow = mymont$NCOHORTS.GLOBAL , ncol = mymont$NDCYC @@ -922,6 +1075,7 @@ read.q.files <<- function( datum )#end size2ca )#end pmin taiconow = laiconow + waiconow + agvolumeconow = agbconow / wood.densconow * 1.e-3 #------ Auxiliary variables for mean diurnal cycle. ------------------------------# q.pftconow = matrix( data = pftconow , nrow = mymont$NCOHORTS.GLOBAL @@ -1102,10 +1256,10 @@ read.q.files <<- function( datum #----- Flags to tell whether leaves and branchwood were resolvable. --------------# - leaf.okconow = mymont$MMEAN.LEAF.HCAP.CO %>=% pft$veg.hcap.min[pftconow ] - wood.okconow = mymont$MMEAN.WOOD.HCAP.CO %>=% pft$veg.hcap.min[pftconow ] - q.leaf.okconow = mymont$QMEAN.LEAF.HCAP.CO %>=% pft$veg.hcap.min[q.pftconow] - q.wood.okconow = mymont$QMEAN.WOOD.HCAP.CO %>=% pft$veg.hcap.min[q.pftconow] + leaf.okconow = mymont$MMEAN.LEAF.HCAP.CO %ge% pft$veg.hcap.min[pftconow ] + wood.okconow = mymont$MMEAN.WOOD.HCAP.CO %ge% pft$veg.hcap.min[pftconow ] + q.leaf.okconow = mymont$QMEAN.LEAF.HCAP.CO %ge% pft$veg.hcap.min[q.pftconow] + q.wood.okconow = mymont$QMEAN.WOOD.HCAP.CO %ge% pft$veg.hcap.min[q.pftconow] #---------------------------------------------------------------------------------# @@ -1300,6 +1454,13 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# + + #----- Leaf water potential. -----------------------------------------------------# + dmin.leaf.psiconow = mymont$MMEAN.DMIN.LEAF.PSI.CO * wdns * grav * 1.e-6 + dmax.leaf.psiconow = mymont$MMEAN.DMAX.LEAF.PSI.CO * wdns * grav * 1.e-6 + #---------------------------------------------------------------------------------# + + #----- Find the net radiation for leaves (in m2/leaf!). --------------------------# par.mult = Watts.2.Ein * 1.e6 leaf.parconow = ifelse( leaf.okconow & showconow @@ -1358,39 +1519,47 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# # Leaf/wood thermal properties. # #---------------------------------------------------------------------------------# - leaf.waterconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.WATER.CO / laiconow - , no = NA - )#end ifelse - leaf.tempconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.TEMP.CO - t00 - , no = NA - )#end ifelse - wood.tempconow = ifelse( test = wood.okconow & showconow - , yes = mymont$MMEAN.WOOD.TEMP.CO - t00 - , no = NA - )#end ifelse - leaf.vpdconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.VPDEF.CO * 0.01 - , no = NA - )#end ifelse - #----- Mean diurnal cycle. -------------------------------------------------------# - q.leaf.waterconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.WATER.CO / q.laiconow + leaf.waterconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.WATER.CO / laiconow + , no = NA + )#end ifelse + leaf.water.im2conow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.WATER.IM2.CO / laiconow , no = NA )#end ifelse - q.leaf.tempconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.TEMP.CO - t00 + leaf.tempconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.TEMP.CO - t00 , no = NA )#end ifelse - q.wood.tempconow = ifelse( test = q.wood.okconow & q.showconow - , yes = mymont$QMEAN.WOOD.TEMP.CO - t00 + wood.tempconow = ifelse( test = wood.okconow & showconow + , yes = mymont$MMEAN.WOOD.TEMP.CO - t00 , no = NA )#end ifelse - q.leaf.vpdconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.VPDEF.CO * 0.01 + leaf.vpdconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.VPDEF.CO * 0.01 , no = NA )#end ifelse + #----- Mean diurnal cycle. -------------------------------------------------------# + q.leaf.waterconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.WATER.CO / q.laiconow + , no = NA + )#end ifelse + q.leaf.water.im2conow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.WATER.IM2.CO / q.laiconow + , no = NA + )#end ifelse + q.leaf.tempconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.TEMP.CO - t00 + , no = NA + )#end ifelse + q.wood.tempconow = ifelse( test = q.wood.okconow & q.showconow + , yes = mymont$QMEAN.WOOD.TEMP.CO - t00 + , no = NA + )#end ifelse + q.leaf.vpdconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.VPDEF.CO * 0.01 + , no = NA + )#end ifelse #---------------------------------------------------------------------------------# @@ -1453,6 +1622,17 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # Find fire lethality rate. # + #---------------------------------------------------------------------------------# + fire.lethalconow = mymont$MMEAN.FIRE.LETHAL.RATE.CO + #---------------------------------------------------------------------------------# + + + + #------ Find the AGB and basal area of the previous month. -----------------------# agbcolmon = agbconow * exp(-agb.growthconow/12.) bacolmon = baconow * exp(-bsa.growthconow/12.) @@ -1501,24 +1681,28 @@ read.q.files <<- function( datum phap.leaf.gsaconow = NA + pftconow phap.can.shv.conow = NA + pftconow }else if (one.cohort){ - phap.lparconow = mean(mymont$QMEAN.PAR.L.CO [phap]) - phap.ltempconow = mean(mymont$QMEAN.LEAF.TEMP.CO [phap]) - phap.lwaterconow = mean(mymont$QMEAN.LEAF.WATER.CO[phap]) - phap.lvpdconow = mean(mymont$QMEAN.LEAF.VPDEF.CO[phap]) - phap.fs.openconow = mean(mymont$QMEAN.FS.OPEN.CO [phap]) - phap.lpsiconow = mean(mymont$QMEAN.TRANSP.CO [phap]) - phap.leaf.gbaconow = mean(mymont$QMEAN.LEAF.GBW.CO [phap]) - phap.leaf.gsaconow = mean(mymont$QMEAN.LEAF.GSW.CO [phap]) - phap.can.shv.conow = rep(mean(mymont$QMEAN.CAN.SHV.PA[phap]),times=ncohorts) + phap.lparconow = mean(mymont$QMEAN.PAR.L.CO [phap]) + phap.ltempconow = mean(mymont$QMEAN.LEAF.TEMP.CO [phap]) + phap.lwaterconow = mean(mymont$QMEAN.LEAF.WATER.CO [phap]) + phap.lwater.im2conow = mean(mymont$QMEAN.LEAF.WATER.IM2.CO [phap]) + phap.lvpdconow = mean(mymont$QMEAN.LEAF.VPDEF.CO [phap]) + phap.fs.openconow = mean(mymont$QMEAN.FS.OPEN.CO [phap]) + phap.lpsiconow = mean(mymont$QMEAN.TRANSP.CO [phap]) + phap.leaf.gbaconow = mean(mymont$QMEAN.LEAF.GBW.CO [phap]) + phap.leaf.gsaconow = mean(mymont$QMEAN.LEAF.GSW.CO [phap]) + phap.can.shv.conow = rep( x = mean(mymont$QMEAN.CAN.SHV.PA[phap]) + , times = ncohorts + )#end rep }else{ - phap.lparconow = rowMeans(mymont$QMEAN.PAR.L.CO [,phap]) - phap.ltempconow = rowMeans(mymont$QMEAN.LEAF.TEMP.CO [,phap]) - phap.lwaterconow = rowMeans(mymont$QMEAN.LEAF.WATER.CO[,phap]) - phap.lvpdconow = rowMeans(mymont$QMEAN.LEAF.VPDEF.CO[,phap]) - phap.fs.openconow = rowMeans(mymont$QMEAN.FS.OPEN.CO [,phap]) - phap.lpsiconow = rowMeans(mymont$QMEAN.TRANSP.CO [,phap]) - phap.leaf.gbaconow = rowMeans(mymont$QMEAN.LEAF.GBW.CO [,phap]) - phap.leaf.gsaconow = rowMeans(mymont$QMEAN.LEAF.GSW.CO [,phap]) + phap.lparconow = rowMeans(mymont$QMEAN.PAR.L.CO [,phap]) + phap.ltempconow = rowMeans(mymont$QMEAN.LEAF.TEMP.CO [,phap]) + phap.lwaterconow = rowMeans(mymont$QMEAN.LEAF.WATER.CO [,phap]) + phap.lwater.im2conow = rowMeans(mymont$QMEAN.LEAF.WATER.IM2.CO[,phap]) + phap.lvpdconow = rowMeans(mymont$QMEAN.LEAF.VPDEF.CO [,phap]) + phap.fs.openconow = rowMeans(mymont$QMEAN.FS.OPEN.CO [,phap]) + phap.lpsiconow = rowMeans(mymont$QMEAN.TRANSP.CO [,phap]) + phap.leaf.gbaconow = rowMeans(mymont$QMEAN.LEAF.GBW.CO [,phap]) + phap.leaf.gsaconow = rowMeans(mymont$QMEAN.LEAF.GSW.CO [,phap]) if (one.patch){ phap.can.shv.conow = rep( x = mean(mymont$QMEAN.CAN.SHV.PA[phap]) , times = ncohorts @@ -1585,132 +1769,140 @@ read.q.files <<- function( datum }else{ #----- Make everything NA. -------------------------------------------------------# - ipaconow = NA - icoconow = NA - areaconow = NA - luconow = NA - dbhconow = NA - dbhcut = NA - dbhlevs = NA - dbhfac = NA - dbhconow.1ago = NA - dbhcut.1ago = NA - dbhlevs.1ago = NA - dbhfac.1ago = NA - dbhconow.lmon = NA - dbhcut.lmon = NA - dbhlevs.lmon = NA - dbhfac.lmon = NA - ageconow = NA - pftconow = NA - nplantconow = NA - heightconow = NA - wood.densconow = NA - vm0conow = NA - llspanconow = NA - slaconow = NA - baconow = NA - agbconow = NA - biomassconow = NA - laiconow = NA - waiconow = NA - taiconow = NA - gppconow = NA - leaf.respconow = NA - stem.respconow = NA - root.respconow = NA - froot.respconow = NA - croot.respconow = NA - aerobic.respconow = NA - growth.respconow = NA - storage.respconow = NA - plant.respconow = NA - assim.lightconow = NA - assim.rubpconow = NA - assim.co2conow = NA - assim.ratioconow = NA - nppconow = NA - cbaconow = NA - cbamaxconow = NA - cbalightconow = NA - cbamoistconow = NA - cbarelconow = NA - mcostconow = NA - ldropconow = NA - dcbadtconow = NA - sm.stressconow = NA - lightconow = NA - light.beamconow = NA - light.diffconow = NA - thbarkconow = NA - baliveconow = NA - bdeadconow = NA - btimberconow = NA - bleafconow = NA - bsapwoodconow = NA - bfrootconow = NA - bcrootconow = NA - brootconow = NA - bstemconow = NA - bbarkconow = NA - bstorageconow = NA - bseedsconow = NA - byieldconow = NA - hflxlcconow = NA - wflxlcconow = NA - transpconow = NA - i.hflxlcconow = NA - i.wflxlcconow = NA - i.transpconow = NA - wueconow = NA - cueconow = NA - ecueconow = NA - etueconow = NA - leaf.tempconow = NA - leaf.waterconow = NA - wood.tempconow = NA - leaf.vpdconow = NA - demandconow = NA - supplyconow = NA - mortconow = NA - ncbmortconow = NA - hydmortconow = NA - dimortconow = NA - recruitconow = NA - growthconow = NA - agb.growthconow = NA - bsa.growthconow = NA - leaf.gbwconow = NA - leaf.gswconow = NA - wood.gbwconow = NA - f.gppconow = NA - f.plant.respconow = NA - f.nppconow = NA - f.mcoconow = NA - f.dcbadtconow = NA - f.cbaconow = NA - f.bstorageconow = NA - f.bleafconow = NA - f.bstemconow = NA - f.brootconow = NA - f.bbarkconow = NA - f.bseedsconow = NA - leaf.parconow = NA - leaf.par.beamconow = NA - leaf.par.diffconow = NA - leaf.rshortconow = NA - leaf.rlongconow = NA - leaf.gppconow = NA - rueconow = NA - opencanconow = NA - useconow = NA - phap.lparconow = NA - phap.ltempconow = NA - phap.lwaterconow = NA - phap.lvpdconow = NA - phap.smsconow = NA - phap.lgbwconow = NA - phap.lgswconow = NA + isiconow = NA_integer_ + lslconow = NA_integer_ + ntextconow = NA_integer_ + ipaconow = NA_integer_ + icoconow = NA_integer_ + areaconow = NA_real_ + luconow = NA_integer_ + dbhconow = NA_real_ + dbhcut = NA_real_ + dbhlevs = NA_real_ + dbhfac = NA_real_ + dbhconow.1ago = NA_real_ + dbhcut.1ago = NA_real_ + dbhlevs.1ago = NA_real_ + dbhfac.1ago = NA_real_ + dbhconow.lmon = NA_real_ + dbhcut.lmon = NA_real_ + dbhlevs.lmon = NA_real_ + dbhfac.lmon = NA_real_ + ageconow = NA_real_ + pftconow = NA_integer_ + nplantconow = NA_real_ + heightconow = NA_real_ + wood.densconow = NA_real_ + vm0conow = NA_real_ + llspanconow = NA_real_ + slaconow = NA_real_ + baconow = NA_real_ + agbconow = NA_real_ + biomassconow = NA_real_ + laiconow = NA_real_ + waiconow = NA_real_ + taiconow = NA_real_ + agvolumeconow = NA_real_ + gppconow = NA_real_ + leaf.respconow = NA_real_ + stem.respconow = NA_real_ + root.respconow = NA_real_ + froot.respconow = NA_real_ + croot.respconow = NA_real_ + aerobic.respconow = NA_real_ + growth.respconow = NA_real_ + storage.respconow = NA_real_ + plant.respconow = NA_real_ + assim.lightconow = NA_real_ + assim.rubpconow = NA_real_ + assim.co2conow = NA_real_ + assim.ratioconow = NA_real_ + nppconow = NA_real_ + cbaconow = NA_real_ + cbamaxconow = NA_real_ + cbalightconow = NA_real_ + cbamoistconow = NA_real_ + cbarelconow = NA_real_ + mcostconow = NA_real_ + ldropconow = NA_real_ + dcbadtconow = NA_real_ + sm.stressconow = NA_real_ + lightconow = NA_real_ + light.beamconow = NA_real_ + light.diffconow = NA_real_ + thbarkconow = NA_real_ + baliveconow = NA_real_ + bdeadconow = NA_real_ + btimberconow = NA_real_ + bleafconow = NA_real_ + bsapwoodconow = NA_real_ + bfrootconow = NA_real_ + bcrootconow = NA_real_ + brootconow = NA_real_ + bstemconow = NA_real_ + bbarkconow = NA_real_ + bstorageconow = NA_real_ + bseedsconow = NA_real_ + byieldconow = NA_real_ + hflxlcconow = NA_real_ + wflxlcconow = NA_real_ + transpconow = NA_real_ + i.hflxlcconow = NA_real_ + i.wflxlcconow = NA_real_ + i.transpconow = NA_real_ + wueconow = NA_real_ + cueconow = NA_real_ + ecueconow = NA_real_ + etueconow = NA_real_ + leaf.tempconow = NA_real_ + leaf.waterconow = NA_real_ + leaf.water.im2conow = NA_real_ + wood.tempconow = NA_real_ + leaf.vpdconow = NA_real_ + demandconow = NA_real_ + supplyconow = NA_real_ + mortconow = NA_real_ + ncbmortconow = NA_real_ + hydmortconow = NA_real_ + dimortconow = NA_real_ + fire.lethalconow = NA_real_ + recruitconow = NA_real_ + growthconow = NA_real_ + agb.growthconow = NA_real_ + bsa.growthconow = NA_real_ + leaf.gbwconow = NA_real_ + leaf.gswconow = NA_real_ + wood.gbwconow = NA_real_ + f.gppconow = NA_real_ + f.plant.respconow = NA_real_ + f.nppconow = NA_real_ + f.mcoconow = NA_real_ + f.dcbadtconow = NA_real_ + f.cbaconow = NA_real_ + f.bstorageconow = NA_real_ + f.bleafconow = NA_real_ + f.bstemconow = NA_real_ + f.brootconow = NA_real_ + f.bbarkconow = NA_real_ + f.bseedsconow = NA_real_ + leaf.parconow = NA_real_ + leaf.par.beamconow = NA_real_ + leaf.par.diffconow = NA_real_ + leaf.rshortconow = NA_real_ + leaf.rlongconow = NA_real_ + leaf.gppconow = NA_real_ + dmin.leaf.psiconow = NA_real_ + dmax.leaf.psiconow = NA_real_ + rueconow = NA_real_ + opencanconow = NA_real_ + useconow = NA_real_ + phap.lparconow = NA_real_ + phap.ltempconow = NA_real_ + phap.lwaterconow = NA_real_ + phap.lvpdconow = NA_real_ + phap.smsconow = NA_real_ + phap.lgbwconow = NA_real_ + phap.lgswconow = NA_real_ }#end if #------------------------------------------------------------------------------------# #====================================================================================# @@ -1731,6 +1923,9 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# plab = paste0("y",sprintf("%4.4i",thisyear),"m",sprintf("%2.2i",thismonth)) #----- Bind the current patches. ----------------------------------------------------# + patch$isi [[plab]] = isipa + patch$lsl [[plab]] = lslpa + patch$ntext [[plab]] = ntextpa patch$ipa [[plab]] = ipa patch$age [[plab]] = agepa patch$area [[plab]] = areapa @@ -1769,18 +1964,25 @@ read.q.files <<- function( datum patch$rshort.gnd [[plab]] = mymont$MMEAN.RSHORT.GND.PA patch$par.gnd [[plab]] = mymont$MMEAN.PAR.GND.PA * Watts.2.Ein * 1e6 patch$rnet [[plab]] = mymont$MMEAN.RNET.PA + patch$sfcw.temp [[plab]] = mymont$MMEAN.SFCW.TEMP.PA - t00 + patch$sfcw.fliq [[plab]] = mymont$MMEAN.SFCW.FLIQ.PA + patch$sfcw.mass [[plab]] = mymont$MMEAN.SFCW.MASS.PA + patch$sfcw.depth [[plab]] = mymont$MMEAN.SFCW.DEPTH.PA + patch$sfcw.cover [[plab]] = mymont$MMEAN.SNOWFAC.PA #----- Find soil averages. ----------------------------------------------------------# - soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PA - t00 - soil.water.lyr = mymont$MMEAN.SOIL.WATER.PA - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) - p.tt.wgtz = matrix(tt.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - p.tm.wgtz = matrix(tm.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - p.bm.wgtz = matrix(bm.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - patch$soil.temp.top [[plab]] = rowSums(soil.temp.lyr * p.tt.wgtz) - patch$soil.water.top [[plab]] = rowSums(soil.water.lyr * p.tm.wgtz) * wdns*dz.msttop - patch$soil.water.bot [[plab]] = rowSums(soil.water.lyr * p.bm.wgtz) * wdns*dz.mstbot - patch$soil.wetness.top[[plab]] = rowSums(soil.water.lyr * p.tm.wgtz) - patch$soil.wetness.bot[[plab]] = rowSums(soil.water.lyr * p.bm.wgtz) + soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PA * soil.mask - t00 + soil.water.lyr = mymont$MMEAN.SOIL.WATER.PA * soil.mask + soil.wetness.lyr = ( (soil.water.lyr - soilcp.pa) + / (soilpo.pa - soilcp.pa) ) * soil.mask + patch$soil.temp.top [[plab]] = rowSums(soil.temp.lyr * p.tt.wgtz,na.rm=TRUE) + patch$soil.water.top [[plab]] = ( rowSums(soil.water.lyr * p.tm.wgtz,na.rm=TRUE) + * wdns*dz.msttop + )#end soil.water.top + patch$soil.water.bot [[plab]] = ( rowSums(soil.water.lyr * p.bm.wgtz,na.rm=TRUE) + * wdns*dz.mstbot + )#end soil.water.bot + patch$soil.wetness.top[[plab]] = rowSums(soil.water.lyr * p.tm.wgtz,na.rm=TRUE) + patch$soil.wetness.bot[[plab]] = rowSums(soil.water.lyr * p.bm.wgtz,na.rm=TRUE) #----- Bind the current mean diurnal cycle patch. -----------------------------------# qpatch$rk4step [[plab]] = mymont$QMEAN.RK4STEP.PA qpatch$nep [[plab]] = mymont$QMEAN.NEP.PA @@ -1823,92 +2025,122 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Initialise patch-level properties that are derived from cohort-level. # #------------------------------------------------------------------------------------# - patch$lai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$agb [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$ba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$nplant [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wood.dens [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$vm0 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$llspan [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$sla [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$can.depth [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$can.area [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$sm.stress [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 - patch$leaf.water [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$leaf.vpd [[plab]] = mymont$MMEAN.CAN.VPDEF.PA * 0.01 - patch$wood.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 - patch$par.leaf [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$par.leaf.beam [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$par.leaf.diff [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$phap.lpar [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.ltemp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lwater [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lvpd [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.sms [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lgbw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lgsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.gpp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.gsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par.beam [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par.diff [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.light [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.rubp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.co2 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$gpp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$npp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$cba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$plant.resp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$hflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$hflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$transp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$soil.resp [[plab]] = mymont$MMEAN.RH.PA - patch$fast.grnd.c [[plab]] = mymont$MMEAN.FAST.GRND.C.PA - patch$fast.soil.c [[plab]] = mymont$MMEAN.FAST.SOIL.C.PA - patch$struct.grnd.c [[plab]] = mymont$MMEAN.STRUCT.GRND.C.PA - patch$struct.soil.c [[plab]] = mymont$MMEAN.STRUCT.SOIL.C.PA - patch$microbe.soil.c[[plab]] = mymont$MMEAN.MICROBE.SOIL.C.PA - patch$slow.soil.c [[plab]] = mymont$MMEAN.SLOW.SOIL.C.PA - patch$passive.soil.c[[plab]] = mymont$MMEAN.PASSIVE.SOIL.C.PA - patch$fgc.in [[plab]] = mymont$MMEAN.FGC.IN.PA - patch$fsc.in [[plab]] = mymont$MMEAN.FSC.IN.PA - patch$stgc.in [[plab]] = mymont$MMEAN.STGC.IN.PA - patch$stsc.in [[plab]] = mymont$MMEAN.STSC.IN.PA - patch$soil.temp [[plab]] = mymont$MMEAN.SOIL.TEMP.PA - t00 - patch$soil.water [[plab]] = mymont$MMEAN.SOIL.WATER.PA - patch$soil.mstpot [[plab]] = - mymont$MMEAN.SOIL.MSTPOT.PA * grav * wdns * 1.e-6 + patch$lai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$agb [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$ba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$nplant [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wood.dens [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$vm0 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$llspan [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$sla [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$can.depth [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$can.area [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$sm.stress [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 + patch$leaf.water [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$leaf.water.im2 [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$leaf.vpd [[plab]] = mymont$MMEAN.CAN.VPDEF.PA * 0.01 + patch$wood.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 + patch$par.leaf [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$par.leaf.beam [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$par.leaf.diff [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$phap.lpar [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.ltemp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lwater [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lvpd [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.sms [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lgbw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lgsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.gpp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.gsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dmin.leaf.psi [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dmax.leaf.psi [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par.beam [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par.diff [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.light [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.rubp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.co2 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$gpp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$npp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$cba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$plant.resp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$hflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$hflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$transp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$soil.resp [[plab]] = mymont$MMEAN.RH.PA + patch$fast.grnd.c [[plab]] = mymont$MMEAN.FAST.GRND.C.PA + patch$fast.soil.c [[plab]] = mymont$MMEAN.FAST.SOIL.C.PA + patch$struct.grnd.c [[plab]] = mymont$MMEAN.STRUCT.GRND.C.PA + patch$struct.soil.c [[plab]] = mymont$MMEAN.STRUCT.SOIL.C.PA + patch$microbe.soil.c [[plab]] = mymont$MMEAN.MICROBE.SOIL.C.PA + patch$slow.soil.c [[plab]] = mymont$MMEAN.SLOW.SOIL.C.PA + patch$passive.soil.c [[plab]] = mymont$MMEAN.PASSIVE.SOIL.C.PA + patch$fgc.in [[plab]] = mymont$MMEAN.FGC.IN.PA + patch$fsc.in [[plab]] = mymont$MMEAN.FSC.IN.PA + patch$stgc.in [[plab]] = mymont$MMEAN.STGC.IN.PA + patch$stsc.in [[plab]] = mymont$MMEAN.STSC.IN.PA + patch$soil.temp [[plab]] = mymont$MMEAN.SOIL.TEMP.PA - t00 + patch$soil.water [[plab]] = mymont$MMEAN.SOIL.WATER.PA + patch$soil.mstpot [[plab]] = - mymont$MMEAN.SOIL.MSTPOT.PA * grav * wdns * 1.e-6 + #------ Demographic rates. ----------------------------------------------------------# + patch$growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$fire.lethal [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) #------ Mean diurnal cycle. ---------------------------------------------------------# zero.qpatch = matrix(data=0., nrow=mymont$NPATCHES.GLOBAL,ncol=mymont$NDCYC) na.qpatch = matrix(data=NA, nrow=mymont$NPATCHES.GLOBAL,ncol=mymont$NDCYC) - qpatch$sm.stress [[plab]] = na.qpatch - qpatch$leaf.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 - qpatch$leaf.water [[plab]] = zero.qpatch - qpatch$leaf.vpd [[plab]] = mymont$QMEAN.CAN.VPDEF.PA * 0.01 - qpatch$wood.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 - qpatch$par.leaf [[plab]] = zero.qpatch - qpatch$par.leaf.beam[[plab]] = zero.qpatch - qpatch$par.leaf.diff[[plab]] = zero.qpatch - qpatch$leaf.gpp [[plab]] = na.qpatch - qpatch$leaf.gsw [[plab]] = na.qpatch - qpatch$leaf.par [[plab]] = na.qpatch - qpatch$leaf.par.beam[[plab]] = na.qpatch - qpatch$leaf.par.diff[[plab]] = na.qpatch - qpatch$assim.light [[plab]] = na.qpatch - qpatch$assim.rubp [[plab]] = na.qpatch - qpatch$assim.co2 [[plab]] = na.qpatch - qpatch$gpp [[plab]] = zero.qpatch - qpatch$npp [[plab]] = zero.qpatch - qpatch$plant.resp [[plab]] = zero.qpatch - qpatch$hflxlc [[plab]] = zero.qpatch - qpatch$hflxwc [[plab]] = zero.qpatch - qpatch$wflxlc [[plab]] = zero.qpatch - qpatch$wflxwc [[plab]] = zero.qpatch - qpatch$transp [[plab]] = zero.qpatch - qpatch$soil.resp [[plab]] = mymont$QMEAN.RH.PA + qpatch$sm.stress [[plab]] = na.qpatch + qpatch$leaf.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 + qpatch$leaf.water [[plab]] = zero.qpatch + qpatch$leaf.water.im2[[plab]] = zero.qpatch + qpatch$leaf.vpd [[plab]] = mymont$QMEAN.CAN.VPDEF.PA * 0.01 + qpatch$wood.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 + qpatch$par.leaf [[plab]] = zero.qpatch + qpatch$par.leaf.beam [[plab]] = zero.qpatch + qpatch$par.leaf.diff [[plab]] = zero.qpatch + qpatch$leaf.gpp [[plab]] = na.qpatch + qpatch$leaf.gsw [[plab]] = na.qpatch + qpatch$leaf.par [[plab]] = na.qpatch + qpatch$leaf.par.beam [[plab]] = na.qpatch + qpatch$leaf.par.diff [[plab]] = na.qpatch + qpatch$assim.light [[plab]] = na.qpatch + qpatch$assim.rubp [[plab]] = na.qpatch + qpatch$assim.co2 [[plab]] = na.qpatch + qpatch$gpp [[plab]] = zero.qpatch + qpatch$npp [[plab]] = zero.qpatch + qpatch$plant.resp [[plab]] = zero.qpatch + qpatch$hflxlc [[plab]] = zero.qpatch + qpatch$hflxwc [[plab]] = zero.qpatch + qpatch$wflxlc [[plab]] = zero.qpatch + qpatch$wflxwc [[plab]] = zero.qpatch + qpatch$transp [[plab]] = zero.qpatch + qpatch$soil.resp [[plab]] = mymont$QMEAN.RH.PA #------------------------------------------------------------------------------------# @@ -1918,54 +2150,63 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# #----- Find some auxiliary patch-level properties. -------------------------------# - nplant.pa = tapply( X = mymont$NPLANT * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - lai.pa = tapply( X = mymont$MMEAN.LAI.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wai.pa = tapply( X = mymont$WAI.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.energy.pa = tapply( X = mymont$MMEAN.LEAF.ENERGY.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.water.pa = tapply( X = mymont$MMEAN.LEAF.WATER.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.hcap.pa = tapply( X = mymont$MMEAN.LEAF.HCAP.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.pa = tapply( X = mymont$MMEAN.PAR.L.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.beam.pa = tapply( X = mymont$MMEAN.PAR.L.BEAM.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.diff.pa = tapply( X = mymont$MMEAN.PAR.L.DIFF.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.energy.pa = tapply( X = mymont$MMEAN.WOOD.ENERGY.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.water.pa = tapply( X = mymont$MMEAN.WOOD.WATER.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.hcap.pa = tapply( X = mymont$MMEAN.WOOD.HCAP.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply + nplant.pa = tapply( X = mymont$NPLANT * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + lai.pa = tapply( X = mymont$MMEAN.LAI.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wai.pa = tapply( X = mymont$WAI.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + + leaf.energy.pa = tapply( X = mymont$MMEAN.LEAF.ENERGY.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.water.pa = tapply( X = mymont$MMEAN.LEAF.WATER.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.water.im2.pa = tapply( X = mymont$MMEAN.LEAF.WATER.IM2.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.hcap.pa = tapply( X = mymont$MMEAN.LEAF.HCAP.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.pa = tapply( X = mymont$MMEAN.PAR.L.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.beam.pa = tapply( X = mymont$MMEAN.PAR.L.BEAM.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.diff.pa = tapply( X = mymont$MMEAN.PAR.L.DIFF.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.energy.pa = tapply( X = mymont$MMEAN.WOOD.ENERGY.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.water.pa = tapply( X = mymont$MMEAN.WOOD.WATER.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.water.im2.pa = tapply( X = mymont$MMEAN.WOOD.WATER.IM2.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.hcap.pa = tapply( X = mymont$MMEAN.WOOD.HCAP.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply #----- Make root respiration extensive. ------------------------------------------# root.resp.pa = tapply( X = root.respconow*nplantconow , INDEX = ipaconow @@ -2002,18 +2243,21 @@ read.q.files <<- function( datum #----- Find the temperature and liquid fraction of leaf and wood. ----------------# - leaf.empty = leaf.hcap.pa == 0 - wood.empty = wood.hcap.pa == 0 - leaf.temp.pa = uextcm2tl( uext = leaf.energy.pa - , wmass = leaf.water.pa - , dryhcap = leaf.hcap.pa )$temp - t00 - wood.temp.pa = uextcm2tl( uext = wood.energy.pa - , wmass = wood.water.pa - , dryhcap = wood.hcap.pa )$temp - t00 - leaf.water.pa = leaf.water.pa / lai.pa - leaf.temp.pa [leaf.empty] = NA - leaf.water.pa[leaf.empty] = NA - wood.temp.pa [wood.empty] = NA + leaf.empty = leaf.hcap.pa == 0 + wood.empty = wood.hcap.pa == 0 + leaf.temp.pa = uextcm2tl( uext = leaf.energy.pa + , wmass = leaf.water.pa + + leaf.water.im2.pa + , dryhcap = leaf.hcap.pa )$temp - t00 + wood.temp.pa = uextcm2tl( uext = wood.energy.pa + , wmass = wood.water.pa + + wood.water.im2.pa + , dryhcap = wood.hcap.pa )$temp - t00 + leaf.water.pa = leaf.water.pa / lai.pa + leaf.temp.pa [leaf.empty] = NA_real_ + leaf.water.pa [leaf.empty] = NA_real_ + leaf.water.im2.pa[leaf.empty] = NA_real_ + wood.temp.pa [wood.empty] = NA_real_ #---------------------------------------------------------------------------------# @@ -2021,12 +2265,42 @@ read.q.files <<- function( datum #----- Find the variables that must be rendered extensive. -----------------------# - agb.pa = tapply(X=agbconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - ba.pa = tapply(X=baconow *nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - gpp.pa = tapply(X=gppconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - npp.pa = tapply(X=nppconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - cba.pa = tapply(X=cbaconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - plant.resp.pa = tapply( X = plant.respconow*nplantconow + agb.pa = tapply( X = agbconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + agvolume.pa = tapply( X = agvolumeconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + bleaf.pa = tapply( X = bleafconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + ba.pa = tapply( X = baconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + gpp.pa = tapply( X = gppconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + npp.pa = tapply( X = nppconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + cba.pa = tapply( X = cbaconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + plant.resp.pa = tapply( X = plant.respconow * nplantconow * showconow , INDEX = ipaconow , FUN = sum , na.rm = TRUE @@ -2077,6 +2351,21 @@ read.q.files <<- function( datum + #---------------------------------------------------------------------------------# + # Canopy water potential is scaled by the canopy volume (based on Xiangtao's # + # suggestion). # + #---------------------------------------------------------------------------------# + dmin.leaf.psi.pa = mapply( FUN = weighted.mean + , x = split(dmin.leaf.psiconow,ipaconow) + , w = split(agvolumeconow ,ipaconow) + , SIMPLIFY = TRUE + )#end mapply + dmax.leaf.psi.pa = mapply( FUN = weighted.mean + , x = split(dmax.leaf.psiconow,ipaconow) + , w = split(agvolumeconow ,ipaconow) + , SIMPLIFY = TRUE + )#end mapply + #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# @@ -2216,83 +2505,271 @@ read.q.files <<- function( datum , SIMPLIFY = TRUE )#end mapply #----- Discard data from empty cohorts. -----------------------------------------# - leaf.gpp.pa [leaf.empty] = NA - leaf.par.pa [leaf.empty] = NA - leaf.par.beam.pa[leaf.empty] = NA - leaf.par.diff.pa[leaf.empty] = NA - leaf.gsw.pa [leaf.empty] = NA - leaf.vpd.pa [leaf.empty] = NA - sm.stress.pa [leaf.empty] = NA - assim.light.pa [leaf.empty] = NA - assim.rubp.pa [leaf.empty] = NA - assim.co2.pa [leaf.empty] = NA - phap.lpar.pa [leaf.empty] = NA - phap.ltemp.pa [leaf.empty] = NA - phap.lwater.pa [leaf.empty] = NA - phap.lvpd.pa [leaf.empty] = NA - phap.sms.pa [leaf.empty] = NA - phap.lgbw.pa [leaf.empty] = NA - phap.lgsw.pa [leaf.empty] = NA + leaf.gpp.pa [leaf.empty] = NA_real_ + leaf.par.pa [leaf.empty] = NA_real_ + leaf.par.beam.pa[leaf.empty] = NA_real_ + leaf.par.diff.pa[leaf.empty] = NA_real_ + leaf.gsw.pa [leaf.empty] = NA_real_ + leaf.vpd.pa [leaf.empty] = NA_real_ + sm.stress.pa [leaf.empty] = NA_real_ + assim.light.pa [leaf.empty] = NA_real_ + assim.rubp.pa [leaf.empty] = NA_real_ + assim.co2.pa [leaf.empty] = NA_real_ + phap.lpar.pa [leaf.empty] = NA_real_ + phap.ltemp.pa [leaf.empty] = NA_real_ + phap.lwater.pa [leaf.empty] = NA_real_ + phap.lvpd.pa [leaf.empty] = NA_real_ + phap.sms.pa [leaf.empty] = NA_real_ + phap.lgbw.pa [leaf.empty] = NA_real_ + phap.lgsw.pa [leaf.empty] = NA_real_ #---------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------# # Copy the data back to the patch. # #---------------------------------------------------------------------------------# - idx.leaf = idx[! leaf.empty] - idx.wood = idx[! wood.empty] - patch$lai [[plab]][idx ] = lai.pa - patch$wai [[plab]][idx ] = wai.pa - patch$agb [[plab]][idx ] = agb.pa - patch$ba [[plab]][idx ] = ba.pa - patch$nplant [[plab]][idx ] = nplant.pa - patch$can.depth [[plab]][idx ] = can.depth.pa - patch$can.area [[plab]][idx ] = can.area.pa - patch$veg.height [[plab]][idx ] = veg.height.pa - patch$veg.displace [[plab]][idx ] = veg.displace.pa - patch$veg.rough [[plab]][idx ] = veg.rough.pa - patch$can.rough [[plab]][idx ] = can.rough.pa - patch$wood.dens [[plab]][idx ] = wood.dens.pa - patch$vm0 [[plab]][idx ] = vm0.pa - patch$llspan [[plab]][idx ] = llspan.pa - patch$sla [[plab]][idx ] = sla.pa - patch$par.leaf [[plab]][idx ] = par.leaf.pa - patch$par.leaf.beam[[plab]][idx ] = par.leaf.beam.pa - patch$par.leaf.diff[[plab]][idx ] = par.leaf.diff.pa - patch$phap.lpar [[plab]][idx.leaf] = phap.lpar.pa [! leaf.empty] - patch$phap.ltemp [[plab]][idx.leaf] = phap.ltemp.pa [! leaf.empty] - patch$phap.lwater [[plab]][idx.leaf] = phap.lwater.pa [! leaf.empty] - patch$phap.lvpd [[plab]][idx.leaf] = phap.lvpd.pa [! leaf.empty] - patch$phap.sms [[plab]][idx.leaf] = phap.sms.pa [! leaf.empty] - patch$phap.lgbw [[plab]][idx.leaf] = phap.lgbw.pa [! leaf.empty] - patch$phap.lgsw [[plab]][idx.leaf] = phap.lgsw.pa [! leaf.empty] - patch$sm.stress [[plab]][idx.leaf] = sm.stress.pa [! leaf.empty] - patch$leaf.temp [[plab]][idx.leaf] = leaf.temp.pa [! leaf.empty] - patch$leaf.water [[plab]][idx.leaf] = leaf.water.pa [! leaf.empty] - patch$leaf.vpd [[plab]][idx.leaf] = leaf.vpd.pa [! leaf.empty] - patch$leaf.gpp [[plab]][idx.leaf] = leaf.gpp.pa [! leaf.empty] - patch$leaf.gsw [[plab]][idx.leaf] = leaf.gsw.pa [! leaf.empty] - patch$leaf.par [[plab]][idx.leaf] = leaf.par.pa [! leaf.empty] - patch$leaf.par.beam[[plab]][idx.leaf] = leaf.par.beam.pa[! leaf.empty] - patch$leaf.par.diff[[plab]][idx.leaf] = leaf.par.diff.pa[! leaf.empty] - patch$assim.light [[plab]][idx.leaf] = assim.light.pa [! leaf.empty] - patch$assim.rubp [[plab]][idx.leaf] = assim.rubp.pa [! leaf.empty] - patch$assim.co2 [[plab]][idx.leaf] = assim.co2.pa [! leaf.empty] - patch$wood.temp [[plab]][idx.wood] = wood.temp.pa [! wood.empty] - patch$gpp [[plab]][idx ] = gpp.pa - patch$npp [[plab]][idx ] = npp.pa - patch$cba [[plab]][idx ] = cba.pa - patch$plant.resp [[plab]][idx ] = plant.resp.pa - patch$hflxlc [[plab]][idx ] = hflxlc.pa - patch$hflxwc [[plab]][idx ] = hflxwc.pa - patch$wflxlc [[plab]][idx ] = wflxlc.pa - patch$wflxwc [[plab]][idx ] = wflxwc.pa - patch$transp [[plab]][idx ] = transp.pa + idx.leaf = idx[! leaf.empty] + idx.wood = idx[! wood.empty] + patch$lai [[plab]][idx ] = lai.pa + patch$wai [[plab]][idx ] = wai.pa + patch$agb [[plab]][idx ] = agb.pa + patch$ba [[plab]][idx ] = ba.pa + patch$nplant [[plab]][idx ] = nplant.pa + patch$bleaf [[plab]][idx ] = bleaf.pa + patch$can.depth [[plab]][idx ] = can.depth.pa + patch$can.area [[plab]][idx ] = can.area.pa + patch$veg.height [[plab]][idx ] = veg.height.pa + patch$veg.displace [[plab]][idx ] = veg.displace.pa + patch$veg.rough [[plab]][idx ] = veg.rough.pa + patch$can.rough [[plab]][idx ] = can.rough.pa + patch$wood.dens [[plab]][idx ] = wood.dens.pa + patch$vm0 [[plab]][idx ] = vm0.pa + patch$llspan [[plab]][idx ] = llspan.pa + patch$sla [[plab]][idx ] = sla.pa + patch$par.leaf [[plab]][idx ] = par.leaf.pa + patch$par.leaf.beam [[plab]][idx ] = par.leaf.beam.pa + patch$par.leaf.diff [[plab]][idx ] = par.leaf.diff.pa + patch$phap.lpar [[plab]][idx.leaf] = phap.lpar.pa [! leaf.empty] + patch$phap.ltemp [[plab]][idx.leaf] = phap.ltemp.pa [! leaf.empty] + patch$phap.lwater [[plab]][idx.leaf] = phap.lwater.pa [! leaf.empty] + patch$phap.lvpd [[plab]][idx.leaf] = phap.lvpd.pa [! leaf.empty] + patch$phap.sms [[plab]][idx.leaf] = phap.sms.pa [! leaf.empty] + patch$phap.lgbw [[plab]][idx.leaf] = phap.lgbw.pa [! leaf.empty] + patch$phap.lgsw [[plab]][idx.leaf] = phap.lgsw.pa [! leaf.empty] + patch$sm.stress [[plab]][idx.leaf] = sm.stress.pa [! leaf.empty] + patch$leaf.temp [[plab]][idx.leaf] = leaf.temp.pa [! leaf.empty] + patch$leaf.water [[plab]][idx.leaf] = leaf.water.pa [! leaf.empty] + patch$leaf.water.im2[[plab]][idx.leaf] = leaf.water.im2.pa[! leaf.empty] + patch$leaf.vpd [[plab]][idx.leaf] = leaf.vpd.pa [! leaf.empty] + patch$leaf.gpp [[plab]][idx.leaf] = leaf.gpp.pa [! leaf.empty] + patch$leaf.gsw [[plab]][idx.leaf] = leaf.gsw.pa [! leaf.empty] + patch$leaf.par [[plab]][idx.leaf] = leaf.par.pa [! leaf.empty] + patch$leaf.par.beam [[plab]][idx.leaf] = leaf.par.beam.pa [! leaf.empty] + patch$leaf.par.diff [[plab]][idx.leaf] = leaf.par.diff.pa [! leaf.empty] + patch$assim.light [[plab]][idx.leaf] = assim.light.pa [! leaf.empty] + patch$assim.rubp [[plab]][idx.leaf] = assim.rubp.pa [! leaf.empty] + patch$assim.co2 [[plab]][idx.leaf] = assim.co2.pa [! leaf.empty] + patch$wood.temp [[plab]][idx.wood] = wood.temp.pa [! wood.empty] + patch$dmin.leaf.psi [[plab]][idx ] = dmin.leaf.psi.pa + patch$dmax.leaf.psi [[plab]][idx ] = dmax.leaf.psi.pa + patch$gpp [[plab]][idx ] = gpp.pa + patch$npp [[plab]][idx ] = npp.pa + patch$cba [[plab]][idx ] = cba.pa + patch$plant.resp [[plab]][idx ] = plant.resp.pa + patch$hflxlc [[plab]][idx ] = hflxlc.pa + patch$hflxwc [[plab]][idx ] = hflxwc.pa + patch$wflxlc [[plab]][idx ] = wflxlc.pa + patch$wflxwc [[plab]][idx ] = wflxwc.pa + patch$transp [[plab]][idx ] = transp.pa #------ Soil respiration mixes cohort (root) and patch (hetetrophic). ------------# - patch$soil.resp [[plab]][idx] = patch$soil.resp [[plab]][idx] + root.resp.pa + patch$soil.resp [[plab]][idx] = patch$soil.resp [[plab]][idx] + root.resp.pa + #---------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Demographic rates. # + #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + for (jpa in sequence(mymont$NPATCHES.GLOBAL)){ + + #------------------------------------------------------------------------------# + # For mortality and growth, we keep deleting the tiny cohorts because they # + # skew the rates quite significantly and they are rarely included in forest # + # inventory surveys. # + #------------------------------------------------------------------------------# + psel = (ipaconow == jpa) & (dbhconow >= census.dbh.min) + if (any(psel)){ + #----- Growth rates are weighted by population. ----------------------------# + dbh.growth = - 100. * log( weighted.mean( x = exp(-growthconow [psel]) + , w = nplantconow [psel] + * dbhconow [psel] + )#end weighted.mean + )#end log + agb.growth = - 100. * log( weighted.mean( x = exp(-agb.growthconow[psel]) + , w = nplantconow [psel] + * agbconow [psel] + )#end weighted.mean + )#end log + bsa.growth = - 100. * log( weighted.mean( x = exp(-bsa.growthconow[psel]) + , w = nplantconow [psel] + * baconow [psel] + )#end weighted.mean + )#end log + acc.growth = sum( nplantconow[psel] + * agbconow[psel] * (1.-exp(-agb.growthconow[psel])) + )#end sum + patch$growth [[plab]][jpa] = dbh.growth + patch$agb.growth [[plab]][jpa] = agb.growth + patch$acc.growth [[plab]][jpa] = acc.growth + patch$bsa.growth [[plab]][jpa] = bsa.growth + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total number of plants and previous population if the only # + # mortality was the mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] ) + previous = sum( nplantconow[psel] * exp(mortconow [psel])) + ncb.previous = sum( nplantconow[psel] * exp(ncbmortconow [psel])) + hyd.previous = sum( nplantconow[psel] * exp(hydmortconow [psel])) + di.previous = sum( nplantconow[psel] * exp(dimortconow [psel])) + fl.previous = sum( nplantconow[psel] * exp(fire.lethalconow[psel])) + patch$mort [[plab]][jpa] = log(previous / survivor) + patch$ncbmort [[plab]][jpa] = log(ncb.previous / survivor) + patch$hydmort [[plab]][jpa] = log(hyd.previous / survivor) + patch$dimort [[plab]][jpa] = log(di.previous / survivor) + patch$fire.lethal[[plab]][jpa] = log(fl.previous / survivor) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total AGB and previous AGB if the only mortality was the # + # mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * agbcolmon[psel]) + previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(mortconow [psel]) + )#end sum + ncb.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(ncbmortconow [psel]) + )#end sum + hyd.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(hydmortconow [psel]) + )#end sum + di.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(dimortconow [psel]) + )#end sum + patch$agb.mort [[plab]][jpa] = log( previous / survivor ) + patch$agb.ncbmort[[plab]][jpa] = log( ncb.previous / survivor ) + patch$agb.hydmort[[plab]][jpa] = log( hyd.previous / survivor ) + patch$agb.dimort [[plab]][jpa] = log( di.previous / survivor ) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total AGB and previous AGB if the only mortality was the # + # mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * agbcolmon[psel]) + previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( mortconow [psel] / 12.) + )#end sum + ncb.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( ncbmortconow[psel] / 12.) + )#end sum + hyd.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( hydmortconow[psel] / 12.) + )#end sum + di.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( dimortconow [psel] / 12.) + )#end sum + patch$acc.mort [[plab]][jpa] = 12. * (previous - survivor) + patch$acc.ncbmort[[plab]][jpa] = 12. * (ncb.previous - survivor) + patch$acc.hydmort[[plab]][jpa] = 12. * (hyd.previous - survivor) + patch$acc.dimort [[plab]][jpa] = 12. * (di.previous - survivor) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total basal area and previous basal area if the only # + # mortality was the mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * bacolmon[psel]) + previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(mortconow [psel]) + )#end sum + ncb.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(ncbmortconow [psel]) + )#end sum + hyd.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(hydmortconow [psel]) + )#end sum + di.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(dimortconow [psel]) + )#end sum + patch$bsa.mort [[plab]][jpa] = log( previous / survivor ) + patch$bsa.ncbmort[[plab]][jpa] = log( ncb.previous / survivor ) + patch$bsa.hydmort[[plab]][jpa] = log( hyd.previous / survivor ) + patch$bsa.dimort [[plab]][jpa] = log( di.previous / survivor ) + #---------------------------------------------------------------------------# + }#end if + #------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------# + # Recruitment: we must determine whether the plant grew into the new # + # category or not. # + #------------------------------------------------------------------------------# + psel.pop = (ipaconow == jpa) & (dbhconow >= census.dbh.min) + psel.est = psel.pop & (dbhconow.1ago >= census.dbh.min) + psel.elm = psel.pop & (dbhconow.lmon >= census.dbh.min) + if (any(psel.pop) & any(psel.est)){ + + #----- Recruitment rate in terms of individuals. ---------------------------# + population = sum(nplantconow[psel.pop]) + established = sum(nplantconow[psel.est]) + patch$recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of above-ground biomass. ------------------# + population = sum(nplantconow[psel.pop]*agbconow[psel.pop]) + established = sum(nplantconow[psel.est]*agbconow[psel.est]) + patch$agb.recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of above-ground biomass. ------------------# + population = sum(nplantconow[psel.pop]*agbconow[psel.pop]) + established = sum(nplantconow[psel.elm]*agbconow[psel.elm]) + patch$acc.recr[[plab]][jpa] = 12. * (population - established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of basal area. ----------------------------# + population = sum(nplantconow[psel.pop]*baconow [psel.pop]) + established = sum(nplantconow[psel.est]*baconow [psel.est]) + patch$bsa.recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + }#end if + #------------------------------------------------------------------------------# + }#end for (jpa in sequence(mymont$NPATCHES.GLOBAL)) + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + + @@ -2308,78 +2785,90 @@ read.q.files <<- function( datum #----- Find some auxiliary patch-level properties. -------------------------------# - q.nplant.pa = qapply( X = q.nplantconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.lai.pa = qapply( X = q.laiconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wai.pa = qapply( X = q.waiconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.energy.pa = qapply( X = mymont$QMEAN.LEAF.ENERGY.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.water.pa = qapply( X = mymont$QMEAN.LEAF.WATER.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.hcap.pa = qapply( X = mymont$QMEAN.LEAF.HCAP.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.pa = qapply( X = mymont$QMEAN.PAR.L.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.beam.pa = qapply( X = mymont$QMEAN.PAR.L.BEAM.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.diff.pa = qapply( X = mymont$QMEAN.PAR.L.DIFF.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.energy.pa = qapply( X = mymont$QMEAN.WOOD.ENERGY.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.water.pa = qapply( X = mymont$QMEAN.WOOD.WATER.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.hcap.pa = qapply( X = mymont$QMEAN.WOOD.HCAP.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply + q.nplant.pa = qapply( X = q.nplantconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.lai.pa = qapply( X = q.laiconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wai.pa = qapply( X = q.waiconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.energy.pa = qapply( X = mymont$QMEAN.LEAF.ENERGY.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.water.pa = qapply( X = mymont$QMEAN.LEAF.WATER.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.water.im2.pa = qapply( X = mymont$QMEAN.LEAF.WATER.IM2.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.hcap.pa = qapply( X = mymont$QMEAN.LEAF.HCAP.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.pa = qapply( X = mymont$QMEAN.PAR.L.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.beam.pa = qapply( X = mymont$QMEAN.PAR.L.BEAM.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.diff.pa = qapply( X = mymont$QMEAN.PAR.L.DIFF.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.energy.pa = qapply( X = mymont$QMEAN.WOOD.ENERGY.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.water.pa = qapply( X = mymont$QMEAN.WOOD.WATER.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.water.im2.pa = qapply( X = mymont$QMEAN.WOOD.WATER.IM2.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.hcap.pa = qapply( X = mymont$QMEAN.WOOD.HCAP.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply #----- Make root respiration extensive. ------------------------------------------# q.root.resp.pa = qapply( X = q.root.respconow * q.nplantconow , DIM = 1 @@ -2392,27 +2881,33 @@ read.q.files <<- function( datum #----- Find the temperature and liquid fraction of leaf and wood. ----------------# - q.leaf.empty = q.leaf.hcap.pa == 0 - q.wood.empty = q.wood.hcap.pa == 0 - q.leaf.temp.pa = uextcm2tl( uext = q.leaf.energy.pa - , wmass = q.leaf.water.pa - , dryhcap = q.leaf.hcap.pa )$temp - t00 - q.wood.temp.pa = uextcm2tl( uext = q.wood.energy.pa - , wmass = q.wood.water.pa - , dryhcap = q.wood.hcap.pa )$temp - t00 - q.leaf.water.pa = q.leaf.water.pa / q.lai.pa - q.leaf.temp.pa = ifelse( test = q.leaf.hcap.pa == 0 - , yes = NA - , no = q.leaf.temp.pa - )#end ifelse - q.leaf.water.pa = ifelse( test = q.leaf.hcap.pa == 0 - , yes = NA - , no = q.leaf.water.pa - )#end ifelse - q.wood.temp.pa = ifelse( test = q.wood.hcap.pa == 0 - , yes = NA - , no = q.wood.temp.pa - )#end ifelse + q.leaf.empty = q.leaf.hcap.pa == 0 + q.wood.empty = q.wood.hcap.pa == 0 + q.leaf.temp.pa = uextcm2tl( uext = q.leaf.energy.pa + , wmass = q.leaf.water.pa + + q.leaf.water.im2.pa + , dryhcap = q.leaf.hcap.pa )$temp - t00 + q.wood.temp.pa = uextcm2tl( uext = q.wood.energy.pa + , wmass = q.wood.water.pa + + q.wood.water.im2.pa + , dryhcap = q.wood.hcap.pa )$temp - t00 + q.leaf.water.pa = q.leaf.water.pa / q.lai.pa + q.leaf.temp.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.temp.pa + )#end ifelse + q.leaf.water.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.water.pa + )#end ifelse + q.leaf.water.im2.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.water.im2.pa + )#end ifelse + q.wood.temp.pa = ifelse( test = q.wood.hcap.pa == 0. + , yes = NA_real_ + , no = q.wood.temp.pa + )#end ifelse #---------------------------------------------------------------------------------# @@ -2546,16 +3041,16 @@ read.q.files <<- function( datum )#end mapply )#end t #----- Discard data from empty cohorts. -----------------------------------------# - q.leaf.gpp.pa [q.leaf.empty] = NA - q.leaf.par.pa [q.leaf.empty] = NA - q.leaf.par.beam.pa[q.leaf.empty] = NA - q.leaf.par.diff.pa[q.leaf.empty] = NA - q.leaf.gsw.pa [q.leaf.empty] = NA - q.leaf.vpd.pa [q.leaf.empty] = NA - q.sm.stress.pa [q.leaf.empty] = NA - q.assim.light.pa [q.leaf.empty] = NA - q.assim.rubp.pa [q.leaf.empty] = NA - q.assim.co2.pa [q.leaf.empty] = NA + q.leaf.gpp.pa [q.leaf.empty] = NA_real_ + q.leaf.par.pa [q.leaf.empty] = NA_real_ + q.leaf.par.beam.pa[q.leaf.empty] = NA_real_ + q.leaf.par.diff.pa[q.leaf.empty] = NA_real_ + q.leaf.gsw.pa [q.leaf.empty] = NA_real_ + q.leaf.vpd.pa [q.leaf.empty] = NA_real_ + q.sm.stress.pa [q.leaf.empty] = NA_real_ + q.assim.light.pa [q.leaf.empty] = NA_real_ + q.assim.rubp.pa [q.leaf.empty] = NA_real_ + q.assim.co2.pa [q.leaf.empty] = NA_real_ #---------------------------------------------------------------------------------# @@ -2564,30 +3059,31 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# # Copy the data back to the patch. # #---------------------------------------------------------------------------------# - qpatch$par.leaf [[plab]][idx ,] = q.par.leaf.pa - qpatch$par.leaf.beam[[plab]][idx ,] = q.par.leaf.beam.pa - qpatch$par.leaf.diff[[plab]][idx ,] = q.par.leaf.diff.pa - qpatch$sm.stress [[plab]][idx.leaf,] = q.sm.stress.pa [! q.leaf.empty] - qpatch$leaf.temp [[plab]][idx.leaf,] = q.leaf.temp.pa [! q.leaf.empty] - qpatch$leaf.water [[plab]][idx.leaf,] = q.leaf.water.pa [! q.leaf.empty] - qpatch$leaf.vpd [[plab]][idx.leaf,] = q.leaf.vpd.pa [! q.leaf.empty] - qpatch$leaf.gpp [[plab]][idx.leaf,] = q.leaf.gpp.pa [! q.leaf.empty] - qpatch$leaf.gsw [[plab]][idx.leaf,] = q.leaf.gsw.pa [! q.leaf.empty] - qpatch$leaf.par [[plab]][idx.leaf,] = q.leaf.par.pa [! q.leaf.empty] - qpatch$leaf.par.beam[[plab]][idx.leaf,] = q.leaf.par.beam.pa[! q.leaf.empty] - qpatch$leaf.par.diff[[plab]][idx.leaf,] = q.leaf.par.diff.pa[! q.leaf.empty] - qpatch$assim.light [[plab]][idx.leaf,] = q.assim.light.pa [! q.leaf.empty] - qpatch$assim.rubp [[plab]][idx.leaf,] = q.assim.rubp.pa [! q.leaf.empty] - qpatch$assim.co2 [[plab]][idx.leaf,] = q.assim.co2.pa [! q.leaf.empty] - qpatch$wood.temp [[plab]][idx.wood,] = q.wood.temp.pa [! q.wood.empty] - qpatch$gpp [[plab]][idx ,] = q.gpp.pa - qpatch$npp [[plab]][idx ,] = q.npp.pa - qpatch$plant.resp [[plab]][idx ,] = q.plant.resp.pa - qpatch$hflxlc [[plab]][idx ,] = q.hflxlc.pa - qpatch$hflxwc [[plab]][idx ,] = q.hflxwc.pa - qpatch$wflxlc [[plab]][idx ,] = q.wflxlc.pa - qpatch$wflxwc [[plab]][idx ,] = q.wflxwc.pa - qpatch$transp [[plab]][idx ,] = q.transp.pa + qpatch$par.leaf [[plab]][idx ,] = q.par.leaf.pa + qpatch$par.leaf.beam [[plab]][idx ,] = q.par.leaf.beam.pa + qpatch$par.leaf.diff [[plab]][idx ,] = q.par.leaf.diff.pa + qpatch$sm.stress [[plab]][idx.leaf,] = q.sm.stress.pa [! q.leaf.empty] + qpatch$leaf.temp [[plab]][idx.leaf,] = q.leaf.temp.pa [! q.leaf.empty] + qpatch$leaf.water [[plab]][idx.leaf,] = q.leaf.water.pa [! q.leaf.empty] + qpatch$leaf.water.im2[[plab]][idx.leaf,] = q.leaf.water.im2.pa[! q.leaf.empty] + qpatch$leaf.vpd [[plab]][idx.leaf,] = q.leaf.vpd.pa [! q.leaf.empty] + qpatch$leaf.gpp [[plab]][idx.leaf,] = q.leaf.gpp.pa [! q.leaf.empty] + qpatch$leaf.gsw [[plab]][idx.leaf,] = q.leaf.gsw.pa [! q.leaf.empty] + qpatch$leaf.par [[plab]][idx.leaf,] = q.leaf.par.pa [! q.leaf.empty] + qpatch$leaf.par.beam [[plab]][idx.leaf,] = q.leaf.par.beam.pa [! q.leaf.empty] + qpatch$leaf.par.diff [[plab]][idx.leaf,] = q.leaf.par.diff.pa [! q.leaf.empty] + qpatch$assim.light [[plab]][idx.leaf,] = q.assim.light.pa [! q.leaf.empty] + qpatch$assim.rubp [[plab]][idx.leaf,] = q.assim.rubp.pa [! q.leaf.empty] + qpatch$assim.co2 [[plab]][idx.leaf,] = q.assim.co2.pa [! q.leaf.empty] + qpatch$wood.temp [[plab]][idx.wood,] = q.wood.temp.pa [! q.wood.empty] + qpatch$gpp [[plab]][idx ,] = q.gpp.pa + qpatch$npp [[plab]][idx ,] = q.npp.pa + qpatch$plant.resp [[plab]][idx ,] = q.plant.resp.pa + qpatch$hflxlc [[plab]][idx ,] = q.hflxlc.pa + qpatch$hflxwc [[plab]][idx ,] = q.hflxwc.pa + qpatch$wflxlc [[plab]][idx ,] = q.wflxlc.pa + qpatch$wflxwc [[plab]][idx ,] = q.wflxwc.pa + qpatch$transp [[plab]][idx ,] = q.transp.pa #------ Soil respiration mixes cohort (root) and patch (hetetrophic). ------------# qpatch$soil.resp[[plab]][idx,] = qpatch$soil.resp[[plab]][idx,] + q.root.resp.pa #---------------------------------------------------------------------------------# @@ -2615,6 +3111,340 @@ read.q.files <<- function( datum + #====================================================================================# + #====================================================================================# + #====================================================================================# + #====================================================================================# + # Find the site-level variables. # + #------------------------------------------------------------------------------------# + #---- Time-invariant variables (we keep time to make post-post-processing easier). --# + site$isi [m,] = isi + site$lsl [m,] = lslsi + site$ntext[m,] = ntextsi + site$area [m,] = areasi + #---- Variables that can be copied directly from the output. ------------------------# + site$fire.density [m,] = mymont$MMEAN.FIRE.DENSITY.SI * 1.e6 + site$fire.extinction[m,] = 100. * (1. - exp(-mymont$MMEAN.FIRE.EXTINCTION.SI)) + site$fire.intensity [m,] = mymont$MMEAN.FIRE.INTENSITY.SI * 1.e3 + site$fire.tlethal [m,] = mymont$MMEAN.FIRE.TLETHAL.SI / min.sec + site$fire.spread [m,] = mymont$MMEAN.FIRE.SPREAD.SI * min.sec + site$burnt.area [m,] = mymont$BURNT.AREA * 100. + site$ignition.rate [m,] = mymont$MMEAN.IGNITION.RATE.SI * 1.e6*mondays*day.sec + site$fire.f.bherb [m,] = mymont$MMEAN.FIRE.F.BHERB.SI * 100. + site$fire.f.bwoody [m,] = mymont$MMEAN.FIRE.F.BWOODY.SI * 100. + site$fire.f.fgc [m,] = mymont$MMEAN.FIRE.F.FGC.SI * 100. + site$fire.f.stgc [m,] = mymont$MMEAN.FIRE.F.STGC.SI * 100. + #----- Variables that should be scaled by area (most of them). ----------------------# + site$lai [m,] = weighted.mean( x = patch$lai [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wai [m,] = weighted.mean( x = patch$wai [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$agb [m,] = weighted.mean( x = patch$agb [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$ba [m,] = weighted.mean( x = patch$ba [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nplant [m,] = weighted.mean( x = patch$nplant [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$fast.grnd.c [m,] = weighted.mean( x = patch$fast.grnd.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$fast.soil.c [m,] = weighted.mean( x = patch$fast.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$struct.grnd.c [m,] = weighted.mean( x = patch$struct.grnd.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$struct.soil.c [m,] = weighted.mean( x = patch$struct.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$microbe.soil.c [m,] = weighted.mean( x = patch$microbe.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$slow.soil.c [m,] = weighted.mean( x = patch$slow.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$passive.soil.c [m,] = weighted.mean( x = patch$passive.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nep [m,] = weighted.mean( x = patch$nep [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$het.resp [m,] = weighted.mean( x = patch$het.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.resp [m,] = weighted.mean( x = patch$soil.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cflxca [m,] = weighted.mean( x = patch$cflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cflxst [m,] = weighted.mean( x = patch$cflxst [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nee [m,] = weighted.mean( x = patch$nee [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxca [m,] = weighted.mean( x = patch$hflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxgc [m,] = weighted.mean( x = patch$hflxgc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$qwflxca [m,] = weighted.mean( x = patch$qwflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxca [m,] = weighted.mean( x = patch$wflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxgc [m,] = weighted.mean( x = patch$wflxgc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$ustar [m,] = weighted.mean( x = patch$ustar [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rshortup [m,] = weighted.mean( x = patch$rshortup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rlongup [m,] = weighted.mean( x = patch$rlongup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$parup [m,] = weighted.mean( x = patch$parup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rshort.gnd [m,] = weighted.mean( x = patch$rshort.gnd [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$par.gnd [m,] = weighted.mean( x = patch$par.gnd [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rnet [m,] = weighted.mean( x = patch$rnet [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$can.depth [m,] = weighted.mean( x = patch$can.depth [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$can.area [m,] = weighted.mean( x = patch$can.area [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$veg.height [m,] = weighted.mean( x = patch$veg.height [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$sm.stress [m,] = weighted.mean( x = patch$sm.stress [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gpp [m,] = weighted.mean( x = patch$gpp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$npp [m,] = weighted.mean( x = patch$npp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$plant.resp [m,] = weighted.mean( x = patch$plant.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cba [m,] = weighted.mean( x = patch$cba [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$reco [m,] = weighted.mean( x = patch$reco [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxlc [m,] = weighted.mean( x = patch$hflxlc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxwc [m,] = weighted.mean( x = patch$hflxwc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxlc [m,] = weighted.mean( x = patch$wflxlc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxwc [m,] = weighted.mean( x = patch$wflxwc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$transp [m,] = weighted.mean( x = patch$transp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gnd.temp [m,] = weighted.mean( x = patch$gnd.temp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gnd.shv [m,] = weighted.mean( x = patch$gnd.shv [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.temp.top [m,] = weighted.mean( x = patch$soil.temp.top [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.water.top [m,] = weighted.mean( x = patch$soil.water.top [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.water.bot [m,] = weighted.mean( x = patch$soil.water.bot [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.wetness.top[m,] = weighted.mean( x = patch$soil.wetness.top[[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.wetness.bot[m,] = weighted.mean( x = patch$soil.wetness.bot[[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.water [m,] = weighted.mean( x = patch$leaf.water [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.water.im2 [m,] = weighted.mean( x = patch$leaf.water.im2 [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + #----- Quantities that should be weighted by leaf area. -----------------------------# + laiareapa = patch$lai[[plab]] * areapa + if ( sum(laiareapa) > tiny.num ){ + site$vm0 [m,] = weighted.mean( x = patch$vm0 [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.temp [m,] = weighted.mean( x = patch$leaf.temp [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.vpd [m,] = weighted.mean( x = patch$leaf.vpd [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.gpp [m,] = weighted.mean( x = patch$leaf.gpp [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.gsw [m,] = weighted.mean( x = patch$leaf.gsw [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par [m,] = weighted.mean( x = patch$leaf.par [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par.beam[m,] = weighted.mean( x = patch$leaf.par.beam[[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par.diff[m,] = weighted.mean( x = patch$leaf.par.diff[[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$vm0 [m,] = NA_real_ + site$leaf.temp [m,] = NA_real_ + site$leaf.vpd [m,] = NA_real_ + site$leaf.gpp [m,] = NA_real_ + site$leaf.gsw [m,] = NA_real_ + site$leaf.par [m,] = NA_real_ + site$leaf.par.beam[m,] = NA_real_ + site$leaf.par.diff[m,] = NA_real_ + }#end if ( sum(laiareapa) > tiny.num) + #---- Wood density is scaled by basal area. -----------------------------------------# + basareapa = patch$ba[[plab]] * areapa + if ( sum(basareapa) > tiny.num ){ + site$wood.dens [m,] = weighted.mean( x = patch$wood.dens [[plab]] + , w = basareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$wood.dens [m,] = NA_real_ + }#end if (sum(basareapa) > tiny.num) + #---- SLA and leaf life span use leaf biomass as weighting factor. ------------------# + bleafareapa = patch$bleaf[[plab]] * areapa + if ( sum(bleafareapa) > tiny.num ){ + + ltor.si = weighted.mean( x = ltor.pa + , w = bleafareapa + , na.rm = TRUE + )#end weighted.mean + site$sla [m,] = weighted.mean( x = patch$sla[[plab]] + , w = bleafareapa + , na.rm = TRUE + )#end weighted.mean + site$llspan [m,] = ifelse( test = ltor.si %gt% 0. + , yes = 1. / ltor.si + , no = NA_real_ + )#end ifelse + }else{ + site$llspan [m,] = NA_real_ + site$sla [m,] = NA_real_ + }#end if ( sum(bleafareapa) > tiny.num ) + #---- Leaf water potential. Use aboveground volume as weighting factor. ------------# + agvolumeareapa = agvolume.pa * areapa + if ( sum(agvolumeareapa) > tiny.num ){ + site$dmin.leaf.psi[m,] = weighted.mean( x = patch$dmin.leaf.psi[[plab]] + , w = agvolumeareapa + , na.rm = TRUE + )#end weighted.mean + site$dmax.leaf.psi[m,] = weighted.mean( x = patch$dmax.leaf.psi[[plab]] + , w = agvolumeareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$dmin.leaf.psi[m,] = NA_real_ + site$dmax.leaf.psi[m,] = NA_real_ + }#end if ( sum(agvolumeareapa) > tiny.num ) + #------------------------------------------------------------------------------------# + + + #====================================================================================# + #====================================================================================# + #====================================================================================# + #====================================================================================# + @@ -2623,14 +3453,15 @@ read.q.files <<- function( datum # (whatever/plant) to "extensive" (whatever/m2). Sometimes they may be used to # # build weighted averages. # #------------------------------------------------------------------------------------# - w.nplant = nplantconow * areaconow - w.lai = laiconow * areaconow - w.wai = waiconow * areaconow - w.tai = taiconow * areaconow - w.biomass = biomassconow * w.nplant - w.bleaf = bleafconow * w.nplant - w.balive = baliveconow * w.nplant - w.basarea = baconow * w.nplant + w.nplant = nplantconow * areaconow + w.lai = laiconow * areaconow + w.wai = waiconow * areaconow + w.tai = taiconow * areaconow + w.biomass = biomassconow * w.nplant + w.bleaf = bleafconow * w.nplant + w.balive = baliveconow * w.nplant + w.basarea = baconow * w.nplant + w.agvolume = agvolumeconow * w.nplant #------------------------------------------------------------------------------------# @@ -2897,118 +3728,122 @@ read.q.files <<- function( datum #----- Leaf/wood intensive properties , weighted means using LAI/WAI. ------# - szpft$sm.stress [m,d,p] = weighted.mean( x = sm.stressconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.sms [m,d,p] = weighted.mean( x = phap.smsconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par [m,d,p] = weighted.mean( x = leaf.parconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par.beam[m,d,p] = weighted.mean( x = leaf.par.beamconow[sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par.diff[m,d,p] = weighted.mean( x = leaf.par.diffconow[sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lpar [m,d,p] = weighted.mean( x = phap.lparconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.rshort [m,d,p] = weighted.mean( x = leaf.rshortconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.rlong [m,d,p] = weighted.mean( x = leaf.rlongconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gpp [m,d,p] = weighted.mean( x = leaf.gppconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.temp [m,d,p] = weighted.mean( x = leaf.tempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.ltemp [m,d,p] = weighted.mean( x = phap.ltempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.water [m,d,p] = weighted.mean( x = leaf.waterconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lwater [m,d,p] = weighted.mean( x = phap.lwaterconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$wood.temp [m,d,p] = weighted.mean( x = wood.tempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.vpd [m,d,p] = weighted.mean( x = leaf.vpdconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lvpd [m,d,p] = weighted.mean( x = phap.lvpdconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.transp [m,d,p] = weighted.mean( x = i.transpconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.wflxlc [m,d,p] = weighted.mean( x = i.wflxlcconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.hflxlc [m,d,p] = weighted.mean( x = i.hflxlcconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gbw [m,d,p] = weighted.mean( x = leaf.gbwconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lgbw [m,d,p] = weighted.mean( x = phap.lgbwconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gsw [m,d,p] = weighted.mean( x = leaf.gswconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lgsw [m,d,p] = weighted.mean( x = phap.lgswconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.light [m,d,p] = weighted.mean( x = assim.lightconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.rubp [m,d,p] = weighted.mean( x = assim.rubpconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.co2 [m,d,p] = weighted.mean( x = assim.co2conow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$vm0 [m,d,p] = weighted.mean( x = vm0conow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$wood.gbw [m,d,p] = weighted.mean( x = wood.gbwconow [sel] - , w = w.wai [sel] - , na.rm = TRUE - )#end weighted.mean + szpft$sm.stress [m,d,p] = weighted.mean( x = sm.stressconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.sms [m,d,p] = weighted.mean( x = phap.smsconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par [m,d,p] = weighted.mean( x = leaf.parconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par.beam [m,d,p] = weighted.mean( x = leaf.par.beamconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par.diff [m,d,p] = weighted.mean( x = leaf.par.diffconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lpar [m,d,p] = weighted.mean( x = phap.lparconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.rshort [m,d,p] = weighted.mean( x = leaf.rshortconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.rlong [m,d,p] = weighted.mean( x = leaf.rlongconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gpp [m,d,p] = weighted.mean( x = leaf.gppconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.temp [m,d,p] = weighted.mean( x = leaf.tempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.ltemp [m,d,p] = weighted.mean( x = phap.ltempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.water [m,d,p] = weighted.mean( x = leaf.waterconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.water.im2[m,d,p] = weighted.mean( x = leaf.water.im2conow[sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lwater [m,d,p] = weighted.mean( x = phap.lwaterconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$wood.temp [m,d,p] = weighted.mean( x = wood.tempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.vpd [m,d,p] = weighted.mean( x = leaf.vpdconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lvpd [m,d,p] = weighted.mean( x = phap.lvpdconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.transp [m,d,p] = weighted.mean( x = i.transpconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.wflxlc [m,d,p] = weighted.mean( x = i.wflxlcconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.hflxlc [m,d,p] = weighted.mean( x = i.hflxlcconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gbw [m,d,p] = weighted.mean( x = leaf.gbwconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lgbw [m,d,p] = weighted.mean( x = phap.lgbwconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gsw [m,d,p] = weighted.mean( x = leaf.gswconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lgsw [m,d,p] = weighted.mean( x = phap.lgswconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.light [m,d,p] = weighted.mean( x = assim.lightconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.rubp [m,d,p] = weighted.mean( x = assim.rubpconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.co2 [m,d,p] = weighted.mean( x = assim.co2conow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$vm0 [m,d,p] = weighted.mean( x = vm0conow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$wood.gbw [m,d,p] = weighted.mean( x = wood.gbwconow [sel] + , w = w.wai [sel] + , na.rm = TRUE + )#end weighted.mean #---------------------------------------------------------------------------# @@ -3060,6 +3895,19 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------# + #----- Leaf water potential: averaged by volume. ---------------------------# + szpft$dmin.leaf.psi[m,d,p] = weighted.mean( x = dmin.leaf.psiconow[sel] + , w = w.agvolume [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$dmax.leaf.psi[m,d,p] = weighted.mean( x = dmax.leaf.psiconow[sel] + , w = w.agvolume [sel] + , na.rm = TRUE + )#end weighted.mean + #---------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------# # SLA: use leaf biomass as weight so bleaf, SLA, and LAI are consistent. # #---------------------------------------------------------------------------# @@ -3077,7 +3925,7 @@ read.q.files <<- function( datum , w = w.bleaf [sel] , na.rm = TRUE )#end weighted.mean - szpft$llspan [m,d,p] = ifelse( test = szpft$llspan[m,d,p] %>% 0 + szpft$llspan [m,d,p] = ifelse( test = szpft$llspan[m,d,p] %gt% 0 , yes = 1./szpft$llspan[m,d,p] , no = NA_real_ )#end ifelse @@ -3166,8 +4014,9 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------# - # For mortality and growth, we keep deleting the tiny guys because they # - # skew the rates quite significantly. # + # For mortality and growth, we keep deleting the tiny cohorts because they # + # skew the rates quite significantly and they are rarely included in forest # + # inventory surveys. # #------------------------------------------------------------------------------# sel = sel.pft & sel.dbh & dbhconow >= dbhminconow if (any(sel)){ @@ -3202,15 +4051,17 @@ read.q.files <<- function( datum # Find the total number of plants and previous population if the only # # mortality was the mortality we test. # #---------------------------------------------------------------------------# - survivor = sum( w.nplant[sel] ) - previous = sum( w.nplant[sel] * exp(mortconow [sel]) ) - ncb.previous = sum( w.nplant[sel] * exp(ncbmortconow[sel]) ) - hyd.previous = sum( w.nplant[sel] * exp(hydmortconow[sel]) ) - di.previous = sum( w.nplant[sel] * exp(dimortconow [sel]) ) - szpft$mort [m,d,p] = log( previous / survivor ) - szpft$ncbmort[m,d,p] = log( ncb.previous / survivor ) - szpft$hydmort[m,d,p] = log( hyd.previous / survivor ) - szpft$dimort [m,d,p] = log( di.previous / survivor ) + survivor = sum( w.nplant[sel] ) + previous = sum( w.nplant[sel] * exp(mortconow [sel]) ) + ncb.previous = sum( w.nplant[sel] * exp(ncbmortconow [sel]) ) + hyd.previous = sum( w.nplant[sel] * exp(hydmortconow [sel]) ) + di.previous = sum( w.nplant[sel] * exp(dimortconow [sel]) ) + fl.previous = sum( w.nplant[sel] * exp(fire.lethalconow[sel]) ) + szpft$mort [m,d,p] = log( previous / survivor ) + szpft$ncbmort [m,d,p] = log( ncb.previous / survivor ) + szpft$hydmort [m,d,p] = log( hyd.previous / survivor ) + szpft$dimort [m,d,p] = log( di.previous / survivor ) + szpft$fire.lethal[m,d,p] = log( fl.previous / survivor ) #---------------------------------------------------------------------------# @@ -3445,6 +4296,8 @@ read.q.files <<- function( datum emean$leaf.rshort [m] = szpft$leaf.rshort [m,ndbh+1,npft+1] emean$leaf.rlong [m] = szpft$leaf.rlong [m,ndbh+1,npft+1] emean$leaf.gpp [m] = szpft$leaf.gpp [m,ndbh+1,npft+1] + emean$dmin.leaf.psi [m] = szpft$dmin.leaf.psi [m,ndbh+1,npft+1] + emean$dmax.leaf.psi [m] = szpft$dmax.leaf.psi [m,ndbh+1,npft+1] emean$transp [m] = szpft$transp [m,ndbh+1,npft+1] emean$wue [m] = szpft$wue [m,ndbh+1,npft+1] emean$npp [m] = szpft$npp [m,ndbh+1,npft+1] @@ -3453,6 +4306,7 @@ read.q.files <<- function( datum emean$etue [m] = szpft$etue [m,ndbh+1,npft+1] emean$cue [m] = szpft$cue [m,ndbh+1,npft+1] emean$ecue [m] = szpft$ecue [m,ndbh+1,npft+1] + emean$fire.lethal [m] = szpft$fire.lethal [m,ndbh+1,npft+1] emean$agb.growth [m] = szpft$agb.growth [m,ndbh+1,npft+1] emean$agb.mort [m] = szpft$agb.mort [m,ndbh+1,npft+1] emean$agb.dimort [m] = szpft$agb.dimort [m,ndbh+1,npft+1] @@ -3483,8 +4337,10 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Convert leaf water to kg/m2leaf. # #------------------------------------------------------------------------------------# - emean$leaf.water [m ] = emean$leaf.water[m ] / pmax(emean$lai[m],0.01) - qmean$leaf.water [m,] = qmean$leaf.water[m,] / pmax(emean$lai[m],0.01) + emean$leaf.water [m ] = emean$leaf.water [m ] / pmax(emean$lai[m],0.01) + emean$leaf.water.im2[m ] = emean$leaf.water.im2[m ] / pmax(emean$lai[m],0.01) + qmean$leaf.water [m,] = qmean$leaf.water [m,] / pmax(emean$lai[m],0.01) + qmean$leaf.water.im2[m,] = qmean$leaf.water.im2[m,] / pmax(emean$lai[m],0.01) #------------------------------------------------------------------------------------# @@ -3757,6 +4613,9 @@ read.q.files <<- function( datum clab = paste( "y",sprintf("%4.4i",thisyear ) , "m",sprintf("%2.2i",thismonth),sep="") #----- Binding the current cohorts. ----------------------------------------------# + cohort$isi [[clab]] = isiconow + cohort$lsl [[clab]] = lslconow + cohort$ntext [[clab]] = ntextconow cohort$ipa [[clab]] = ipaconow cohort$ico [[clab]] = icoconow cohort$area [[clab]] = areaconow @@ -3823,10 +4682,11 @@ read.q.files <<- function( datum cohort$etue [[clab]] = etueconow cohort$demand [[clab]] = demandconow cohort$supply [[clab]] = supplyconow - cohort$mort [[clab]] = 100. * (1.0 - exp(-mortconow )) - cohort$ncbmort [[clab]] = 100. * (1.0 - exp(-ncbmortconow )) - cohort$hydmort [[clab]] = 100. * (1.0 - exp(-hydmortconow )) - cohort$dimort [[clab]] = 100. * (1.0 - exp(-dimortconow )) + cohort$mort [[clab]] = 100. * (1.0 - exp(-mortconow )) + cohort$ncbmort [[clab]] = 100. * (1.0 - exp(-ncbmortconow )) + cohort$hydmort [[clab]] = 100. * (1.0 - exp(-hydmortconow )) + cohort$dimort [[clab]] = 100. * (1.0 - exp(-dimortconow )) + cohort$fire.lethal [[clab]] = 100. * (1.0 - exp(-fire.lethalconow)) cohort$recruit [[clab]] = recruitconow cohort$growth [[clab]] = 100. * growthconow cohort$agb.growth [[clab]] = 100. * agb.growthconow @@ -3853,6 +4713,8 @@ read.q.files <<- function( datum cohort$leaf.temp [[clab]] = leaf.tempconow cohort$leaf.vpd [[clab]] = leaf.vpdconow cohort$leaf.gsw [[clab]] = leaf.gswconow + cohort$dmin.leaf.psi[[clab]] = dmin.leaf.psiconow + cohort$dmax.leaf.psi[[clab]] = dmax.leaf.psiconow } #end if month=sasmonth #------------------------------------------------------------------------------------# }# end for (m in tresume,ntimes) @@ -3873,6 +4735,7 @@ read.q.files <<- function( datum datum$lu = lu datum$qmean = qmean datum$qmsqu = qmsqu + datum$site = site datum$patch = patch datum$qpatch = qpatch datum$cohort = cohort @@ -3883,3 +4746,24 @@ read.q.files <<- function( datum }#end function read.q.files #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that updates weighting factors, and checks that there are valid factors. # +# Useful for when the simulation has heterogeneous soil depths. # +#------------------------------------------------------------------------------------------# +reweight.valid <<- function(x){ + xsum = sum(x,na.rm=TRUE) + if (xsum %eq% 0){ + ans = rep(NA_real_,times=length(x)) + }else{ + ans = x / xsum + }#end if + return(ans) +}#end reweight.valid +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/rshort.bdown.r b/R-utils/rshort.bdown.r index d8d4ddc35..0ffc2b9b5 100644 --- a/R-utils/rshort.bdown.r +++ b/R-utils/rshort.bdown.r @@ -1,4 +1,4 @@ -#==========================================================================================# + #==========================================================================================# #==========================================================================================# # This subroutine computes the split between direct and diffuse radiation, and # # between visible and near-infrared radiation. Three methods are provided: # @@ -47,17 +47,18 @@ rshort.bdown <<- function(rad.in,atm.prss,cosz,rad.type=c("rshort","par","nir") if (length(atm.prss) == 1) atm.prss = rep(atm.prss,times=length(rad.in)) #----- Prevent clearness index method to be used when rad.type is not rshort. ----------# - if ( (! rad.method %in% "wn85") && (! (rad.type %in% "rshort")) ){ + if ( (rad.method %in% "sib") && (! (rad.type %in% "rshort")) ){ cat0(" - Radiation method: ",rad.method,".") cat0(" - Input radiation type: ",rad.type,".") - stop(" Radiation input type must be \"rshort\" unless using method \"wn85\".)") + stop(" Radiation input type must be \"rshort\" if using method \"sib\".)") }#end if #---------------------------------------------------------------------------------------# ans = switch( EXPR = rad.method , wn85 = rshort.bdown.weissnorman(rad.in,atm.prss,cosz,rad.type) - , clearidx = rshort.bdown.clearidx (rad.in,atm.prss,cosz,apply.bx10.corr) + , clearidx = rshort.bdown.clearidx (rad.in,atm.prss,cosz,apply.bx10.corr + ,rad.type) , sib = rshort.bdown.sib (rad.in,atm.prss,cosz) )#end switch return(ans) @@ -98,65 +99,38 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz #------ Initialise the radiation with NAs. ---------------------------------------------# - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - rshort.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + rshort.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in + #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %gt% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # - #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - if (rad.type %in% "par"){ - par.diff [night] = rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] / fvis.diff.def - }else if(rad.type %in% "nir"){ - par.diff [night] = fvis.diff.def * rad.in[night] / fnir.diff.def - nir.diff [night] = rad.in[night] - }else{ - par.diff [night] = fvis.diff.def * rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] - }#end if - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - rshort.full [night] = rshort.beam[night] + rshort.diff[night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 - #---------------------------------------------------------------------------------------# - - - - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0) - log10secz = log10(secz) + #----- Save the Chapman function to account for the earth's curvature. -----------------# + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = fvis.beam.def * rshort.beam.toa nir.beam.toa = fnir.beam.def * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -167,7 +141,7 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -178,7 +152,7 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -189,19 +163,30 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot #---------------------------------------------------------------------------------------# @@ -210,11 +195,11 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # Find the actual total for PAR and NIR, using equations 7 and 8. # #---------------------------------------------------------------------------------------# if (rad.type %in% "par"){ - ratio = ifelse(day, rad.in / par.full.pot, 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / par.full.pot) }else if (rad.type %in% "nir"){ - ratio = ifelse(day, rad.in / nir.full.pot, 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / nir.full.pot) }else{ - ratio = ifelse(day, rad.in / (par.full.pot + nir.full.pot), 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / (par.full.pot + nir.full.pot)) }#end if par.full = ratio * par.full.pot nir.full = ratio * nir.full.pot @@ -249,15 +234,46 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz #---------------------------------------------------------------------------------------# # Find the radiation components. # #---------------------------------------------------------------------------------------# - par.beam [day] = fvis.beam.act[day] * par.full[day] - par.diff [day] = fvis.diff.act[day] * par.full[day] - nir.beam [day] = fnir.beam.act[day] * nir.full[day] - nir.diff [day] = fnir.diff.act[day] * nir.full[day] - rshort.beam [day] = par.beam [day] + nir.beam [day] - rshort.diff [day] = par.diff [day] + nir.diff [day] - rshort.full [day] = rshort.beam[day] + rshort.diff[day] + par.beam = fvis.beam.act * par.full + par.diff = fvis.diff.act * par.full + nir.beam = fnir.beam.act * nir.full + nir.diff = fnir.diff.act * nir.full + rshort.beam = par.beam + nir.beam + rshort.diff = par.diff + nir.diff + rshort.full = rshort.beam + rshort.diff #---------------------------------------------------------------------------------------# - rshort.bdown = data.frame( par.beam = par.beam + + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Save output data frame. # + #---------------------------------------------------------------------------------------# + rshort.bdown = data.frame( chapman = chapman + , eff.cosz = eff.cosz + , par.beam = par.beam , par.diff = par.diff , par.full = par.full , nir.beam = nir.beam @@ -286,7 +302,8 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # between visible and near-infrared radiation, using the clearness index method (BD08, # # TW05, BX10). # #------------------------------------------------------------------------------------------# -rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ +rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr + ,rad.type=c("rshort","par","nir")){ #---------------------------------------------------------------------------------------# # Local constants. # #---------------------------------------------------------------------------------------# @@ -307,57 +324,42 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #------ Initialise the radiation with NAs (except for rshort.full). --------------------# - rshort.full = rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + rshort.full = NA_real_ * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %ge% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # - #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - par.diff [night] = tw05.eqn02[1] * rshort.full[night] - nir.diff [night] = (1. - tw05.eqn02[1]) * rshort.full[night] - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 + # Save the Chapman function to account for the earth's curvature and find the # + # effective cosine of the zenith angle. # #---------------------------------------------------------------------------------------# - - - - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0.) - log10secz = log10(secz) + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = tw05.eqn02[1] * rshort.beam.toa nir.beam.toa = (1. - tw05.eqn02[1]) * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -369,7 +371,7 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -380,7 +382,7 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -391,24 +393,62 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Find the clearness index based on total shortwave radiation, then find the # # fraction of PAR radiation as a function of total radiation and clearness index, # # following TW05, eqn. 2. # #---------------------------------------------------------------------------------------# - fkt = ifelse(day,pmax(0.,pmin(1.,rshort.full / rshort.beam.toa)),0.) - fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) - par.full[day] = fpar[day] * rshort.full[day] - nir.full[day] = rshort.full[day] - par.full[day] + if (rad.type %in% "par"){ + par.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., par.full / par.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + rshort.full = par.full / fpar + nir.full = rshort.full - par.full + }else if (rad.type %in% "nir"){ + nir.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., nir.full / nir.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + rshort.full = nir.full / (1.-fpar) + par.full = rshort.full - nir.full + + }else{ + rshort.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., rshort.full / rshort.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + par.full = fpar * rshort.full + nir.full = rshort.full - par.full + }#end if #---------------------------------------------------------------------------------------# - + + #---------------------------------------------------------------------------------------# # Find the uncorrected diffuse fraction based on BD08. We use this equation # @@ -442,12 +482,12 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Find the radiation components. # #---------------------------------------------------------------------------------------# - par.diff [day] = fdiff [day] * par.full[day] - par.beam [day] = par.full[day] - par.diff[day] - nir.diff [day] = fdiff [day] * nir.full[day] - nir.beam [day] = nir.full[day] - nir.diff[day] - rshort.diff[day] = par.diff[day] + nir.diff[day] - rshort.beam[day] = par.beam[day] + nir.beam[day] + par.diff = fdiff * par.full + par.beam = par.full - par.diff + nir.diff = fdiff * nir.full + nir.beam = nir.full - nir.diff + rshort.diff = par.diff + nir.diff + rshort.beam = par.beam + nir.beam #---------------------------------------------------------------------------------------# @@ -455,16 +495,40 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - rshort.bdown = data.frame( par.beam = par.beam + rshort.bdown = data.frame( chapman = chapman + , eff.cosz = eff.cosz + , par.beam = par.beam , par.diff = par.diff , par.full = par.full , nir.beam = nir.beam @@ -512,56 +576,42 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #------ Initialise the radiation with NAs (except for rshort.full). --------------------# rshort.full = rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %gt% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # + # Save the Chapman function to account for the earth's curvature and find the # + # effective cosine of the zenith angle. # #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - par.diff [night] = fvis.diff.def * rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0.) - log10secz = log10(secz) - #---------------------------------------------------------------------------------------# - - #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = fvis.beam.def * rshort.beam.toa nir.beam.toa = fnir.beam.def * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -573,7 +623,7 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -584,7 +634,7 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -595,34 +645,43 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Find the cloud cover estimate and the fraction of diffuse radiation. # #---------------------------------------------------------------------------------------# - cloud = ifelse( day - , pmin(1.,pmax(0.,(csib[5] * cosz - rshort.full) / (csib[4] * cosz))) - , 0.5 - )#end ifelse - difrat = ifelse(day,pmin(1.,pmax(0.,0.0604 / ( cosz -0.0223 ) + 0.0683)),1.0) + cloud = pmin(1.,pmax(0.,(csib[5] * eff.cosz - rshort.full) / (csib[4] * eff.cosz))) + difrat = pmin(1.,pmax(0.,0.0604 / ( eff.cosz -0.0223 ) + 0.0683)) difrat = difrat + ( 1. - difrat ) * cloud vnrat = ( ( csib[1] - cloud*csib[2] ) / ( ( csib[1] - cloud*csib[3] ) + ( csib[1] - cloud*csib[2] )) )#end vnrat - rshort.diff[day] = difrat[day] * vnrat[day] * rshort.full[day] - rshort.beam[day] = rshort.full[day] - rshort.diff[day] - par.diff [day] = fvis.diff.def * rshort.diff[day] - nir.diff [day] = fnir.diff.def * rshort.diff[day] - par.beam [day] = fvis.beam.def * rshort.beam[day] - nir.beam [day] = fnir.beam.def * rshort.beam[day] - par.full [day] = par.diff[day] + par.beam[day] - nir.full [day] = nir.diff[day] + nir.beam[day] + rshort.diff = ifelse(test=day,yes=difrat * vnrat * rshort.full,no=rshort.full) + rshort.beam = rshort.full - rshort.diff + par.diff = fvis.diff.def * rshort.diff + nir.diff = fnir.diff.def * rshort.diff + par.beam = fvis.beam.def * rshort.beam + nir.beam = fnir.beam.def * rshort.beam + par.full = par.diff + par.beam + nir.full = nir.diff + nir.beam #---------------------------------------------------------------------------------------# @@ -630,11 +689,36 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# @@ -657,3 +741,65 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ }#end function rshort.bdown.sib #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# This function calculates the effect of sun angle increasing the optical depth in a # +# sphere. This allows accounting for the diffuse radiation at twilight, using the # +# modified Chapman function following: # +# # +# Reference: # +# # +# Huestis DL. 2001. Accurate evaluation of the chapman function for atmospheric # +# attenuation. J. Quant. Spectrosc. Radiat. Transf., 69: 709-721. # +# doi:10.1016/S0022-4073(00)00107-2 # +# # +# # +# Input variables: # +# - tvir. Virtual temperature, in Kelvin. # +# - cosz. Cosine of the sun's zenith angle. # +# - dzen. Bin width of the zenith angle for the numerical integration # +#------------------------------------------------------------------------------------------# +huestis.fun <<- function(cosz,alt=0.,dzen=0.05){ + #----- Dimensionless curvature ratio. --------------------------------------------------# + xx = ( erad + alt ) / ehgt + #---------------------------------------------------------------------------------------# + + + #---- Create the look-up table. --------------------------------------------------------# + zend.ref = seq(from=0,to=180-dzen,by=dzen) + lambda.ref = mid.points(zend.ref) + nzen = length(zend.ref) + ZEND.REF = matrix(data=zend.ref,nrow=nzen,ncol=nzen,byrow=FALSE) + LAMBDA.REF = matrix(data=zend.ref,nrow=nzen,ncol=nzen,byrow=TRUE ) + LAMBDA.REF = pmin(ZEND.REF,LAMBDA.REF) + DLAMBDA.REF = t(apply(X=LAMBDA.REF,MARGIN=1,FUN=diff)) + LAMBDA.REF = t(apply(X=LAMBDA.REF,MARGIN=1,FUN=mid.points)) + ZEND.REF = ZEND.REF[,-nzen] + SINZ.REF = sin(ZEND.REF*pio180) + SINL.REF = sin(LAMBDA.REF*pio180) + COSL.REF = cos(LAMBDA.REF*pio180) + KERNEL = ifelse( test = SINL.REF %eq% 0. + , yes = 0. + , no = exp(xx*(1.-SINZ.REF/SINL.REF))/(1.+COSL.REF) + )#end ifelse + huestis.ref = 1+xx*sin(zend.ref*pio180) * rowSums(KERNEL*DLAMBDA.REF*pio180) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Create matrices with the reference. # + #---------------------------------------------------------------------------------------# + zend = dzen * round(acos(cosz)/pio180/dzen) + idx = match(zend,zend.ref) + ans = 0.*cosz + c(huestis.ref[idx]) + return(ans) + #---------------------------------------------------------------------------------------# +}#end function huestis.fun +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/sample.by.quant.r b/R-utils/sample.by.quant.r index 6a5e1cb62..05ea05f12 100644 --- a/R-utils/sample.by.quant.r +++ b/R-utils/sample.by.quant.r @@ -37,18 +37,17 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ #----- First we check whether a is valid. ----------------------------------------------# - if (length(a) != 1){ - stop (paste(" Factor a must be a scalar, and you entered one with length " - ,length(a),"...",sep="")) - }#end if + if (! (length(a) %eq% 1L)){ + stop(paste0(" Factor \"a\" must be scalar. The input one has length ",length(a),".")) + }#end if (! (length(a) %eq% 1L)) #---------------------------------------------------------------------------------------# #----- First we check whether x or v are valid. ----------------------------------------# if (missing(x) || missing(v)){ - cat (" - x is missing: ",missing(x),"\n") - cat (" - v is missing: ",missing(v),"\n") - stop(" Either x or v (or both) is missing...") + cat (" - \"x\" is missing: ",missing(x),"\n") + cat (" - \"v\" is missing: ",missing(v),"\n") + stop(" Either \"x\" or \"v\" (or both) is missing.") }else if (length(x) < length(v)){ v.names = as.numeric(names(v)) ix = match(x,v.names) @@ -74,7 +73,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ v = v[as.numeric(names(v)) %in% keep] }else{ ix = sequence(length(x)) - }#end if + }#end if (missing(x) || missing(v)) #---------------------------------------------------------------------------------------# @@ -86,7 +85,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ stop(" Variable method must be scalar!") }else{ use = substring(tolower(method),1,1) - }#end if + }#end if (length(method) != 1) #---------------------------------------------------------------------------------------# @@ -124,7 +123,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = rep(1/nx,times=nx) )#end list - }else if (a == 0){ + }else if (a %in% 0L){ s = sample(x=x,size=nx,replace=TRUE) cnt = table(s) prob = rep(0,times=nx) @@ -137,7 +136,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "p"){ + }else if (use %in% "p"){ prob = abs(a) ^ (sign(a)*(1-2*quant)) @@ -149,7 +148,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "l"){ + }else if (use %in% "l"){ prob = inv.logit((a-sign(a))*(quant-0.5-0.01*a)) s = sample(x=x,size=nx,replace=TRUE,prob=prob) ans = list( orig = x @@ -159,7 +158,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "b"){ + }else if (use %in% "b"){ s = rep(NA,times=nx) prob = abs(a) ^ (sign(a)*quant > sign(a)*0.5) s[1] = sample(x=x,size=1,replace=TRUE,prob=prob) @@ -179,7 +178,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "s"){ + }else if (use %in% "s"){ #----- Find the skew normal statistics. ---------------------------------------------# v.loc = sn.location(x=v,na.rm=TRUE) v.scl = sn.scale (x=v,na.rm=TRUE) @@ -193,8 +192,8 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ s.scl = v.scl s.shp = v.shp d.shp = round.log(abs(s.shp)) - q.100 = qsn(p=0.10,location=s.loc,scale=s.scl,shape=s.shp) - q.900 = qsn(p=0.90,location=s.loc,scale=s.scl,shape=s.shp) + q.100 = qsn(p=0.10,xi=s.loc,omega=s.scl,alpha=s.shp) + q.900 = qsn(p=0.90,xi=s.loc,omega=s.scl,alpha=s.shp) v.min = min(v) v.max = max(v) #it = 0 @@ -207,14 +206,14 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ # if (q.900 > v.max){ # s.shp = s.shp - 0.1 * d.shp # }#end if - # q.100 = qsn(p=0.10,location=s.loc,scale=s.scl,shape=s.shp) - # q.900 = qsn(p=0.90,location=s.loc,scale=s.scl,shape=s.shp) + # q.100 = qsn(p=0.10,xi=s.loc,omega=s.scl,alpha=s.shp) + # q.900 = qsn(p=0.90,xi=s.loc,omega=s.scl,alpha=s.shp) #}#end while #------------------------------------------------------------------------------------# #----- Use the new statistics to find the new distribution. -------------------------# - v.goal = rsn(n=nx,location=s.loc,scale=s.scl,shape=s.shp) + v.goal = rsn(n=nx,xi=s.loc,omega=s.scl,alpha=s.shp) s.idx = mapply(FUN=which.closest,x=v.goal,MoreArgs=list(A=v)) s = x[s.idx] cnt = table(s) @@ -231,10 +230,10 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ #------------------------------------------------------------------------------------# }else{ - stop (paste(" Method ",method," is not recognised...",sep="")) + stop (paste0(" Method ",method," is not recognised.")) }#end if #---------------------------------------------------------------------------------------# return(ans) -}#end function +}#end function sample.by.quant #------------------------------------------------------------------------------------------# diff --git a/R-utils/showutils.r b/R-utils/showutils.r index 304a9a4c7..3194b288d 100644 --- a/R-utils/showutils.r +++ b/R-utils/showutils.r @@ -67,7 +67,7 @@ fill.bg <<- function(pch,col,bg="white",dial=0.0){ #----- Discard colours for those points without background support. --------------------# - rgb.bg = ifelse(test=pch %>% 20,yes=rgb.bg,no="transparent") + rgb.bg = ifelse(test=pch %gt% 20,yes=rgb.bg,no="transparent") #---------------------------------------------------------------------------------------# return(rgb.bg) diff --git a/R-utils/soilutils.r b/R-utils/soilutils.r index 7563cf0a6..b941f11f0 100644 --- a/R-utils/soilutils.r +++ b/R-utils/soilutils.r @@ -122,8 +122,85 @@ nstext.polygon <<- nstext.polygon #==========================================================================================# # This function finds the soil parameters. # #------------------------------------------------------------------------------------------# -soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd - ,out.dfr=FALSE){ +soil.params <<- function( ntext = NA_integer_ + , isoilflg = 1 + , slxsand = NA_real_ + , slxclay = NA_real_ + , slsoc = NA_real_ + , slph = NA_real_ + , slcec = NA_real_ + , sldbd = NA_real_ + , slhydro = ifelse( test = ntext %in% c(12,13) + , yes = ntext + , no = isoil.hydro + )#end ifelse + , out.dfr = FALSE + ){ + + #----- Decide whether to call function recursively. ------------------------------------# + ulen = unique( c(length(ntext),length(isoilflg),length(slxsand),length(slsoc) + ,length(slph),length(slcec),length(sldbd),length(slhydro) + )#end c + )#end unique + if (any(ulen > 1)){ + #----- There are vectors. Ensure all data are either scalar or same-sized vector. ---# + if (any(! ulen %in% c(1,max(ulen)))){ + #----- Stop the execution, the data are inconsistent. ----------------------------# + cat0("---------------------------------------------------------------------") + cat0(" Input data must be either scalars or vectors with the same size.") + cat0("---------------------------------------------------------------------") + cat0(" Length(ntext) = ",length(ntext) ,".") + cat0(" Length(isoilflg) = ",length(isoilflg),".") + cat0(" Length(slxsand) = ",length(slxsand) ,".") + cat0(" Length(slxclay) = ",length(slxclay) ,".") + cat0(" Length(slsoc) = ",length(slsoc) ,".") + cat0(" Length(slph) = ",length(slph) ,".") + cat0(" Length(slcec) = ",length(slcec) ,".") + cat0(" Length(sldbd) = ",length(sldbd) ,".") + cat0(" Length(slhydro) = ",length(slhydro) ,".") + cat0("---------------------------------------------------------------------") + stop(" Dimension mismatch of input variables.") + #---------------------------------------------------------------------------------# + }#end if (any(! ulen %in% c(1,max(ulen)))) + #------------------------------------------------------------------------------------# + + + #----- At this point we are clear. Turn data into vectors. -------------------------# + mxlen = max(ulen) + if (length(ntext ) %in% c(1)) ntext = rep(x=ntext ,times=mxlen) + if (length(isoilflg) %in% c(1)) isoilflg = rep(x=isoilflg,times=mxlen) + if (length(slxsand ) %in% c(1)) slxsand = rep(x=slxsand ,times=mxlen) + if (length(slxclay ) %in% c(1)) slxclay = rep(x=slxclay ,times=mxlen) + if (length(slsoc ) %in% c(1)) slsoc = rep(x=slsoc ,times=mxlen) + if (length(slph ) %in% c(1)) slph = rep(x=slph ,times=mxlen) + if (length(slcec ) %in% c(1)) slcec = rep(x=slcec ,times=mxlen) + if (length(sldbd ) %in% c(1)) sldbd = rep(x=sldbd ,times=mxlen) + if (length(slhydro ) %in% c(1)) slhydro = rep(x=slhydro ,times=mxlen) + #------------------------------------------------------------------------------------# + + + #----- Use mapply to run the function. ----------------------------------------------# + ans = mapply( FUN = soil.params + , ntext = as.list(ntext ) + , isoilflg = as.list(isoilflg) + , slxsand = as.list(slxsand ) + , slxclay = as.list(slxclay ) + , slsoc = as.list(slsoc ) + , slph = as.list(slph ) + , slcec = as.list(slcec ) + , sldbd = as.list(sldbd ) + , slhydro = as.list(slhydro ) + , MoreArgs = list(out.dfr=out.dfr) + , SIMPLIFY = FALSE + )#end mapply + if (out.dfr) ans = do.call(what="rbind",args=ans) + return(ans) + #------------------------------------------------------------------------------------# + }#end if (any(ulen > 1)) + #---------------------------------------------------------------------------------------# + + + #----- Define some prescribed fractions. -----------------------------------------------# xsand.def = c( 0.920, 0.825, 0.660, 0.200, 0.410, 0.590 , 0.100, 0.320, 0.520, 0.060, 0.200, 0.200 @@ -142,6 +219,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd slpotst.MPa = 5.e-4 # "saturated" soil approximation for van Genuchten [ MPa] slpotth.MPa = 0.01 # soil-water potential: field capacity (Tomasella-Hodnett) [ MPa] slpotsr.MPa = 0.033 # soil-water potential: field capacity (Saxton-Rawls) [ MPa] + slpotdg.MPa = 5.0 # soil-water potential: air dry soil (van Genuchten) [ MPa] slpotcp.MPa = 3.1 # soil-water potential: air dry soil [ MPa] slpotwp.MPa = 1.5 # soil-water potential: wilting point [ MPa] slpotld.MPa = 0.75 # soil-water potential that plants start dropping leaves [ MPa] @@ -228,7 +306,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Find soil class and sand, silt, and clay fractions. # #---------------------------------------------------------------------------------------# - if (missing(slxsand) || missing(slxclay) || missing(isoilflg)){ + if (is.na(slxsand) || is.na(slxclay) || is.na(isoilflg)){ mysoil$ntext = ntext mysoil$name = soil.name[mysoil$ntext] mysoil$key = soil.key [mysoil$ntext] @@ -236,9 +314,9 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$xclay = xclay.def[ntext] mysoil$xsilt = 1. - mysoil$xsand - mysoil$xclay }else if (isoilflg == 2 & slxsand > 0 & slxclay > 0 & (slxsand + slxclay) < 1 ){ - mysoil$ntext = sclass(slxsand,slxclay) - mysoil$name = soil.name[mysoil$ntext] - mysoil$key = soil.key [mysoil$ntext] + mysoil$ntext = if(is.na(ntext)){sclass(sandfrac=slxsand,clayfrac=slxclay)}else{ntext} + mysoil$name = "User" + mysoil$key = "User" mysoil$xsand = slxsand mysoil$xclay = slxclay mysoil$xsilt = 1. - mysoil$xsand - mysoil$xclay @@ -255,11 +333,11 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #----- Decide which method to use. -----------------------------------------------------# - if ( mysoil$ntext %in% 13){ + if ( slhydro %in% 13){ mysoil$method = "BDRK" - }else if ( (mysoil$ntext %in% c(12)) || isoil.hydro %in% c(0,1)){ + }else if ( slhydro %in% c(0,1,12)){ mysoil$method = "BC64" - }else if (isoil.hydro %in% 2){ + }else if (slhydro %in% 2){ mysoil$method = "vG80" }else{ mysoil$method = "SR06" @@ -272,7 +350,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# if (mysoil$method %in% "vG80"){ #----- Make sure all required variables are provided. -------------------------------# - fine = ! (missing(slsoc) || missing(slph) || missing(slcec) || missing(sldbd)) + fine = ! (is.na(slsoc) || is.na(slph) || is.na(slcec) || is.na(sldbd)) if (fine){ #----- Copy values from inputs. --------------------------------------------------# mysoil$slsoc = slsoc @@ -284,10 +362,10 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #----- Missing data, issue an error message. -------------------------------------# cat0("---------------------------------------------------------------------------") cat0(" Missing parameters for isoil.hydro = 2 (Hodnett and Tomasella 2002)! ") - cat0(" Missing \"slsoc\" = ",missing(slsoc),".") - cat0(" Missing \"slph\" = ",missing(slph) ,".") - cat0(" Missing \"slcec\" = ",missing(slcec),".") - cat0(" Missing \"sldbd\" = ",missing(sldbd),".") + cat0(" Missing \"slsoc\" = ",is.na(slsoc),".") + cat0(" Missing \"slph\" = ",is.na(slph) ,".") + cat0(" Missing \"slcec\" = ",is.na(slcec),".") + cat0(" Missing \"sldbd\" = ",is.na(sldbd),".") cat0("---------------------------------------------------------------------------") stop(" Invalid settings for soil.params.") #---------------------------------------------------------------------------------# @@ -295,7 +373,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #------------------------------------------------------------------------------------# }else if (mysoil$method %in% "SR06"){ #----- Make sure all required variables are provided. -------------------------------# - fine = ! (missing(slsoc) || missing(slph) || missing(slcec) || missing(sldbd)) + fine = ! is.na(slsoc) if (fine){ #----- Copy values from inputs. --------------------------------------------------# mysoil$slsoc = slsoc @@ -311,16 +389,16 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #------------------------------------------------------------------------------------# #----- Variables are dummy but we honour the input variables if provided. -----------# - if (! missing(slph )) mysoil$slph = slph - if (! missing(slcec)) mysoil$slcec = slcec - if (! missing(sldbd)) mysoil$sldbd = sldbd + mysoil$slph = slph + mysoil$slcec = slcec + mysoil$sldbd = sldbd #------------------------------------------------------------------------------------# }else{ #----- Variables are dummy but we honour the input variables if provided. -----------# - if (! missing(slsoc)) mysoil$slsoc = slsoc - if (! missing(slph )) mysoil$slph = slph - if (! missing(slcec)) mysoil$slcec = slcec - if (! missing(sldbd)) mysoil$sldbd = sldbd + mysoil$slsoc = slsoc + mysoil$slph = slph + mysoil$slcec = slcec + mysoil$sldbd = sldbd #------------------------------------------------------------------------------------# }#end if (mysoil$method %in% "vG1980") #---------------------------------------------------------------------------------------# @@ -330,11 +408,11 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Set up primary properties. # #---------------------------------------------------------------------------------------# - if (mysoil$ntext == 13){ + if (slhydro == 13){ #----- Bedrock. Most things are zero, because it is an impermeable soil. -----------# mysoil$slcpd = 2130000. #------------------------------------------------------------------------------------# - }else if (mysoil$ntext == 12){ + }else if (slhydro == 12){ #------------------------------------------------------------------------------------# # Peat. High concentration of organic matter. Mineral soil equations don't # # apply here. # @@ -358,7 +436,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 0){ + }else if (slhydro == 0){ #------------------------------------------------------------------------------------# # Mineral soil. Use the standard ED-2.2 equations. # #------------------------------------------------------------------------------------# @@ -386,7 +464,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotfc = smoist2mpot(mysoil$sfldcap, mysoil) mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) - }else if (isoil.hydro == 1){ + }else if (slhydro == 1){ #------------------------------------------------------------------------------------# # Use Tomasella and Hodnett (1998). # #------------------------------------------------------------------------------------# @@ -431,7 +509,8 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 2){ + }else if (slhydro == 2){ + #------------------------------------------------------------------------------------# # Use Hodnett and Tomasella (2002). # #------------------------------------------------------------------------------------# @@ -483,7 +562,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 3){ + }else if (slhydro == 3){ #------------------------------------------------------------------------------------# # Use Saxton and Rawls (2006). # #------------------------------------------------------------------------------------# @@ -542,9 +621,13 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Calculate the derived properties in case this is not bedrock. # #---------------------------------------------------------------------------------------# - if (mysoil$ntext != 13){ + if (slhydro != 13){ mysoil$fhydraul = 2.0 - mysoil$slpotcp = - slpotcp.MPa * 1.e6 / ( wdns * grav ) + if (mysoil$method %in% "vG80"){ + mysoil$slpotcp = - slpotdg.MPa * 1.e6 / ( wdns * grav ) + }else{ + mysoil$slpotcp = - slpotcp.MPa * 1.e6 / ( wdns * grav ) + }#end if (mysoil$method %in% "vG80") mysoil$slpotld = - slpotld.MPa * 1.e6 / ( wdns * grav ) mysoil$slpotfr = - slpotfr.MPa * 1.e6 / ( wdns * grav ) mysoil$soilcp = mpot2smoist(mysoil$slpotcp, mysoil) @@ -584,16 +667,16 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Make sure everything makes sense. In case it doesn't, check. # #---------------------------------------------------------------------------------------# - cp.fine = all(mysoil$soilre %<=% mysoil$soilcp ) - wp.fine = all(mysoil$soilcp %<=% mysoil$soilwp ) - fc.fine = all(mysoil$soilwp %<=% mysoil$sfldcap) - po.fine = all(mysoil$sfldcap %<=% mysoil$slmsts ) + cp.fine = all(mysoil$soilre %le% mysoil$soilcp ) + wp.fine = all(mysoil$soilcp %le% mysoil$soilwp ) + fc.fine = all(mysoil$soilwp %le% mysoil$sfldcap) + po.fine = all(mysoil$sfldcap %le% mysoil$slmsts ) if (! (cp.fine && wp.fine && fc.fine && po.fine) ) browser() #---------------------------------------------------------------------------------------# #----- Select the output format according to the users' choice. ------------------------# - if (out.dfr) mysoil = as.data.frame(mysoil,stringsAsFactors=FALSE) + if (out.dfr) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) #---------------------------------------------------------------------------------------# return(mysoil) @@ -618,12 +701,28 @@ sclass <<- function(sandfrac,clayfrac){ silt = 100. - sand - clay #---------------------------------------------------------------------------------------# + + #----- If the fractions are vectors, use mapply to get the answer. ---------------------# + if (length(sand) > 1){ + l.sand = as.list(0.01*sand) + l.clay = as.list(0.01*clay) + ans = mapply( FUN = sclass + , sandfrac = l.sand + , clayfrac = l.clay + , SIMPLIFY = TRUE + )#end mapply + return(ans) + }#end if + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Here there is not much we can do other than explore where in the triangle space # # we are. # #---------------------------------------------------------------------------------------# - - if (silt > 100. | silt < 0. | sand > 100. | sand < 0. | clay > 100. | clay < 0. ) { + if ( is.na(silt) || is.na(sand) || is.na(clay) ){ + mysoil = NA_integer_ + }else if (silt > 100. | silt < 0. | sand > 100. | sand < 0. | clay > 100. | clay < 0. ) { print("---------------------------------------------------") print(" At least one of your percentages is screwy...") print(paste0("SAND = ",sprintf("%.2f",sand),"%")) @@ -755,30 +854,77 @@ soil.idx2water <<- function(soil.index,soil){ # Function that converts matric potential (m) into soil moisture (m3/m3). # #------------------------------------------------------------------------------------------# smoist2mpot <<- function(smoist,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "BDRK"){ - #----- Bedrock, ignore. -------------------------------------------------------------# - mpot = 0. - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$soilpo - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - mpot = mysoil$slpotbp * (smfrac^mysoil$slmu - 1.)^(1.-mysoil$slmm) - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "SR06"){ - #----- Saxton and Rawls (2006). -----------------------------------------------------# - smbelow = pmin(1.,smoist/mysoil$sfldcap) - smabove = pmax(0.,smoist - mysoil$sfldcap) - mpot = with(mysoil, slpotfc / smbelow^slbs + slas * smabove) - #------------------------------------------------------------------------------------# - }else{ - #----- Brooks and Corey (1964). -----------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$slmsts - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - mpot = mysoil$slpots / smfrac ^ mysoil$slbs - #------------------------------------------------------------------------------------# - }#end if (mysoil$method %in% "vG80") + + + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nsmoist = length(smoist) + if (nmysoil == 1){ + idx = rep(1,times=nsmoist) + mysoil = mysoil[idx,] + }else if (nmysoil != nsmoist){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between smoist and mysoil!" ) + cat0(" - length(smoist): ",nsmoist ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match smoist length.") + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + mpot = NA_real_ * smoist + smbelow = NA_real_ * smoist + smabove = NA_real_ * smoist + smfrac = NA_real_ * smoist + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + sr06 = mysoil$method %in% "SR06" + bc64 = mysoil$method %in% "BC64" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + mpot[bdrk] = 0. + #---------------------------------------------------------------------------------------# + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac[vg80] = with( mysoil + , (smoist[vg80] - soilre[vg80]) / (soilpo[vg80] - soilre[vg80]) + )#end with + smfrac[vg80] = 0. * smfrac[vg80] + pmax(0.,pmin(1.,smfrac[vg80])) + mpot [vg80] = with( mysoil + , slpotbp[vg80] * (smfrac[vg80]^slmu[vg80] - 1.)^(1.-slmm[vg80]) + )#end with + #----- Saxton and Rawls (2006). --------------------------------------------------------# + smbelow[sr06] = pmin(1.,smoist[sr06] / mysoil$sfldcap[sr06]) + smabove[sr06] = pmax(0.,smoist[sr06] - mysoil$sfldcap[sr06]) + mpot [sr06] = with(mysoil + , slpotfc[sr06] + / smbelow[sr06]^slbs[sr06] + slas[sr06] * smabove[sr06] + )#end with + #---------------------------------------------------------------------------------------# + #----- Brooks and Corey (1964). --------------------------------------------------------# + smfrac[bc64] = with( mysoil + , (smoist[bc64] - soilre[bc64]) / (slmsts[bc64] - soilre[bc64]) + )#end with + smfrac[bc64] = 0. * smfrac[bc64] + pmax(0.,pmin(1.,smfrac[bc64])) + mpot [bc64] = mysoil$slpots[bc64] / smfrac[bc64] ^ mysoil$slbs[bc64] + #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# return(mpot) @@ -796,33 +942,73 @@ smoist2mpot <<- function(smoist,mysoil){ # Function that converts soil moisture (m3/m3) into matric potential (m). # #------------------------------------------------------------------------------------------# mpot2smoist <<- function(mpot,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "BDRK"){ - #----- Bedrock, ignore. -------------------------------------------------------------# - smoist = 0. - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = ( 1. / ( 1. + (mysoil$malpha*mpot)^mysoil$slnm) )^mysoil$slmm - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - smoist = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$soilpo - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "SR06"){ - #----- Saxton and Rawls (2006). -----------------------------------------------------# - smoist = with( mysoil - , ifelse( test = mpot %<% slpotfc - , yes = sfldcap * ( slpotfc / mpot ) ^ (1. / slbs ) - , no = sfldcap + ( slpotfc - slpots) / slas - )#end ifelse - )#end with - #------------------------------------------------------------------------------------# - }else{ - #----- Brooks and Corey (1964). -----------------------------------------------------# - smfrac = ( mysoil$slpots / mpot ) ^ mysoil$slnm - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - smoist = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$slmsts - #------------------------------------------------------------------------------------# - }#end if (mysoil$method %in% "vG80") + + + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nmpot = length(mpot ) + if (nmysoil == 1){ + idx = rep(1,times=nmpot) + mysoil = mysoil[idx,] + }else if (nmysoil != nmpot){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between mpot and mysoil!" ) + cat0(" - length(mpot): ",nmpot ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match mpot length." ) + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + smoist = NA_real_ * mpot + smfrac = NA_real_ * mpot + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + sr06 = mysoil$method %in% "SR06" + bc64 = mysoil$method %in% "BC64" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + smoist[bdrk] = 0. + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac[vg80] = with( mysoil + , ( 1. / ( 1. + (malpha[vg80]*mpot[vg80])^slnm[vg80]) )^slmm[vg80] + )#end with + smfrac[vg80] = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) + smoist[vg80] = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$soilpo + #---------------------------------------------------------------------------------------# + #----- Saxton and Rawls (2006). --------------------------------------------------------# + smoist[sr06] = with( mysoil + , ifelse( test = mpot[sr06] %lt% slpotfc[sr06] + , yes = sfldcap[sr06] + * ( slpotfc[sr06] / mpot[sr06] ) ^ (1. / slbs[sr06] ) + , no = sfldcap[sr06] + + ( slpotfc[sr06] - slpots[sr06]) / slas[sr06] + )#end ifelse + )#end with + #----- Brooks and Corey (1964). --------------------------------------------------------# + smfrac[bc64] = ( mysoil$slpots[bc64] / mpot[bc64] ) ^ mysoil$slnm[bc64] + smfrac[bc64] = 0. * smfrac[bc64] + pmax(0.,pmin(1.,smfrac[bc64])) + smoist[bc64] = with( mysoil + , (1. - smfrac[bc64]) * soilre[bc64] + smfrac[bc64] * slmsts[bc64] + )#end with #---------------------------------------------------------------------------------------# @@ -844,21 +1030,66 @@ mpot2smoist <<- function(mpot,mysoil){ smoist2hydcond <<- function(smoist,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$soilpo - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - fibf = 1. - (1. - smfrac^(1./mysoil$slmm))^mysoil$slmm - hydcond = mysoil$slcons * smfrac ^ mysoil$sltt * fibf * fibf - #------------------------------------------------------------------------------------# - }else{ - #----- Saxton and Rawls (2006) or Brooks and Corey (1964). --------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$slmsts - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - hydcond = mysoil$slcons * smfrac ^ mysoil$slmm - #------------------------------------------------------------------------------------# - }#end if + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nsmoist = length(smoist) + if (nmysoil == 1){ + idx = rep(1,times=nsmoist) + mysoil = mysoil[idx,] + }else if (nmysoil != nsmoist){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between smoist and mysoil!" ) + cat0(" - length(smoist): ",nsmoist ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match smoist length.") + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + mpot = NA_real_ * smoist + smfrac = NA_real_ * smoist + hydcond = NA_real_ * smoist + fibf = NA_real_ * smoist + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + cm76 = mysoil$method %in% c("SR06","BC64") + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + hydcond[bdrk] = 0. + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac [vg80] = with( mysoil + , (smoist[vg80] - soilre[vg80]) / (soilpo[vg80] - soilre[vg80]) + )#end with + smfrac [vg80] = 0. * smfrac[vg80] + pmax(0.,pmin(1.,smfrac[vg80])) + fibf [vg80] = with( mysoil + , 1. - (1. - smfrac[vg80]^(1./slmm[vg80]))^slmm[vg80] + )#end with + hydcond[vg80] = with( mysoil + , slcons[vg80] * smfrac[vg80] ^ sltt[vg80] * fibf[vg80] * fibf[vg80] + )#end with + #----- Saxton and Rawls (2006) or Brooks and Corey (1964). -----------------------------# + smfrac [cm76] = with( mysoil + , (smoist[cm76] - soilre[cm76]) / (soilpo[cm76] - soilre[cm76]) + )#end with + smfrac [cm76] = 0. * smfrac[cm76] + pmax(0.,pmin(1.,smfrac[cm76])) + hydcond[cm76] = with(mysoil,slcons[cm76] * smfrac[cm76] ^ slmm[cm76]) #---------------------------------------------------------------------------------------# hydcond = 0. * hydcond + pmax(hydcond.min,hydcond) diff --git a/R-utils/spei.r b/R-utils/spei.r index 3d9be3db9..73381d870 100644 --- a/R-utils/spei.r +++ b/R-utils/spei.r @@ -128,7 +128,7 @@ spei <<- function( x # Find the standardised values of p3cdf: # #-----------------------------------------------------------------------------------# # P = 1. - cdf - # FS = ifelse( test = P %<=% 0.5, yes = 1.0, no = -1.0) + # FS = ifelse( test = P %le% 0.5, yes = 1.0, no = -1.0) # PUSE = 0.5 - sqrt((P - 0.5)^2) # W = sqrt(-2. * log(PUSE)) #-----------------------------------------------------------------------------------# diff --git a/R-utils/stipples.r b/R-utils/stipples.r index b2aac4aa4..8766b2db3 100644 --- a/R-utils/stipples.r +++ b/R-utils/stipples.r @@ -6,7 +6,7 @@ stipples <<- function(xleft,ybottom,xright,ytop,density=2,pch=".",cex=0.7,col="b #----- Check that coordinates are all provided. ----------------------------------------# stopifnot(! ( missing(xleft) | missing(ybottom) | missing(xright) | missing(ytop)) ) - stopifnot(density %>% 0) + stopifnot(density %gt% 0) #---------------------------------------------------------------------------------------# diff --git a/R-utils/summnum.r b/R-utils/summnum.r index 577474be9..e3c4ce16e 100644 --- a/R-utils/summnum.r +++ b/R-utils/summnum.r @@ -66,7 +66,7 @@ summnum <<- function(x,byrow=FALSE,finite.only=TRUE,neverlog=NULL,is.debug=FALSE #----- Second, ensure that zeroes are relatively rare. ------------------------------# - few.zeroes = ans$min %>=% 0. & ans$q100 %>% 0 + few.zeroes = ans$min %ge% 0. & ans$q100 %gt% 0 #------------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ summnum <<- function(x,byrow=FALSE,finite.only=TRUE,neverlog=NULL,is.debug=FALSE , no = NA_real_ )#end ifelse )#end with - lognorm.is.better = ln.lnorm %>=% ln.norm + lognorm.is.better = ln.lnorm %ge% ln.norm #------------------------------------------------------------------------------------# @@ -146,7 +146,7 @@ summnum.int <<- function(x,finite.only){ if ("try-error" %in% is(wcm.2)){wcm.2 = NA}else if (is.null(wcm.2)){wcm.2 = NA} if ("try-error" %in% is(wcm.1)){wcm.1 = NA}else if (is.null(wcm.1)){wcm.1 = NA} - #if (! all(c(wcm.1,wcm.2,wcm.3) %==% c("lapply","sapply","summnum"))){ + #if (! all(c(wcm.1,wcm.2,wcm.3) %eq% c("lapply","sapply","summnum"))){ # stop(" Function summnum.int is internal, and must be called through summnum","\n") #}#end if #---------------------------------------------------------------------------------------# @@ -181,7 +181,7 @@ summnum.int <<- function(x,finite.only){ , skew = skew(x,na.rm=TRUE) , kurt = kurt(x,na.rm=TRUE) , navl = sum (! is.na(x)) - , npos = sum (x %<% 0) + , npos = sum (x %lt% 0) , ntot = nx )#end c }else{ @@ -244,7 +244,7 @@ lnlike.comp <<- function(x,xlab="nothing"){ if ("try-error" %in% is(wcm.2)){wcm.2 = NA}else if (is.null(wcm.2)){wcm.2 = NA} if ("try-error" %in% is(wcm.1)){wcm.1 = NA}else if (is.null(wcm.1)){wcm.1 = NA} - #if (! all(c(wcm.1,wcm.2,wcm.3) %==% c("lapply","sapply","summnum"))){ + #if (! all(c(wcm.1,wcm.2,wcm.3) %eq% c("lapply","sapply","summnum"))){ # stop(" Function sw.pvalue is internal and must be called through summnum","\n") #}#end if #---------------------------------------------------------------------------------------# @@ -258,7 +258,7 @@ lnlike.comp <<- function(x,xlab="nothing"){ #----- Make sure x is a simple vector. Keep only the positive terms. ------------------# x = as.numeric(unlist(c(x))) - lnx = ifelse(test=x %>% 0,yes=log(x),no=NA_real_) + lnx = ifelse(test=x %gt% 0,yes=log(x),no=NA_real_) sel = is.finite(lnx) x = x [sel] lnx = lnx[sel] diff --git a/R-utils/sw.test.r b/R-utils/sw.test.r index 82e6dea01..a58db67b2 100644 --- a/R-utils/sw.test.r +++ b/R-utils/sw.test.r @@ -46,7 +46,7 @@ sw.test <<- function(x){ #-------------------------------------------------------------------------------------# # Decide which method to use based on the kurtosis. # #-------------------------------------------------------------------------------------# - if (kurt(x) %>% 3){ + if (kurt(x) %gt% 3){ #----------------------------------------------------------------------------------# # Use Shapiro-Francia as the sample is leptokurtic. The Shapiro-Francia # # statistic W is calculated to avoid excessive rounding errors for W close to 1 # diff --git a/R-utils/taxonutils.r b/R-utils/taxonutils.r index 1a87b6d67..e4fc97b57 100644 --- a/R-utils/taxonutils.r +++ b/R-utils/taxonutils.r @@ -5,8 +5,9 @@ unknown.wildcard <<- c("aff","cf","deleteme","ind","indet","na","ni","sp","s ,paste0("spb" ,sequence(99)) ,paste0("spp" ,sequence(99)) ,paste0("sp" ,sequence(99),"cay-atdn") - ,paste0("sp" ,sequence(99),"guyafor") - ,paste0("spfg",sequence(99),"-holst") + ,paste0("sp" ,sequence(99),"-cay" ) + ,paste0("sp" ,sequence(99),"guyafor" ) + ,paste0("spfg",sequence(99),"-holst" ) )#end c unknown.common <<- "mato" unk.liana.common <<- "cipo" @@ -73,7 +74,7 @@ standard.common.name <<- function(x){ x = gsub(pattern="^quina-quina" ,replacement="quinaquina" ,x=x) x = gsub(pattern="^tamarino" ,replacement="tamarindo" ,x=x) x = gsub(pattern="^taxi" ,replacement="tachi" ,x=x) - x = gsub(pattern="^uchi" ,replacement="uxi" ,x=x) + x = gsub(pattern="^uxi" ,replacement="uchi" ,x=x) x = gsub(pattern="verdadiera" ,replacement="verdadeira" ,x=x) x = gsub(pattern="^xixua" ,replacement="chichua" ,x=x) #---------------------------------------------------------------------------------------# @@ -83,7 +84,10 @@ standard.common.name <<- function(x){ #----- Full replacements. --------------------------------------------------------------# sel = (x %in% "?" ); x[sel] = NA_character_ sel = (x %in% "abacaba" ); x[sel] = "bacaba" + sel = (x %in% "abacabeira" ); x[sel] = "bacaba" sel = (x %in% "abicuiba" ); x[sel] = "ucuuba" + sel = (x %in% "abirana" ); x[sel] = "abiurana" + sel = (x %in% "abirana branca" ); x[sel] = "abiurana branca" sel = (x %in% "abirana rosadinha" ); x[sel] = "abiu rosadinho" sel = (x %in% "abil fura fura" ); x[sel] = "abiu-fura-fura" sel = (x %in% "abiui" ); x[sel] = "abiu" @@ -96,12 +100,16 @@ standard.common.name <<- function(x){ sel = (x %in% "abiu guajara" ); x[sel] = "abiu-guajara" sel = (x %in% "abiu goiabao" ); x[sel] = "abiu-goiabao" sel = (x %in% "abiu mangabinha" ); x[sel] = "abiu-mangabinha" + sel = (x %in% "abiu rosadinha" ); x[sel] = "abiu rosadinho" sel = (x %in% "abiu tauari" ); x[sel] = "tauari" sel = (x %in% "abiu vermelha" ); x[sel] = "abiu vermelho" sel = (x %in% "abiurana vermelho" ); x[sel] = "abiurana vermelha" sel = (x %in% "abiurana vermlho" ); x[sel] = "abiurana vermelha" sel = (x %in% "abiuarana" ); x[sel] = "abiurana" sel = (x %in% "abiurana rosadinha" ); x[sel] = "abiu rosadinho" + sel = (x %in% "acaizeiro" ); x[sel] = "acai" + sel = (x %in% "acariguara" ); x[sel] = "acariquara" + sel = (x %in% "acariguarana" ); x[sel] = "acariquarana" sel = (x %in% "acoita cavalo" ); x[sel] = "acoita-cavalo" sel = (x %in% "algodao brabo" ); x[sel] = "algodao-bravo" sel = (x %in% "algodao bravo" ); x[sel] = "algodao-bravo" @@ -139,16 +147,19 @@ standard.common.name <<- function(x){ sel = (x %in% "baubarana" ); x[sel] = "embaubarana" sel = (x %in% "breu/louro preto?" ); x[sel] = NA_character_ sel = (x %in% "breu aroeira" ); x[sel] = "breu-aroeira" + sel = (x %in% "breu brrote" ); x[sel] = "breu barrote" sel = (x %in% "breu sucuruba" ); x[sel] = "breu-sucuruba" sel = (x %in% "breu sucuruba branco" ); x[sel] = "breu-sucuruba branco" sel = (x %in% "breu sucurubinha" ); x[sel] = "breu-sucurubinha" + sel = (x %in% "brteu branco" ); x[sel] = "breu branco" sel = (x %in% "babao" ); x[sel] = "macauba" sel = (x %in% "bolao" ); x[sel] = "fava-bolota" sel = (x %in% "bombeira" ); x[sel] = "pau-pombo" sel = (x %in% "brau" ); x[sel] = "breu" - sel = (x %in% "brejauba" ); x[sel] = "brejauva" - sel = (x %in% "breu sucuuba" ); x[sel] = "breu sucuruba" - sel = (x %in% "cabeca de urubu" ); x[sel] = "cabeca-de-urubu" + sel = (x %in% "brejauba" ); x[sel] = "brejauva" + sel = (x %in% "breu sucuuba" ); x[sel] = "breu sucuruba" + sel = (x %in% "burra leteira" ); x[sel] = "burra leiteira" + sel = (x %in% "cabeca de urubu" ); x[sel] = "cabeca-de-urubu" sel = (x %in% "cabela" ); x[sel] = "louro canela" sel = (x %in% "cabriuva" ); x[sel] = "cabreuva" sel = (x %in% "cabriuna" ); x[sel] = "cabreuva" @@ -156,8 +167,9 @@ standard.common.name <<- function(x){ sel = (x %in% "cabreuba" ); x[sel] = "cabreuva" sel = (x %in% "caca piolho" ); x[sel] = "mata-piolho" sel = (x %in% "cacau bravo" ); x[sel] = "cacaui" - sel = (x %in% "cacau da mata" ); x[sel] = "cacau" - sel = (x %in% "cacaurana" ); x[sel] = "cacau" + sel = (x %in% "cacau da mata" ); x[sel] = "cacau" + sel = (x %in% "cacau do mato" ); x[sel] = "cacau" + sel = (x %in% "cacaurana" ); x[sel] = "cacau" sel = (x %in% "cachixa" ); x[sel] = "caxixa" sel = (x %in% "cachudinha" ); x[sel] = "cascudinha" sel = (x %in% "cagaca" ); x[sel] = "abiurana-cagaca" @@ -183,7 +195,9 @@ standard.common.name <<- function(x){ sel = (x %in% "capueiro branco" ); x[sel] = "capueiro" sel = (x %in% "caqui branco" ); x[sel] = "caqui" sel = (x %in% "caqui folha grande" ); x[sel] = "caqui" - sel = (x %in% "carobia" ); x[sel] = "caroba" + sel = (x %in% "carana" ); x[sel] = NA_character_ + sel = (x %in% "carape" ); x[sel] = "caripe" + sel = (x %in% "carobia" ); x[sel] = "caroba" sel = (x %in% "cascudinho" ); x[sel] = "cascudinha" sel = (x %in% "cascudo" ); x[sel] = "cascudinha" sel = (x %in% "castanha do brasil" ); x[sel] = "castanha-do-para" @@ -196,7 +210,8 @@ standard.common.name <<- function(x){ sel = (x %in% "castanha de sapocaia" ); x[sel] = "castanha-sapucaia" sel = (x %in% "castanha de sapucaia" ); x[sel] = "castanha-sapucaia" sel = (x %in% "castanha sapocaia" ); x[sel] = "castanha-sapucaia" - sel = (x %in% "castanheira" ); x[sel] = "castanha-do-para" + sel = (x %in% "castanha sapucaia" ); x[sel] = "castanha-sapucaia" + sel = (x %in% "castanheira" ); x[sel] = "castanha-do-para" sel = (x %in% "cauba" ); x[sel] = "macacauba" sel = (x %in% "cauxo" ); x[sel] = "caucho" sel = (x %in% "caxeta" ); x[sel] = "caixeta" @@ -263,8 +278,9 @@ standard.common.name <<- function(x){ sel = (x %in% "envira cabo de rodo" ); x[sel] = "envira cabo-de-rodo" sel = (x %in% "envira caju" ); x[sel] = "envira-caju" sel = (x %in% "envira conduru" ); x[sel] = "envira-conduru" - sel = (x %in% "envira cunauaru" ); x[sel] = "envira-cunauaru" - sel = (x %in% "envira de caju" ); x[sel] = "envira-jacu" + sel = (x %in% "envira cunacaru" ); x[sel] = "envira-cunauaru" + sel = (x %in% "envira cunauaru" ); x[sel] = "envira-cunauaru" + sel = (x %in% "envira de caju" ); x[sel] = "envira-jacu" sel = (x %in% "envira de jacu" ); x[sel] = "envira-jacu" sel = (x %in% "envira-mao-de-onca" ); x[sel] = "envira mao-de-onca" sel = (x %in% "envira molia branco" ); x[sel] = "envira-molia branco" @@ -304,19 +320,25 @@ standard.common.name <<- function(x){ sel = (x %in% "fava orelha" ); x[sel] = "fava orelha-de-macaco" sel = (x %in% "fava orelha de macaco" ); x[sel] = "fava orelha-de-macaco" sel = (x %in% "fava paricarana" ); x[sel] = "fava-paricana" + sel = (x %in% "fava rosa" ); x[sel] = "fava-de-rosca" sel = (x %in% "fava saboeira" ); x[sel] = "fava-saboeira" - sel = (x %in% "fava tambori" ); x[sel] = "fava-tamboril" + sel = (x %in% "fava saboeiro" ); x[sel] = "fava-saboeira" + sel = (x %in% "fava tambori" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamburi" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamboril" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamboriu" ); x[sel] = "fava-tamboril" - sel = (x %in% "favera amargosa" ); x[sel] = "fava amargosa" - sel = (x %in% "faveira branca" ); x[sel] = "fava branca" - sel = (x %in% "feijo branco" ); x[sel] = "freijo branco" + sel = (x %in% "faveira" ); x[sel] = "fava" + sel = (x %in% "faveira amargosa" ); x[sel] = "fava amargosa" + sel = (x %in% "faveira branca" ); x[sel] = "fava branca" + sel = (x %in% "faveira rosa" ); x[sel] = "fava-de-rosca" + sel = (x %in% "favera amargosa" ); x[sel] = "fava amargosa" + sel = (x %in% "feijo branco" ); x[sel] = "freijo branco" sel = (x %in% "ferdinandusa elliptica" ); x[sel] = "bacabinha quina" sel = (x %in% "figado de preguisa" ); x[sel] = "figado-de-preguica" sel = (x %in% "figueira brava" ); x[sel] = "figueira" - sel = (x %in% "gameleiro" ); x[sel] = "gameleira" - sel = (x %in% "gapeba" ); x[sel] = "guapeva" + sel = (x %in% "gaivota" ); x[sel] = "gaivotinha" + sel = (x %in% "gameleiro" ); x[sel] = "gameleira" + sel = (x %in% "gapeba" ); x[sel] = "guapeva" sel = (x %in% "guapeba" ); x[sel] = "guapeva" sel = (x %in% "gema de ovo" ); x[sel] = "gema-de-ovo" sel = (x %in% "geniparana" ); x[sel] = "jeniparana" @@ -369,6 +391,7 @@ standard.common.name <<- function(x){ sel = (x %in% "jacariuba" ); x[sel] = "jacareuba" sel = (x %in% "jambo" ); x[sel] = "jambo-do-mato" sel = (x %in% "jara" ); x[sel] = "jarana" + sel = (x %in% "jarana vermelha" ); x[sel] = "jarana" sel = (x %in% "jaruma" ); x[sel] = "taruma" sel = (x %in% "jauari" ); x[sel] = "tauari" sel = (x %in% "jenita" ); x[sel] = "janita" @@ -401,9 +424,11 @@ standard.common.name <<- function(x){ sel = (x %in% "mafim" ); x[sel] = "marfim" sel = (x %in% "mamao jacatia" ); x[sel] = "jacaratia" sel = (x %in% "mamica de porca" ); x[sel] = "mamica-de-porca" - sel = (x %in% "mamonini" ); x[sel] = "mamoninha" + sel = (x %in% "mamominho" ); x[sel] = "mamoninha" + sel = (x %in% "mamonini" ); x[sel] = "mamoninha" sel = (x %in% "mandioqueiro" ); x[sel] = "mandioqueira" sel = (x %in% "mandioqueiro escamoso" ); x[sel] = "mandioqueira" + sel = (x %in% "manguirana" ); x[sel] = "manguerana" sel = (x %in% "mangueira" ); x[sel] = "manguerana" sel = (x %in% "manguerano" ); x[sel] = "manguerana" sel = (x %in% "maparajuba" ); x[sel] = "parajuba" @@ -413,8 +438,10 @@ standard.common.name <<- function(x){ sel = (x %in% "maquira" ); x[sel] = "muiratinga" sel = (x %in% "maracata" ); x[sel] = "marassacaca" sel = (x %in% "maracatia" ); x[sel] = "muiracatiara" + sel = (x %in% "maracatiara rajada" ); x[sel] = "maracatiara" sel = (x %in% "maracacaca" ); x[sel] = "marassacaca" sel = (x %in% "marasacaca" ); x[sel] = "marassacaca" + sel = (x %in% "marauba" ); x[sel] = NA_character_ sel = (x %in% "marimari" ); x[sel] = "fava-marimari" sel = (x %in% "massaranduba" ); x[sel] = "macaranduba" sel = (x %in% "mata fome" ); x[sel] = "mata-fome" @@ -426,9 +453,11 @@ standard.common.name <<- function(x){ sel = (x %in% "mata pau+jito" ); x[sel] = "gito" sel = (x %in% "mata caldo" ); x[sel] = "mata-calado" sel = (x %in% "melanciera" ); x[sel] = "melancieira" + sel = (x %in% "mirapiranga" ); x[sel] = "muirapiranga" sel = (x %in% "morto" ); x[sel] = "morta" sel = (x %in% "morango de macaco" ); x[sel] = "morango-de-macaco" sel = (x %in% "morango de morcego" ); x[sel] = "morango-de-macaco" + sel = (x %in% "muiracacaco" ); x[sel] = NA_character_ sel = (x %in% "muiratinga folha grande/amapa" ); x[sel] = "muiratinga folha grande" sel = (x %in% "muiratinga fura fura" ); x[sel] = "muiratinga fura-fura" sel = (x %in% "mulatero" ); x[sel] = "mulateiro" @@ -441,6 +470,8 @@ standard.common.name <<- function(x){ sel = (x %in% "mutama" ); x[sel] = "mutambo" sel = (x %in% "mutamba" ); x[sel] = "mutambo" sel = (x %in% "mututiassu" ); x[sel] = "mututi-acu" + sel = (x %in% "nao identificada" ); x[sel] = NA_character_ + sel = (x %in% "nao indetificada" ); x[sel] = NA_character_ sel = (x %in% "ni" ); x[sel] = NA_character_ sel = (x %in% "orelha de burro" ); x[sel] = "orelha-de-burro" sel = (x %in% "orelha de macaco" ); x[sel] = "fava orelha-de-macaco" @@ -474,7 +505,7 @@ standard.common.name <<- function(x){ sel = (x %in% "pau de rego" ); x[sel] = "pau-de-remo" sel = (x %in% "pau de remo" ); x[sel] = "pau-de-remo" sel = (x %in% "pau de sangue" ); x[sel] = "pau-sangue" - sel = (x %in% "pau doce" ); x[sel] = "pau-doce" + sel = (x %in% "pau-doce" ); x[sel] = "pau doce" sel = (x %in% "pau jacare" ); x[sel] = "pau-jacare" sel = (x %in% "pau marfim" ); x[sel] = "pau-marfim" sel = (x %in% "pau mulato" ); x[sel] = "pau-mulato" @@ -488,6 +519,7 @@ standard.common.name <<- function(x){ sel = (x %in% "pau rego" ); x[sel] = "pau-de-remo" sel = (x %in% "pau sangue" ); x[sel] = "pau-sangue" sel = (x %in% "pereauna" ); x[sel] = "perebuna" + sel = (x %in% "pedra ume" ); x[sel] = "pedra ume-caa" sel = (x %in% "pedra umi" ); x[sel] = "pedra ume-caa" sel = (x %in% "pelo de cutia" ); x[sel] = "pelo-de-cutia" sel = (x %in% "pente de macaco" ); x[sel] = "pente-de-macaco" @@ -496,19 +528,23 @@ standard.common.name <<- function(x){ sel = (x %in% "pepino do mato" ); x[sel] = "pepino-do-mato" sel = (x %in% "pepino-do-mato" ); x[sel] = "pepino-do-mato" sel = (x %in% "perna de moca" ); x[sel] = "perna-de-moca" - sel = (x %in% "piqui" ); x[sel] = "piquia" + sel = (x %in% "pincel de macaco" ); x[sel] = "pente-de-macaco" + sel = (x %in% "piqui" ); x[sel] = "piquia" sel = (x %in% "piqui rosa" ); x[sel] = "piquia" sel = (x %in% "piquiazeiro" ); x[sel] = "piquia" sel = (x %in% "pitomba da mata" ); x[sel] = "pitomba-da-mata" + sel = (x %in% "pocoro" ); x[sel] = NA_character_ sel = (x %in% "pororoca" ); x[sel] = "jutai-pororoca" sel = (x %in% "prapara" ); x[sel] = "parapara" sel = (x %in% "pratudo" ); x[sel] = "pau-para-tudo" + sel = (x %in% "puriu" ); x[sel] = "purui" sel = (x %in% "puruirana/purui branco" ); x[sel] = "purui branco" sel = (x %in% "quaiquara" ); x[sel] = "acariquara" sel = (x %in% "quariquara" ); x[sel] = "acariquara" sel = (x %in% "quariquarana" ); x[sel] = "acariquara" sel = (x %in% "quariquari" ); x[sel] = "acariquara" - sel = (x %in% "quari quari" ); x[sel] = "acariquara" + sel = (x %in% "quari quari" ); x[sel] = "acariquara" + sel = (x %in% "quariuba" ); x[sel] = "quaruba" sel = (x %in% "quaruba cedro" ); x[sel] = "quaruba-cedro" sel = (x %in% "quebrado" ); x[sel] = NA_character_ sel = (x %in% "quina" ); x[sel] = "quinarana" @@ -536,7 +572,9 @@ standard.common.name <<- function(x){ sel = (x %in% "seringa branco" ); x[sel] = "seringueira" sel = (x %in% "seringa verdadeira" ); x[sel] = "seringueira" sel = (x %in% "seringarana preta" ); x[sel] = "seringarana" - sel = (x %in% "seritinga" ); x[sel] = "seringueira" + sel = (x %in% "seringuarana" ); x[sel] = "seringarana" + sel = (x %in% "seritinga" ); x[sel] = "seringueira" + sel = (x %in% "sorvao" ); x[sel] = "sorva" sel = (x %in% "sorveira" ); x[sel] = "sorva" sel = (x %in% "sorveira leite" ); x[sel] = "sorva" sel = (x %in% "sorvo" ); x[sel] = "sorva" @@ -551,13 +589,18 @@ standard.common.name <<- function(x){ sel = (x %in% "tachi preto ???" ); x[sel] = "tachi preto" sel = (x %in% "tachi preto folh" ); x[sel] = "tachi preto" sel = (x %in% "tachi vermelha" ); x[sel] = "tachi vermelho" - sel = (x %in% "talquari" ); x[sel] = "tauari" - sel = (x %in% "tamaquarao" ); x[sel] = "tamaquare" + sel = (x %in% "taguari" ); x[sel] = "taquari" + sel = (x %in% "talquari" ); x[sel] = "taquari" + sel = (x %in% "tamaguare" ); x[sel] = "tamaquare" + sel = (x %in% "tamaquarao" ); x[sel] = "tamaquare" sel = (x %in% "tamarindu" ); x[sel] = "tamarindo" sel = (x %in% "tamauma" ); x[sel] = "sumauma" sel = (x %in% "tamboril" ); x[sel] = "fava-tamboril" sel = (x %in% "tamboriul" ); x[sel] = "fava-tamboril" sel = (x %in% "tanari roxo" ); x[sel] = "tauari" + sel = (x %in% "tanenbuco" ); x[sel] = "tanimbuca" + sel = (x %in% "tanenbuco amarelo" ); x[sel] = "tanimbuca amarela" + sel = (x %in% "tanibuca" ); x[sel] = "tanimbuca" sel = (x %in% "tangarana" ); x[sel] = "tangirana" sel = (x %in% "tanimbuca" ); x[sel] = "tanibuca" sel = (x %in% "tapiririca" ); x[sel] = "tatapiririca" @@ -565,25 +608,35 @@ standard.common.name <<- function(x){ sel = (x %in% "tatapiririca verm." ); x[sel] = "tatapiririca vermelha" sel = (x %in% "taturana" ); x[sel] = "taturuba" sel = (x %in% "tauri" ); x[sel] = "tauari" + sel = (x %in% "tento cachua" ); x[sel] = "tento caxua" sel = (x %in% "tento folha" ); x[sel] = "tento" sel = (x %in% "tento foha grauda" ); x[sel] = "tento folha grauda" - sel = (x %in% "tintero" ); x[sel] = "tinteiro" + sel = (x %in% "timbora" ); x[sel] = "timborana" + sel = (x %in% "tintero" ); x[sel] = "tinteiro" sel = (x %in% "titiriba" ); x[sel] = "cucutitiriba" sel = (x %in% "tucuma acu" ); x[sel] = "tucuma-acu" - sel = (x %in% "ucuarana" ); x[sel] = "urucurana" - sel = (x %in% "ucuuba da varzea" ); x[sel] = "ucuuba-da-varzea" + sel = (x %in% "uchi coroa" ); x[sel] = "uchi-curua" + sel = (x %in% "ucuarana" ); x[sel] = "urucurana" + sel = (x %in% "ucurana" ); x[sel] = "urucurana" + sel = (x %in% "ucuuba da varzea" ); x[sel] = "ucuuba-da-varzea" sel = (x %in% "ucuuba da terra firme" ); x[sel] = "ucuuba terra-firme" + sel = (x %in% "ucuuba folha grande" ); x[sel] = "ucuuba" sel = (x %in% "ucuuba terra firme" ); x[sel] = "ucuuba terra-firme" sel = (x %in% "ucuuba tf" ); x[sel] = "ucuuba terra-firme" - sel = (x %in% "ucuuba vermelho" ); x[sel] = "ucuuba vermelha" + sel = (x %in% "ucuuba t.f" ); x[sel] = "ucuuba terra-firme" + sel = (x %in% "ucuuba vermelho" ); x[sel] = "ucuuba vermelha" sel = (x %in% "umbia" ); x[sel] = "goiabarana" sel = (x %in% "unha de vaca" ); x[sel] = "pata-de-vaca" sel = (x %in% "uruci" ); x[sel] = "muruci" sel = (x %in% "urucu" ); x[sel] = "urucum" + sel = (x %in% "urucurana branco" ); x[sel] = "urucurana branca" sel = (x %in% "urucuri" ); x[sel] = "urucum" sel = (x %in% "uruucurana" ); x[sel] = "urucurana" sel = (x %in% "virola" ); x[sel] = "ucuuba" + sel = (x %in% "virola(ucuuba)" ); x[sel] = "ucuuba" + sel = (x %in% "virola/ucuuba preta" ); x[sel] = "ucuuba preta" sel = (x %in% "xaonoquito" ); x[sel] = "pau vermelho" + sel = (x %in% "zaguari" ); x[sel] = "taquari" #---------------------------------------------------------------------------------------# return(x) @@ -629,6 +682,29 @@ standard.scientific.name <<- function(dat,nafill=TRUE){ , stringsAsFactors = FALSE )#end read.csv nsynonym = nrow(synonym) + #---------------------------------------------------------------------------------------# + # Make sure there is no circularity in the synonym table. # + #---------------------------------------------------------------------------------------# + circular = which(synonym$accepted %in% synonym$synonym) + if (length(circular) %gt% 0L){ + toshow = synonym[circular,,drop=FALSE] + toshow$line = circular + toshow = toshow[,c("line","synonym","accepted"),drop=FALSE] + cat0("-----------------------------------------------------------") + cat0(" Circularity detected in file \"synonym_taxon.csv\":") + cat0(" ") + print(toshow,quote=FALSE) + cat0("-----------------------------------------------------------") + cat0(" ") + browser() + }#end if (length(circular) %gt% 0L) + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Replace synonyms with accepted names. # + #---------------------------------------------------------------------------------------# idx = match(g.s,synonym$synonym) sel = is.finite(idx) g.s[sel] = synonym$accepted[idx[sel]] @@ -692,7 +768,7 @@ standard.scientific.name <<- function(dat,nafill=TRUE){ #---------------------------------------------------------------------------------------# return(dat) -}#end function standard.common.name +}#end function standard.scientific.name #==========================================================================================# #==========================================================================================# @@ -879,7 +955,7 @@ standard.order.phylum.name <<- function(datum,nafill=TRUE){ #---------------------------------------------------------------------------------------# idx = which( ( ! (is.na(datum$family) | (datum$family %in% unknown.family) ) ) & ( ! datum$family %in% f2o$family ) - & ( regexpr(pattern=unknown.family,text=datum$family,ignore.case=T) %==% -1) + & ( regexpr(pattern=unknown.family,text=datum$family,ignore.case=T) %eq% -1) )#end which if (length(idx) > 0){ tofill.fam = t(t(sort(unique(datum$family[idx])))) @@ -1541,7 +1617,7 @@ find.wood.density <<- function( datum }else if (is.character(weight) && (length(weight) == 1)){ #----- Character with column name was provided. -------------------------------------# if (weight %in% names(datum)){ - wgtfac = ifelse(datum[[weight]] %>% 0, datum[[weight]], 0) + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) }else{ stop(paste0(" Weight Variable name (",weight,") not found in datum!")) }#end if @@ -1551,13 +1627,13 @@ find.wood.density <<- function( datum if (! (weight %wr% c(1,ncol(datum)))){ stop(paste0(" Weight column index (",weight,") doesn't make sense")) }else if (is.numeric(datum[,weight])){ - wgtfac = ifelse(datum[,weight] %>% 0, datum[,weight], 0) + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) }else{ stop(paste0(" Column ",weight," of data frame is not numeric!")) }#end if #------------------------------------------------------------------------------------# }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ - wgtfac = ifelse(weight %>% 0, weight, 0) + wgtfac = ifelse(weight %gt% 0, weight, 0) }else{ stop("Variable weight is not properly set!") }#end if (is.null(weight)) @@ -2004,7 +2080,7 @@ find.trait <<- function( datum }else if (is.character(weight) && (length(weight) == 1)){ #----- Character with column name was provided. -------------------------------------# if (weight %in% names(datum)){ - wgtfac = ifelse(datum[[weight]] %>% 0, datum[[weight]], 0) + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) }else{ stop(paste0(" Weight Variable name (",weight,") not found in datum!")) }#end if @@ -2014,13 +2090,13 @@ find.trait <<- function( datum if (! (weight %wr% c(1,ncol(datum)))){ stop(paste0(" Weight column index (",weight,") doesn't make sense")) }else if (is.numeric(datum[,weight])){ - wgtfac = ifelse(datum[,weight] %>% 0, datum[,weight], 0) + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) }else{ stop(paste0(" Column ",weight," of data frame is not numeric!")) }#end if #------------------------------------------------------------------------------------# }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ - wgtfac = ifelse(weight %>% 0, weight, 0) + wgtfac = ifelse(weight %gt% 0, weight, 0) }else{ stop("Variable weight is not properly set!") }#end if (is.null(weight)) @@ -2044,6 +2120,8 @@ find.trait <<- function( datum # Read data base to fill traits. # #---------------------------------------------------------------------------------------# tdb = read.csv(file=tdb.csv,header=TRUE,stringsAsFactors=FALSE) + keep = is.finite(tdb[[trait]]) + tdb = tdb[keep,,drop=FALSE] #---------------------------------------------------------------------------------------# @@ -2677,6 +2755,10 @@ keep.gen.spe.only <<- function(x,out=c("both","genus","species"),is.debug=FALSE) x = gsub(pattern="_form2$",replacement=" form2",x=x) #------------------------------------------------------------------------------------# + #----- Remove "indet" that may appear in from of an unknown genus. ------------------# + x = gsub(pattern="^indet",replacement="",x=x) + #------------------------------------------------------------------------------------# + #----- Split words, and remove stuff like sp, cf, etc. ------------------------------# ans = unlist(strsplit(unlist(c(tolower(x))),split=" ")) diff --git a/R-utils/taylor.plot.r b/R-utils/taylor.plot.r index f25e98ccb..baff7b1f1 100644 --- a/R-utils/taylor.plot.r +++ b/R-utils/taylor.plot.r @@ -152,8 +152,8 @@ taylor.plot <<- function ( obs #---------------------------------------------------------------------------------------# R = sapply(X = mod, FUN = cor, x = obs, use = "pairwise") if (is.na(pos.corr)){ - pos.corr = ! any(R %<% 0.) - }else if (pos.corr && any(R %<% 0)){ + pos.corr = ! any(R %lt% 0.) + }else if (pos.corr && any(R %lt% 0)){ warning(" There are negative correlations, but you've asked positive side only!") }#end if #---------------------------------------------------------------------------------------# diff --git a/R-utils/test.goodness.r b/R-utils/test.goodness.r index a940dfc54..f0306e704 100644 --- a/R-utils/test.goodness.r +++ b/R-utils/test.goodness.r @@ -44,8 +44,8 @@ test.goodness <<- function(x.mod,x.obs,x.sigma=NULL,n.parameters=NULL,out.dfr=FA #----- Find associated weights, and re-create the vectors x.mod and x.obs. ----------# - x.wgt = ifelse(x.sigma %>% 0, 1. / x.sigma^2, 0) - sel = x.wgt %>% 0 + x.wgt = ifelse(x.sigma %gt% 0, 1. / x.sigma^2, 0) + sel = x.wgt %gt% 0 x.obs.orig = x.obs x.mod.orig = x.mod x.obs = x.obs[sel] * sqrt(x.wgt[sel]) diff --git a/R-utils/thermlib.r b/R-utils/thermlib.r index 4b0689eb3..9f8213466 100644 --- a/R-utils/thermlib.r +++ b/R-utils/thermlib.r @@ -691,6 +691,32 @@ idealdenssh <<- function(pres,temp,qvpr,qtot=NULL){ +#==========================================================================================# +#==========================================================================================# +# This function finds the dry-air molar density (mol/m3), using the ideal gas law. # +#------------------------------------------------------------------------------------------# +idealdmolsh <<- function(pres,temp,qvpr,qtot=NULL){ + + + #----- Find the partial pressure of water vapour. --------------------------------------# + pdry = pres * (1.0 - qvpr / (ep + (1.0 - ep) * qvpr)) + #---------------------------------------------------------------------------------------# + + + #----- Convert using a generalised function. -------------------------------------------# + dmol = pdry / (rmol * temp) + #---------------------------------------------------------------------------------------# + + return(dmol) +}#end if +#==========================================================================================# +#==========================================================================================# + + + + + + #==========================================================================================# #==========================================================================================# # This function computes the pressure at the top of the tower using hydrostatic and # @@ -753,7 +779,7 @@ tower.press <<- function(p0,e0,t0,z0,t1,e1,z1,hum="pvap"){ #---------------------------------------------------------------------------------------# return(p1) -}#end function reducedpress +}#end function tower.press #==========================================================================================# #==========================================================================================# @@ -762,6 +788,65 @@ tower.press <<- function(p0,e0,t0,z0,t1,e1,z1,hum="pvap"){ + +#==========================================================================================# +#==========================================================================================# +# This function computes reduces the pressure from the reference height to the canopy # +# height by assuming hydrostatic equilibrium. For simplicity, we assume that R and cp are # +# constants (in reality they are dependent on humidity). # +#------------------------------------------------------------------------------------------# +reducedpress <<- function(pres,thetaref,shvref,zref,thetacan,shvcan,zcan,fthva_rp=0.5){ + + + #---------------------------------------------------------------------------------------# + # Missing data points. # + #---------------------------------------------------------------------------------------# + any.miss = c(missing(pres),missing(thetaref),missing(shvref),missing(zref) + ,missing(thetacan),missing(shvcan),missing(zcan)) + if (any(any.miss)){ + cat0(" Variable \"pres\" is provided: " ,! missing(pres ),".") + cat0(" Variable \"thetaref\" is provided: ",! missing(thetaref),".") + cat0(" Variable \"shvref\" is provided: ",! missing(shvref ),".") + cat0(" Variable \"zref\" is provided: ",! missing(zrefref ),".") + cat0(" Variable \"thetacan\" is provided: ",! missing(thetacan),".") + cat0(" Variable \"shvcan\" is provided: ",! missing(shvcan ),".") + cat0(" Variable \"zcan\" is provided: ",! missing(zcancan ),".") + stop("All variables above must be provided.") + }#end if (any.miss) + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # First we compute the average virtual potential temperature between the canopy # + # top and the reference level. Because of the equation below, we average the inverse # + # of the potential temperature. # + #---------------------------------------------------------------------------------------# + thvref = thetaref * (1.0 + epim1 * shvref) + thvcan = thetacan * (1.0 + epim1 * shvcan) + thvbar = thvref * thvcan / ( ( 1.0 - fthva_rp ) * thvref + fthva_rp * thvcan ) + #---------------------------------------------------------------------------------------# + + + + #----- Then, we find the pressure gradient scale. --------------------------------------# + pinc = grav * p00k * (zref - zcan) / (cpdry * thvbar) + #---------------------------------------------------------------------------------------# + + + + #----- And we can find the reduced pressure. -------------------------------------------# + ans = (pres**rocp + pinc ) ** cpor + #---------------------------------------------------------------------------------------# + + + return(ans) +}#end function reducedpress +#==========================================================================================# +#==========================================================================================# + + + + + #==========================================================================================# #==========================================================================================# # This subroutine finds the lifting condensation level given the ice-liquid # @@ -1148,3 +1233,30 @@ uextcm2tl <<- function(uext,wmass,dryhcap){ }#end function uextcm2tl #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Functions that convert between pressure and Exner function. # +#------------------------------------------------------------------------------------------# +press2exner <<- function(pres ){ cpdry * (pres * p00i ) ^ rocp} +exner2press <<- function(exner){ p00 * (exner * cpdryi) ^ cpor} +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Functions that convert between temperature and potential temperature using Exner. # +#------------------------------------------------------------------------------------------# +extemp2theta <<- function(exner,temp ){ cpdry * temp / exner } +extheta2temp <<- function(exner,theta){ cpdryi * theta * exner } +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/time.to.edge.r b/R-utils/time.to.edge.r new file mode 100644 index 000000000..dee8f03df --- /dev/null +++ b/R-utils/time.to.edge.r @@ -0,0 +1,130 @@ +#==========================================================================================# +#==========================================================================================# +# Function time.to.edge. # +# # +# This function computes the time it takes for air to reach the edge, assuming that # +# air moves along the dominant wind. # +# # +#------------------------------------------------------------------------------------------# +time.to.edge <<- function( datum + , emask + , u.vnam + , v.vnam + , xy.m.fac = 1000. + , wmin = 0.05 + , tmax = 5000./wmin + , cosmin = cos(15.*pio180) + ){ + + #------ Fortran code. ------------------------------------------------------------------# + fortran.so = file.path(srcdir,"time_to_edge.so") + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Extract wind data from data table. # + #---------------------------------------------------------------------------------------# + uvsel = is.finite(datum[[u.vnam]]) & is.finite(datum[[v.vnam]]) + dsel = datum[uvsel] + nwind = nrow(dsel) + xwind = dsel$x * xy.m.fac + ywind = dsel$y * xy.m.fac + uwind = dsel[[u.vnam]] + vwind = dsel[[v.vnam]] + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Extract wind data from mask table. # + #---------------------------------------------------------------------------------------# + edsel = emask$mask & (! is.na(emask$mask) ) + edge = emask[edsel] + nedge = nrow(edge) + xedge = edge$x * xy.m.fac + yedge = edge$y * xy.m.fac + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # Find the time to edge. # + #---------------------------------------------------------------------------------------# + if ( (nedge*nwind) > 0){ + + + #------ Load Fortran and run code. --------------------------------------------------# + # if (! is.loaded("timetoedge")) dummy = dyn.load(fortran.so) + # tedge = .Fortran( "timetoedge" + # , nwind = as.integer(nwind) + # , xwind = as.double (xwind) + # , ywind = as.double (ywind) + # , uwind = as.double (uwind) + # , vwind = as.double (vwind) + # , nedge = as.integer(nedge) + # , xedge = as.double (xedge) + # , yedge = as.double (yedge) + # , wmin = as.double (wmin) + # , time = as.double (tedge) + # )#end .Fortran + #------------------------------------------------------------------------------------# + + + + + #------ Populate answer. ------------------------------------------------------------# + # ans = rep(NA_real_,times=nrow(datum)) + # ans[uvsel] = pmin(tmax,tedge$time) + # rm(tedge) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Calculate wind speed and direction. # + #------------------------------------------------------------------------------------# + SPEED = matrix(data=sqrt(uwind*uwind+vwind*vwind),nrow=nwind,ncol=nedge) + OMEGA = matrix(data=atan2(y=vwind,x=uwind) ,nrow=nwind,ncol=nedge) + #------------------------------------------------------------------------------------# + + + #------ Calculate distance from point to edge. --------------------------------------# + DX = -outer(X=xwind,Y=xedge,FUN=`-`) + DY = -outer(X=ywind,Y=yedge,FUN=`-`) + DIST = sqrt(DX*DX+DY*DY) + DELTA = atan2(y=DY,x=DX) + #------------------------------------------------------------------------------------# + + + #----- Find the baseline time to edge. ----------------------------------------------# + WEDGE = matrix(data=pmax(wmin,SPEED * cos(OMEGA - DELTA)),nrow=nwind,ncol=nedge) + #------------------------------------------------------------------------------------# + + + #----- Select the minimum time as the time to edge. ---------------------------------# + TEDGE = DIST / WEDGE + tedge = apply(X=TEDGE,MARGIN=1,FUN=min,na.rm=TRUE) + #------------------------------------------------------------------------------------# + + + + + #------ Populate answer. ------------------------------------------------------------# + ans = rep(NA_real_,times=nrow(datum)) + ans[uvsel] = pmin(tmax,tedge) + rm(SPEED,OMEGA,DX,DY,DIST,WEDGE,TEDGE,tedge) + #------------------------------------------------------------------------------------# + + }else{ + #------ Either wind or edge were completely missing. Return dummy answer. -----------# + ans = ifelse( test = uvsel + , yes = tmax + , no = NA_real_ + )#end ifelse + #------------------------------------------------------------------------------------# + }#end if + #---------------------------------------------------------------------------------------# + + + + return(ans) +}#end time.to.edge +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/timeutils.r b/R-utils/timeutils.r index 4ac0300cb..f1f00aa5f 100644 --- a/R-utils/timeutils.r +++ b/R-utils/timeutils.r @@ -323,12 +323,12 @@ alltimes <<- function(datin,lon,lat,ed21=TRUE,zeronight=FALSE,meanval=FALSE,imet zenith = ed.zen (when=datout$when,lon=lon,lat=lat,ed21=ed21 ,zeronight=zeronight,meanval=meanval,imetavg=imetavg ,nmean=nmean,...) - datout$cosz = zenith$cosz - datout$zen = zenith$zen - datout$sunhgt = zenith$hgt - datout$nighttime = zenith$night - datout$daytime = zenith$day - datout$twilight = (! zenith$night) & (! zenith$day) + datout$cosz = zenith$cosz + datout$zen = zenith$zen + datout$sunhgt = zenith$hgt + datout$nighttime = zenith$night + datout$daytime = zenith$day + datout$twilight = zenith$twilight datout$diel = as.integer(! datout$nighttime) + as.integer(datout$daytime) datout$highsun = zenith$cosz >= cosz.highsun datout$riseset = zenith$cosz >= cosz.twilight & zenith$cosz < cosz.highsun diff --git a/R-utils/trait.utils.r b/R-utils/trait.utils.r index 1d02412ad..da5675468 100644 --- a/R-utils/trait.utils.r +++ b/R-utils/trait.utils.r @@ -87,7 +87,7 @@ fix.try.lon <<- function(x){ #---------------------------------------------------------------------------------------# #------ Make sure the coordinates are between 180W and 180E. ---------------------------# - subtr = (ans %>=% 180.) & (ans %<=% 360.) + subtr = (ans %ge% 180.) & (ans %le% 360.) ans[subtr] = ans[subtr] - 360. #---------------------------------------------------------------------------------------# diff --git a/R-utils/unitlist.r b/R-utils/unitlist.r index 699717b82..9f336907b 100644 --- a/R-utils/unitlist.r +++ b/R-utils/unitlist.r @@ -3,158 +3,225 @@ # This list contains the list of all commonly used units written in mathematical # # format. # #------------------------------------------------------------------------------------------# -untab <<- list( cm = "c*m" - , cm2m = "c*m^2*m" - , cm2om2 = "c*m^2*m^{-2}" - , cm2opl = "c*m^2*p*l*a*n*t^{-1}" - , cm2om2oyr = "c*m^2*m^{-2}*y*r^{-1}" - , day = "d*a*y" - , deg = "degree" - , degC = "degree*C" - , degCodec = "degree*C*d*e*c*a*d*e^{-1}" - , degE = "degree*E" - , degN = "degree*N" - , degS = "degree*S" - , degW = "degree*W" - , empty = "phantom(1)-phantom(1)" - , gcokgw = "g*C^phantom(1)*k*g*W^{-1}" - , gcokgcbio = "g*C^phantom(1)*k*g[C[b*i*o]]^{-1}" - , gcom2oday = "g*C^phantom(1)*m^{-2}*d*a*y^{-1}" - , Gjom2 = "G*J^phantom(1)*m^{-2}" - , gmt = "G*M*T" - , gom3 = "g^phantom(1)*m^{-3}" - , gocm3 = "g^phantom(1)*c*m^{-3}" - , gwokg = "g*W^phantom(1)*k*g^{-1}" - , gwokgodec = "g*W^phantom(1)*k*g^{-1}*d*e*c*a*d*e^{-1}" - , hpa = "h*P*a" - , hpaodec = "h*P*a^phantom(1)*d*e*c*a*d*e^{-1}" - , hr = "h*o*u*r" - , jokgom2 = "J^phantom(1)*k*g^{-1}*m^{-2}" - , jokgopl = "J^phantom(1)*k*g^{-1}*p*l^{-1}" - , jom2 = "J^phantom(1)*m^{-2}" - , K = "K" - , Kodec = "K^phantom(1)*d*e*c*a*d*e^{-1}" - , k = "K" - , kg = "k*g" - , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" - , kgcokgn = "k*g*C^phantom(1)*k*g*N^{-1}" - , kgcokgp = "k*g*C^phantom(1)*k*g*P^{-1}" - , kgcom2 = "k*g*C^phantom(1)*m^{-2}" - , kgcom2l = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" - , kgcom2loyr = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}" - , kgcom2oday = "k*g*C^phantom(1)*m^{-2}*d*a*y^{-1}" - , kgcom2oyr = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}" - , kgcom2oyrodec = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}*d*e*c*a*d*e^{-1}" - , kgcom3 = "k*g*C^phantom(1)*m^{-3}" - , kgcopl = "k*g*C^phantom(1)*p*l*a*n*t^{-1}" - , kgcoployr = "k*g*C^phantom(1)*p*l*a*n*t^{-1}*y*r^{-1}" - , kgokg = "k*g^phantom(1)*k*g^{-1}" - , kgom2 = "k*g^phantom(1)*m^{-2}" - , kgom2loday = "k*g^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" - , kgom3 = "k*g^phantom(1)*m^{-3}" - , kgnokg = "k*g*N^phantom(1)*k*g^{-1}" - , kgnom2 = "k*g*N^phantom(1)*m^{-2}" - , kgpokg = "k*g*P^phantom(1)*k*g^{-1}" - , kgwokg = "k*g*W^phantom(1)*k*g^{-1}" - , kgpom2 = "k*g*P^phantom(1)*m^{-2}" - , kgwom2 = "k*g*W^phantom(1)*m^{-2}" - , kgwom2l = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}" - , kgwom2oday = "k*g*W^phantom(1)*m^{-2}*d*a*y^{-1}" - , kgwom2ohr = "k*g*W^phantom(1)*m^{-2}*h*r^{-1}" - , kgwom2os = "k*g*W^phantom(1)*m^{-2}*s^{-1}" - , kgwom2loday = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" - , kgwom3oday = "k*g*W^phantom(1)*m^{-3}*d*a*y^{-1}" - , kgwoploday = "k*g*W^phantom(1)*p*l*a*n*t^{-1}*d*a*y^{-1}" - , km = "k*m" - , Kmos = "K^phantom(1)*m^phantom(1)*s^{-1}" - , kpa = "k*P*a" - , m = "m" - , m2 = "m^2" - , mm = "m*m" - , mmodec = "m*m^phantom(1)*d*e*c*a*d*e^{-1}" - , mmoyrodec = "m*m^phantom(1)*y*r^{-1}*d*e*c*a*d*e^{-1}" - , mm2okgw = "m*m^2*k*g*W^{-1}" - , mmoday = "m*m^phantom(1)*d*a*y^{-1}" - , mmohr = "m*m^phantom(1)*h*r^{-1}" - , mmolom2os = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}" - , mmomo = "m*m^phantom(1)*m*o*n*t*h^{-1}" - , molom2 = "m*o*l^phantom(1)*m^{-2}" - , molom2l = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}" - , molcom2 = "m*o*l*C^phantom(1)*m^{-2}" - , month = "m*o*n*t*h" - , mos = "m^phantom(1)*s^{-1}" - , mosodec = "m^phantom(1)*s^{-1}*d*e*c*a*d*e^{-1}" - , m2oha = "m^{2}*h*a^{-1}" - , m2om2 = "m^2*m^{-2}" - , m2om3 = "m^2*m^{-3}" - , m2opl = "m^2*p*l^{-1}" - , m2lokgc = "m[l*e*a*f]^2*k*g*C^{-1}" - , m2lom2 = "m[l*e*a*f]^2*m^{-2}" - , m2lom2odec = "m[l*e*a*f]^2*m^{-2}*d*e*c*a*d*e^{-1}" - , m2lopl = "m[l*e*a*f]^2*p*l^{-1}" - , m2pom2 = "m[l*e*a*f+w*o*o*d]^2*m^{-2}" - , m2popl = "m[l*e*a*f+w*o*o*d]^2*p*l^{-1}" - , m2wom2 = "m[w*o*o*d]^2*m^{-2}" - , m2wopl = "m[w*o*o*d]^2*p*l^{-1}" - , m3oha = "m^3*h*a^{-1}" - , m3om2 = "m^3*m^{-2}" - , m3wom3 = "m[W]^3*m^{-3}" - , Mgcoha = "M*g*C^phantom(1)*h*a^{-1}" - , Mgoha = "M*g^phantom(1)*h*a^{-1}" - , Mgwom2 = "M*g*W^phantom(1)*m^{-2}" - , Mjom2 = "M*J^phantom(1)*m^{-2}" - , mmoyr = "m*m^phantom(1)*y*r^{-1}" - , mpa = "M*P*a" - , nmo.090 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" - , nmo.100 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" - , nmo.110 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" - , nmo.120 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" - , nmo.wdef = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" - , nmolomol = "n*m*o*l^phantom(1)*m*o*l^{-1}" - , oneom = "m^{-1}" - , oneoha = "h*a^{-1}" - , oneom2 = "m^{-2}" - , oneoyr = "y*r^{-1}" - , oneodec = "d*e*c*a*d*e^{-1}" - , pa = "P*a" - , pc = "'%'" - , pcbio = "'%'[b*i*o]" - , pcagboyr = "'%'[A*G*B]^phantom(1)*y*r^{-1}" - , pcagbo50yr = "'%'[A*G*B]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" - , pcareaoyr = "'%'[a*r*e*a]^phantom(1)*y*r^{-1}" - , pcbaoyr = "'%'[B*A]^phantom(1)*y*r^{-1}" - , pcbiooyr = "'%'[b*i*o]^phantom(1)*y*r^{-1}" - , pcdbhoyr = "'%'[D*B*H]^phantom(1)*y*r^{-1}" - , pcetoyr = "'%'[E*T]^phantom(1)*y*r^{-1}" - , pceto50yr = "'%'[E*T]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" - , pcoyr = "'%'^phantom(1)*y*r^{-1}" - , pcpopoyr = "'%'[p*o*p]^phantom(1)*y*r^{-1}" - , pcsat = "'%'[S*a*t]" - , pgc = "P*g*C" - , pgcoyr = "P*g*C^phantom(1)*y*r^{-1}" - , plom2 = "p*l*a*n*t^phantom(1)*m^{-2}" - , ploha = "p*l*a*n*t^phantom(1)*h*a^{-1}" - , s = "s" - , t1e3 = "phantom(1)%*%10^{3}" - , t1e6 = "phantom(1)%*%10^{6}" - , t1e9 = "phantom(1)%*%10^{9}" - , thkm2oyr = "10^{3*phantom(1)}*k*m^{2}*y*r^{-1}" - , umolcom2os = "mu*m*o*l*C^phantom(1)*m^{-2}*s^{-1}" - , umolokgcos = "mu*m*o*l^phantom(1)*k*g*C^{-1}*s^{-1}" - , umolom2 = "mu*m*o*l^phantom(1)*m^{-2}" - , umolom2os = "mu*m*o*l^phantom(1)*m^{-2}*s^{-1}" - , umolom2l = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}" - , umolom2los = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}*s^{-1}" - , umolcom2 = "mu*m*o*l*C^phantom(1)*m^{-2}" - , umolcomol = "mu*m*o*l*C^phantom(1)*m*o*l^{-1}" - , umolomol = "mu*m*o*l^phantom(1)*m*o*l^{-1}" - , utc = "U*T*C" - , wom2 = "W^phantom(1)*m^{-2}" - , wom2l = "W^phantom(1)*m[l*e*a*f]^{-2}" - , wom2oyr = "W^phantom(1)*m^{-2}*y*r^{-1}" - , wom2odec = "W^phantom(1)*m^{-2}*d*e*c*a*d*e^{-1}" - , wopl = "W^phantom(1)*p*l*a*n*t^{-1}" - , yr = "y*r" +untab <<- list( cm = "c*m" + , cmohaoyr = "c*m^phantom(1)*h*a^{-1}*y*r^{-1}" + , cmoyr = "c*m^phantom(1)*y*r^{-1}" + , cm2m = "c*m^2*m" + , cm2om2 = "c*m^2*m^{-2}" + , cm2om2odec = "c*m^2*m^{-2}*d*e*c^{-1}" + , cm2opl = "c*m^2*p*l*a*n*t^{-1}" + , cm2om2oyr = "c*m^2*m^{-2}*y*r^{-1}" + , day = "d*a*y" + , deg = "degree" + , degC = "degree*C" + , degCodec = "degree*C^phantom(1)*d*e*c^{-1}" + , degE = "degree*E" + , degN = "degree*N" + , degS = "degree*S" + , degW = "degree*W" + , empty = "phantom(1)-phantom(1)" + , gcoday = "g*C^phantom(1)*d*a*y^{-1}" + , gcokg = "g*C^phantom(1)*k*g^{-1}" + , gcokgw = "g*C^phantom(1)*k*g*W^{-1}" + , gcokgcbio = "g*C^phantom(1)*k*g[C[b*i*o]]^{-1}" + , gcom2oday = "g*C^phantom(1)*m^{-2}*d*a*y^{-1}" + , Gjom2 = "G*J^phantom(1)*m^{-2}" + , gmpaos = "g^phantom(1)*M*P*a^phantom(1)*s^{-1}" + , gmt = "G*M*T" + , gnokg = "g*N^phantom(1)*k*g^{-1}" + , gom2oday = "g^phantom(1)*m^{-2}*d*a*y^{-1}" + , gom3 = "g^phantom(1)*m^{-3}" + , gocm3 = "g^phantom(1)*c*m^{-3}" + , gocm3odec = "g^phantom(1)*c*m^{-3}*d*e*c^{-1}" + , gokg = "g^phantom(1)*k*g^{-1}" + , gpokg = "g*P^phantom(1)*k*g^{-1}" + , gwokg = "g*W^phantom(1)*k*g^{-1}" + , gwokgodec = "g*W^phantom(1)*k*g^{-1}*d*e*c^{-1}" + , ha = "h*a" + , hpa = "h*P*a" + , hpaodec = "h*P*a^phantom(1)*d*e*c^{-1}" + , hr = "h*o*u*r" + , jokgom2 = "J^phantom(1)*k*g^{-1}*m^{-2}" + , jokgopl = "J^phantom(1)*k*g^{-1}*p*l^{-1}" + , jom2 = "J^phantom(1)*m^{-2}" + , K = "K" + , Kodec = "K^phantom(1)*d*e*c^{-1}" + , k = "K" + , kg = "k*g" + , kgc = "k*g*C" + , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" + , kgcokgn = "k*g*C^phantom(1)*k*g*N^{-1}" + , kgcokgp = "k*g*C^phantom(1)*k*g*P^{-1}" + , kgcom2 = "k*g*C^phantom(1)*m^{-2}" + , kgcom2odec = "k*g*C^phantom(1)*m^{-2}*d*e*c^{-1}" + , kgcom2l = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , kgcom2loyr = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}" + , kgcom2loyrodec = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}*dec^{-1}" + , kgcom2oday = "k*g*C^phantom(1)*m^{-2}*d*a*y^{-1}" + , kgcom2oyr = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}" + , kgcom2oyrodec = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}*d*e*c^{-1}" + , kgcom3 = "k*g*C^phantom(1)*m^{-3}" + , kgcopl = "k*g*C^phantom(1)*p*l*a*n*t^{-1}" + , kgcoployr = "k*g*C^phantom(1)*p*l*a*n*t^{-1}*y*r^{-1}" + , kgcoyr = "k*g*C^phantom(1)*y*r^{-1}" + , kgokg = "k*g^phantom(1)*k*g^{-1}" + , kgom2 = "k*g^phantom(1)*m^{-2}" + , kgom2loday = "k*g^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" + , kgom3 = "k*g^phantom(1)*m^{-3}" + , kgomos2 = "k*g^phantom(1)*m^{-1}*s^{-2}" + , kgnokg = "k*g*N^phantom(1)*k*g^{-1}" + , kgnokgp = "k*g*N^phantom(1)*k*g*P^{-1}" + , kgnom2 = "k*g*N^phantom(1)*m^{-2}" + , kgpokg = "k*g*P^phantom(1)*k*g^{-1}" + , kgwokg = "k*g*W^phantom(1)*k*g^{-1}" + , kgpom2 = "k*g*P^phantom(1)*m^{-2}" + , kgwom2 = "k*g*W^phantom(1)*m^{-2}" + , kgwom2l = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}" + , kgwom2oday = "k*g*W^phantom(1)*m^{-2}*d*a*y^{-1}" + , kgwom2odec = "k*g*W^phantom(1)*m^{-2}*d*e*c^{-1}" + , kgwom2ohr = "k*g*W^phantom(1)*m^{-2}*h*r^{-1}" + , kgwom2os = "k*g*W^phantom(1)*m^{-2}*s^{-1}" + , kgwom2loday = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" + , kgwom3oday = "k*g*W^phantom(1)*m^{-3}*d*a*y^{-1}" + , kgwom3ompa = "k*g*W^phantom(1)*m^{-3}*M*P*a^{-1}" + , kgwomosompa = "k*g*W^phantom(1)*m^{-1}*s^{-1}*M*P*a^{-1}" + , kgwoploday = "k*g*W^phantom(1)*p*l*a*n*t^{-1}*d*a*y^{-1}" + , km = "k*m" + , Kmos = "K^phantom(1)*m^phantom(1)*s^{-1}" + , kpa = "k*P*a" + , kwom = "k*W^phantom(1)*m^{-1}" + , m = "m" + , m2 = "m^2" + , m2ocm2 = "m^2*c*m^{-2}" + , mg = "m*g" + , min = "m*i*n" + , mm = "m*m" + , mmodec = "m*m^phantom(1)*d*e*c^{-1}" + , mmoyrodec = "m*m^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , mm2okgw = "m*m^2*k*g*W^{-1}" + , mmoday = "m*m^phantom(1)*d*a*y^{-1}" + , mmodayodec = "m*m^phantom(1)*d*a*y^{-1}*d*e*c^{-1}" + , mmohr = "m*m^phantom(1)*h*r^{-1}" + , mmolom2os = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}" + , mmolom2osompa = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}*M*P*a^{-1}" + , mmologos = "m*m*o*l^phantom(1)*g^{-1}*s^{-1}" + , mmolokgos = "m*m*o*l^phantom(1)*k*g^{-1}*s^{-1}" + , mmolcokg = "k*g^phantom(1)*m*m*o*l*C^{-1}" + , mmomo = "m*m^phantom(1)*m*o*n*t*h^{-1}" + , mokg = "m^phantom(1)*k*g^{-1}" + , molom2 = "m*o*l^phantom(1)*m^{-2}" + , molom2osompa = "m*o*l^phantom(1)*m^{-2}*s^{-1}*M*P*a^{-1}" + , molom2l = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}" + , molom2lompa = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}*M*P*a^{-1}" + , molcom2 = "m*o*l*C^phantom(1)*m^{-2}" + , molosompa = "m*o*l^phantom(1)*s^{-1}*M*P*a^{-1}" + , month = "m*o*n*t*h" + , monthodec = "m*o*n*t*h^phantom(1)*d*e*c^{-1}" + , mos = "m^phantom(1)*s^{-1}" + , momin = "m^phantom(1)*m*i*n^{-1}" + , mosodec = "m^phantom(1)*s^{-1}*d*e*c^{-1}" + , m2oha = "m^{2}*h*a^{-1}" + , m2ohaoyr = "m^{2}*h*a^{-1}*y*r^{-1}" + , m2okg = "m^2*k*g^{-1}" + , m2om2 = "m^2*m^{-2}" + , m2om3 = "m^2*m^{-3}" + , m2opl = "m^2*p*l^{-1}" + , m2lokg = "m[l*e*a*f]^2*k*g^{-1}" + , m2lokgc = "m[l*e*a*f]^2*k*g*C^{-1}" + , m2lokgcodec = "m[l*e*a*f]^2*k*g*C^{-1}*d*e*c^{-1}" + , m2lom2 = "m[l*e*a*f]^2*m^{-2}" + , m2lom2odec = "m[l*e*a*f]^2*m^{-2}*d*e*c^{-1}" + , m2lopl = "m[l*e*a*f]^2*p*l^{-1}" + , m2pom2 = "m[l*e*a*f+w*o*o*d]^2*m^{-2}" + , m2popl = "m[l*e*a*f+w*o*o*d]^2*p*l^{-1}" + , m2wom2 = "m[w*o*o*d]^2*m^{-2}" + , m2wopl = "m[w*o*o*d]^2*p*l^{-1}" + , m3oha = "m^3*h*a^{-1}" + , m3om2 = "m^3*m^{-2}" + , m3wom3 = "m[W]^3*m^{-3}" + , Mgcoha = "M*g*C^phantom(1)*h*a^{-1}" + , Mgoha = "M*g^phantom(1)*h*a^{-1}" + , Mgwom2 = "M*g*W^phantom(1)*m^{-2}" + , Mjom2 = "M*J^phantom(1)*m^{-2}" + , mmoyr = "m*m^phantom(1)*y*r^{-1}" + , mpa = "M*P*a" + , mpaodec = "M*P*a^phantom(1)*d*e*c^{-1}" + , mwom2ok = "m*W^phantom(1)*m^{-2}*K^{-1}" + , nmo.090 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" + , nmo.100 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" + , nmo.110 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" + , nmo.120 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" + , nmo.wdef = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" + , nmolomol = "n*m*o*l^phantom(1)*m*o*l^{-1}" + , oneoday = "d*a*y^{-1}" + , oneom = "m^{-1}" + , oneoha = "h*a^{-1}" + , oneok = "K^{-1}" + , oneokm2 = "k*m^{-2}" + , oneokm2oday = "k*m^{-2}*d*a*y^{-1}" + , oneokm2omo = "k*m^{-2}*m*o*n*t*h^{-1}" + , oneom2 = "m^{-2}" + , oneoyr = "y*r^{-1}" + , oneodec = "d*e*c^{-1}" + , pa = "P*a" + , pc = "'%'" + , pcoday = "'%'^phantom(1)*d*a*y^{-1}" + , pcodec = "'%'^phantom(1)*d*e*c^{-1}" + , pcbio = "'%'[b*i*o]" + , pcagboyr = "'%'[A*G*B]^phantom(1)*y*r^{-1}" + , pcagboyrodec = "'%'[A*G*B]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcagbo50yr = "'%'[A*G*B]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" + , pcareaoyr = "'%'[a*r*e*a]^phantom(1)*y*r^{-1}" + , pcbaoyr = "'%'[B*A]^phantom(1)*y*r^{-1}" + , pcbiooyr = "'%'[b*i*o]^phantom(1)*y*r^{-1}" + , pcbiooyrodec = "'%'[b*i*o]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcdbhoyr = "'%'[D*B*H]^phantom(1)*y*r^{-1}" + , pcdbhoyrodec = "'%'[D*B*H]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcetoyr = "'%'[E*T]^phantom(1)*y*r^{-1}" + , pceto50yr = "'%'[E*T]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" + , pcoyr = "'%'^phantom(1)*y*r^{-1}" + , pcoyrodec = "'%'^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcpopoyr = "'%'[p*o*p]^phantom(1)*y*r^{-1}" + , pcsat = "'%'[S*a*t]" + , pgc = "P*g*C" + , pgcoyr = "P*g*C^phantom(1)*y*r^{-1}" + , plom2 = "p*l*a*n*t^phantom(1)*m^{-2}" + , plom2odec = "p*l*a*n*t^phantom(1)*m^{-2}*d*e*c^{-1}" + , ploha = "p*l*a*n*t^phantom(1)*h*a^{-1}" + , plohaoyr = "p*l*a*n*t^phantom(1)*h*a^{-1}*y*r^{-1}" + , plohaodec = "p*l*a*n*t^phantom(1)*h*a^{-1}*d*e*c^{-1}" + , s = "s" + , t1e3 = "phantom(1)%*%10^{3}" + , t1e6 = "phantom(1)%*%10^{6}" + , t1e9 = "phantom(1)%*%10^{9}" + , thkm2oyr = "10^{3*phantom(1)}*k*m^{2}*y*r^{-1}" + , umolcom2os = "mu*m*o*l*C^phantom(1)*m^{-2}*s^{-1}" + , umologcos = "mu*m*o*l^phantom(1)*g*C^{-1}*s^{-1}" + , umologos = "mu*m*o*l^phantom(1)*g^{-1}*s^{-1}" + , umolokgcos = "mu*m*o*l^phantom(1)*k*g*C^{-1}*s^{-1}" + , umolokgos = "mu*m*o*l^phantom(1)*k*g^{-1}*s^{-1}" + , umolom2 = "mu*m*o*l^phantom(1)*m^{-2}" + , umolom2os = "mu*m*o*l^phantom(1)*m^{-2}*s^{-1}" + , molom2osompa = "m^{2}*s^phantom(1)*M*P*a^phantom(1)*m*o*l^{-1}" + , molom2lompa = "m[l*e*a*f]^{2}*M*P*a^phantom(1)*m*o*l^{-1}" + , molosompa = "s^phantom(1)*M*P*a^phantom(1)*m*o*l^{-1}" + , umolom2l = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}" + , umolom2los = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}*s^{-1}" + , umolcom2 = "mu*m*o*l*C^phantom(1)*m^{-2}" + , umolcomol = "mu*m*o*l*C^phantom(1)*m*o*l^{-1}" + , umolomol = "mu*m*o*l^phantom(1)*m*o*l^{-1}" + , umolomolodec = "mu*m*o*l^phantom(1)*m*o*l^{-1}*d*e*c^{-1}" + , usd = "U*S*D" + , usdoyr = "U*S*D^phantom(1)*y*r^{-1}" + , utc = "U*T*C" + , wom2 = "W^phantom(1)*m^{-2}" + , wom2l = "W^phantom(1)*m[l*e*a*f]^{-2}" + , wom2oyr = "W^phantom(1)*m^{-2}*y*r^{-1}" + , wom2odec = "W^phantom(1)*m^{-2}*d*e*c^{-1}" + , wopl = "W^phantom(1)*p*l*a*n*t^{-1}" + , yr = "y*r" + , zscore = "Z[s*c*o*r*e]" + , zscoreodec = "Z[s*c*o*r*e]^phantom(1)*d*e*c^{-1}" )#end list #==========================================================================================# #==========================================================================================# @@ -170,156 +237,217 @@ untab <<- list( cm = "c*m" # density function are the inverse of the actual units of the quantity, so the integral # # becomes dimensionless. # #------------------------------------------------------------------------------------------# -i.untab <<- list( cm = "c*m^{-1}" - , cm2m = "c*m^{-2}*m^{-1}" - , cm2om2 = "m^2*c*m^{-2}" - , cm2opl = "p*l*a*n*t^phantom(1)*c*m^{-2}" - , cm2om2oyr = "m^2*y*r^phantom(1)*c*m^{-2}" - , day = "d*a*y^{-1}" - , deg = "degree^{-1}" - , degC = "degree*C^{-1}" - , degCodec = "d*e*c*a*d*e^phantom(1)*degree*C^{-1}" - , degE = "degree*E^{-1}" - , degN = "degree*N^{-1}" - , degS = "degree*S^{-1}" - , degW = "degree*W^{-1}" - , empty = "phantom(1)-phantom(1)" - , gcom2oday = "m^{2}*d*a*y^phantom(1)*g*C^{-1}" - , gcokgw = "k*g*W^phantom(1)*g*C^{-1}" - , gcokgcbio = "k*g[C[b*i*o]]^phantom(1)*g*C^{-1}" - , gmt = "G*M*T^{-1}" - , gom3 = "m^3*g^{-1}" - , gocm3 = "c*m^3*g^{-1}" - , gwokg = "k*g^phantom(1)*g*W^{-1}" - , gwokgodec = "k*g^phantom(1)*d*e*c*a*d*e^phantom(1)*k*g*W^{-1}" - , hpa = "h*P*a^{-1}" - , hpaodec = "d*e*c*a*d*e^phantom(1)*h*P*a^{-1}" - , hr = "h*o*u*r^{-1}" - , jokgom2 = "k*g^phantom(1)*m^{-2}*J^{-1}" - , jokgopl = "k*g^phantom(1)*pl^phantom(1)*J^{-1}" - , jom2 = "m^{2}*J^{-1}" - , K = "K^{-1}" - , Kodec = "d*e*c*a*d*e^phantom(1)*K^{-1}" - , k = "K^{-1}" - , kg = "k*g^{-1}" - , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" - , kgcokgn = "k*g*N^phantom(1)*k*g*C^{-1}" - , kgcokgp = "k*g*P^phantom(1)*k*g*C^{-1}" - , kgcom2 = "m^{2}*k*g*C^{-1}" - , kgcom2l = "m[l*e*a*f]^{2}*k*g*C^{-1}" - , kgcom2loyr = "m[l*e*a*f]^{2}*y*r^phantom(1)*k*g*C^{-1}" - , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*C^{-1}" - , kgcom2oyr = "m^{2}*y*r^phantom(1)*k*g*C^{-1}" - , kgcom2oyrodec = "m^{2}*y*r^phantom(1)*d*e*c*a*d*e^phantom(1)*k*g*C^{-1}" - , kgcom3 = "m^{3}*k*g*C^{-1}" - , kgcopl = "p*l*a*n*t^phantom(1)*k*g*C^{-1}" - , kgcoployr = "p*l*a*n*t^phantom(1)*y*r^phantom(1)*k*g*C^{-1}" - , kgokg = "k*g^phantom(1)*k*g^{-1}" - , kgom2 = "m^{2}*k*g^{-1}" - , kgom3 = "m^{3}*k*g^{-1}" - , kgnokg = "k*g^phantom(1)*k*g*N^{-1}" - , kgnom2 = "m^{2}*k*g*N^{-1}" - , kgpokg = "k*g^phantom(1)*k*g*P^{-1}" - , kgwokg = "k*g^phantom(1)*k*g*W^{-1}" - , kgpom2 = "m^{2}*k*g*P^{-1}" - , kgwom2 = "m^{2}*k*g*W^{-1}" - , kgwom2l = "m[l*e*a*f]^{2}*k*g*W^{-1}" - , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwom2ohr = "m^{2}*h*r^phantom(1)*k*g*W^{-1}" - , kgwom2os = "m^{2}*s^phantom(1)*k*g*W^{-1}" - , kgwom2loday = "m[l*e*a*f]^{2}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwom3oday = "m^{-3}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwoploday = "p*l*a*n*t^phantom(1)*d*a*y^phantom(1)*k*g*W^{-1}" - , km = "k*m^{-1}" - , Kmos = "s^phantom(1)*K^{-1}*m^{-1}" - , kpa = "k*P*a^{-1}" - , m = "m^{-1}" - , m2 = "m^{-2}" - , mm = "m*m^{-1}" - , mmodec = "d*e*c*a*d*e^phantom(1)*m*m^^{-1}" - , mmoyrodec = "y*r^phantom(1)*d*e*c*a*d*e^phantom(1)*m*m^^{-1}" - , mm2okgw = "k*g*W^phantom(1)*m*m^{-2}" - , mmoday = "d*a*y^phantom(1)*m*m^{-1}" - , mmohr = "h*r^phantom(1)*m*m^{-1}" - , mmolom2os = "m^{2}*s^phantom(1)*m*m*o*l^{-1}" - , mmomo = "m*o*n*t*h^phantom(1)*^m*m{-1}" - , molom2 = "m^{2}*m*o*l^{-1}" - , molom2l = "m[l*e*a*f]^{2}*m*o*l^{-1}" - , molcom2 = "m^{2}*m*o*l*C^{-1}" - , month = "m*o*n*t*h^{-1}" - , mos = "s^phantom(1)*m^{-1}" - , mosodec = "s^phantom(1)*d*e*c*a*d*e^phantom(1)*m^{-1}" - , m2oha = "h*a^phantom(1)*m^{-2}" - , m2om2 = "m^2*m^{-2}" - , m2om3 = "m^3*m^{-2}" - , m2opl = "p*l^phantom(1)*m^{-2}" - , m2lokgc = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" - , m2lom2 = "m^2*m[l*e*a*f]^{-2}" - , m2lom2odec = "m^{2}*d*e*c*a*d*e^phantom(1)*m[l*e*a*f]^{-2}" - , m2lopl = "p*l^phantom(1)*m[l*e*a*f]^{-2}" - , m2pom2 = "m^2*m[l*e*a*f+w*o*o*d]^{-2}" - , m2popl = "p*l^phantom(1)*m[l*e*a*f+w*o*o*d]^{-2}" - , m2wom2 = "m^2*m[w*o*o*d]^{-2}" - , m2wopl = "p*l^phantom(1)*m[w*o*o*d]^{-2}" - , m3oha = "h*a^phantom(1)*m^{-3}" - , m3om2 = "m^2*m^{-3}" - , m3wom3 = "m^3*m[W]^{-3}" - , Mgcoha = "h*a^phantom(1)*M*g*C^{-1}" - , Mgoha = "h*a^phantom(1)*M*g^{-1}" - , Mgwom2 = "m^{2}*M*g*W^{-1}" - , Mjom2 = "m^{2}*M*J^{-1}" - , mmoyr = "y*r^phantom(1)*m*m^{-1}" - , mpa = "M*P*a^{-1}" - , nmo.090 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" - , nmo.100 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" - , nmo.110 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" - , nmo.120 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" - , nmo.wdef = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" - , nmolomol = "m*o*l^phantom(1)*n*m*o*l^{-1}" - , oneom = "m" - , oneoha = "h*a" - , oneom2 = "m^{2}" - , oneoyr = "y*r" - , oneodec = "d*e*c*a*d*e" - , pa = "P*a^{-1}" - , pc = "'%'^{-1}" - , pcbio = "'%'[b*i*o]^{-1}" - , pcagboyr = "y*r^phantom(1)*'%'[A*G*B]^{-1}" - , pcagbo50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[A*G*B]^{-1}" - , pcareaoyr = "y*r^phantom(1)*'%'[a*r*e*a]^{-1}" - , pcbaoyr = "y*r^phantom(1)*'%'[B*A]^{-1}" - , pcbiooyr = "y*r^phantom(1)*'%'[b*i*o]^{-1}" - , pcdbhoyr = "y*r^phantom(1)*'%'[D*B*H]^{-1}" - , pcetoyr = "y*r^phantom(1)*'%'[E*T]^{-1}" - , pceto50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[E*T]^{-1}" - , pcoyr = "y*r^phantom(1)*'%'^{-1}" - , pcpopoyr = "y*r^phantom(1)*'%'[p*o*p]^{-1}" - , pcsat = "'%'[S*a*t]^{-1}" - , pgc = "P*g*C^{-1}" - , pgcoyr = "y*r^phantom(1)*P*g*C^{-1}" - , plom2 = "m^2*p*l*a*n*t^{-1}" - , ploha = "h*a^phantom(1)*p*l*a*n*t^{-1}" - , s = "s^{-1}" - , t1e3 = "phantom(1)%*%10^{-3}" - , t1e6 = "phantom(1)%*%10^{-6}" - , t1e9 = "phantom(1)%*%10^{-9}" - , thkm2oyr = "y*r^phantom(1)*10^{-3*phantom(1)}*k*m^{-2}" - , umolcom2os = "m^2*s^phantom(1)*mu*m*o*l*C^{-1}" - , umolokgcos = "k*g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" - , umolom2 = "m^2*mu*m*o*l^{-1}" - , umolom2os = "m^2*s^phantom(1)*mu*m*o*l^{-1}" - , umolom2l = "m[l*e*a*f]^2*mu*m*o*l^{-1}" - , umolom2los = "m[l*e*a*f]^2*s^phantom(1)*mu*m*o*l^{-1}" - , umolcom2 = "m^2*mu*m*o*l*C^{-1}" - , umolcomol = "m*o*l^phantom(1)*mu*m*o*l*C^{-1}" - , umolomol = "m*o*l^phantom(1)*mu*m*o*l^{-1}" - , utc = "U*T*C^{-1}" - , wom2 = "m^2*W^{-1}" - , wom2l = "m[l*e*a*f]^{2}*W^phantom(1)" - , wom2oyr = "m^{2}*y*r^phantom(1)*W^{-1}" - , wom2odec = "m^{2}*d*e*c*a*d*e^phantom(1)*W^{-1}" - , wopl = "p*l*a*n*t^phantom(1)*W^{-1}" - , yr = "y*r^{-1}" +i.untab <<- list( cm = "c*m^{-1}" + , cmohaoyr = "h*a^phantom(1)*y*r^phantom(1)*c*m^{-1}" + , cmoyr = "y*r^phantom(1)*c*m^{-1}" + , cm2m = "c*m^{-2}*m^{-1}" + , cm2om2 = "m^2*c*m^{-2}" + , cm2om2odec = "d*e*c^phantom(1)*m^2*c*m^{-2}" + , cm2opl = "p*l*a*n*t^phantom(1)*c*m^{-2}" + , cm2om2oyr = "m^2*y*r^phantom(1)*c*m^{-2}" + , day = "d*a*y^{-1}" + , deg = "degree^{-1}" + , degC = "degree*C^{-1}" + , degCodec = "d*e*c^phantom(1)*degree*C^{-1}" + , degE = "degree*E^{-1}" + , degN = "degree*N^{-1}" + , degS = "degree*S^{-1}" + , degW = "degree*W^{-1}" + , empty = "phantom(1)-phantom(1)" + , gcoday = "d*a*y^phantom(1)*g*C^{-1}" + , gcokg = "k*g^phantom(1)*g*C^{-1}" + , gcom2oday = "m^{2}*d*a*y^phantom(1)*g*C^{-1}" + , gcokgw = "k*g*W^phantom(1)*g*C^{-1}" + , gcokgcbio = "k*g[C[b*i*o]]^phantom(1)*g*C^{-1}" + , gmpaos = "s^phantom(1)*g^{-1}*M*P*a^{-1}" + , gmt = "G*M*T^{-1}" + , gnokg = "k*g^phantom(1)*g*N^{-1}" + , gom2oday = "m^{2}*d*a*y^phantom(1)*g^{-1}" + , gom3 = "m^3*g^{-1}" + , gocm3 = "c*m^3*g^{-1}" + , gocm3odec = "d*e*c^phantom(1)*c*m^3*g^{-1}" + , gokg = "k*g^phantom(1)*g^{-1}" + , gpokg = "k*g^phantom(1)*g*P^{-1}" + , gwokg = "k*g^phantom(1)*g*W^{-1}" + , gwokgodec = "k*g^phantom(1)*d*e*c^phantom(1)*k*g*W^{-1}" + , ha = "h*a^{-1}" + , hpa = "h*P*a^{-1}" + , hpaodec = "d*e*c^phantom(1)*h*P*a^{-1}" + , hr = "h*o*u*r^{-1}" + , jokgom2 = "k*g^phantom(1)*m^{-2}*J^{-1}" + , jokgopl = "k*g^phantom(1)*pl^phantom(1)*J^{-1}" + , jom2 = "m^{2}*J^{-1}" + , K = "K^{-1}" + , Kodec = "d*e*c^phantom(1)*K^{-1}" + , k = "K^{-1}" + , kg = "k*g^{-1}" + , kgc = "k*g*C^{-1}" + , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" + , kgcokgn = "k*g*N^phantom(1)*k*g*C^{-1}" + , kgcokgp = "k*g*P^phantom(1)*k*g*C^{-1}" + , kgcom2 = "m^{2}*k*g*C^{-1}" + , kgcom2odec = "d*e*c^phantom(1)*m^{2}*k*g*C^{-1}" + , kgcom2l = "m[l*e*a*f]^{2}*k*g*C^{-1}" + , kgcom2loyr = "m[l*e*a*f]^{2}*y*r^phantom(1)*k*g*C^{-1}" + , kgcom2loyrodec = "m[l*e*a*f]^{2}*y*r^phantom(1)*d*e*c^phantom(1)*k*g*C^{-1}" + , kgcom2oday = "m^{2}*d*a*y^phantom(1)*k*g*C^{-1}" + , kgcom2oyr = "m^{2}*y*r^phantom(1)*k*g*C^{-1}" + , kgcom2oyrodec = "m^{2}*y*r^phantom(1)*d*e*c^phantom(1)*k*g*C^{-1}" + , kgcom3 = "m^{3}*k*g*C^{-1}" + , kgcopl = "p*l*a*n*t^phantom(1)*k*g*C^{-1}" + , kgcoployr = "p*l*a*n*t^phantom(1)*y*r^phantom(1)*k*g*C^{-1}" + , kgcoyr = "y*r^phantom(1)*k*g*C^{-1}" + , kgokg = "k*g^phantom(1)*k*g^{-1}" + , kgom2 = "m^{2}*k*g^{-1}" + , kgom3 = "m^{3}*k*g^{-1}" + , kgomos2 = "m^phantom(1)*s^{2}*k*g^{-1}" + , kgnokg = "k*g^phantom(1)*k*g*N^{-1}" + , kgnokgp = "k*g*P^phantom(1)*k*g*N^{-1}" + , kgnom2 = "m^{2}*k*g*N^{-1}" + , kgpokg = "k*g^phantom(1)*k*g*P^{-1}" + , kgwokg = "k*g^phantom(1)*k*g*W^{-1}" + , kgpom2 = "m^{2}*k*g*P^{-1}" + , kgwom2 = "m^{2}*k*g*W^{-1}" + , kgwom2l = "m[l*e*a*f]^{2}*k*g*W^{-1}" + , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom2odec = "m^{2}*d*e*c^phantom(1)*k*g*W^{-1}" + , kgwom2ohr = "m^{2}*h*r^phantom(1)*k*g*W^{-1}" + , kgwom2os = "m^{2}*s^phantom(1)*k*g*W^{-1}" + , kgwom2loday = "m[l*e*a*f]^{2}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom3oday = "m^{-3}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom3ompa = "m^{-3}*M*P*a^phantom(1)*k*g*W^{-1}" + , kgwomosompa = "m^phantom(1)*s^phantom(1)*M*P*a^phantom(1)*kg^{-1}" + , kgwoploday = "p*l*a*n*t^phantom(1)*d*a*y^phantom(1)*k*g*W^{-1}" + , km = "k*m^{-1}" + , Kmos = "s^phantom(1)*K^{-1}*m^{-1}" + , kpa = "k*P*a^{-1}" + , kwom = "m^phantom(1)*k*W^{-1}" + , m = "m^{-1}" + , m2 = "m^{-2}" + , m2ocm2 = "c*m^2*m^{-2}" + , mg = "m*g^{-1}" + , min = "m*i*n^{-1}" + , mm = "m*m^{-1}" + , mmodec = "d*e*c^phantom(1)*m*m^^{-1}" + , mmoyrodec = "y*r^phantom(1)*d*e*c^phantom(1)*m*m^^{-1}" + , mm2okgw = "k*g*W^phantom(1)*m*m^{-2}" + , mmoday = "d*a*y^phantom(1)*m*m^{-1}" + , mmodayodec = "d*a*y^phantom(1)*d*e*c^phantom(1)*m*m^{-1}" + , mmohr = "h*r^phantom(1)*m*m^{-1}" + , mmologos = "g^phantom(1)*s^phantom(1)*m*m*o*l^{-1}" + , mmolokgos = "k*g^phantom(1)*s^phantom(1)*m*m*o*l^{-1}" + , mmolom2os = "m^{2}*s^phantom(1)*m*m*o*l^{-1}" + , mmolom2osompa = "m^{2}*s^phantom(1)*M*P*a^phantom(1)*m*m*o*l^{-1}" + , mmolcokg = "m*m*o*l*C^phantom(1)*k*g^{-1}" + , mmomo = "m*o*n*t*h^phantom(1)*^m*m{-1}" + , mokg = "k*g^phantom(1)*m^{-1}" + , molom2 = "m^{2}*m*o*l^{-1}" + , molom2l = "m[l*e*a*f]^{2}*m*o*l^{-1}" + , molcom2 = "m^{2}*m*o*l*C^{-1}" + , month = "m*o*n*t*h^{-1}" + , monthodec = "d*e*c^phantom(1)*m*o*n*t*h^{-1}" + , mos = "s^phantom(1)*m^{-1}" + , momin = "m*i*n^phantom(1)*m^{-1}" + , mosodec = "s^phantom(1)*d*e*c^phantom(1)*m^{-1}" + , m2oha = "h*a^phantom(1)*m^{-2}" + , m2ohaoyr = "h*a^phantom(1)*m^{2}*y*r^phantom(1)*h*a^{-1}" + , m2okg = "k*g^phantom(1)*m^{-2}" + , m2om2 = "m^2*m^{-2}" + , m2om3 = "m^3*m^{-2}" + , m2opl = "p*l^phantom(1)*m^{-2}" + , m2lokg = "k*g^phantom(1)*m[l*e*a*f]^{-2}" + , m2lokgc = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , m2lokgcodec = "d*e*c^phantom(1)*k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , m2lom2 = "m^2*m[l*e*a*f]^{-2}" + , m2lom2odec = "m^{2}*d*e*c^phantom(1)*m[l*e*a*f]^{-2}" + , m2lopl = "p*l^phantom(1)*m[l*e*a*f]^{-2}" + , m2pom2 = "m^2*m[l*e*a*f+w*o*o*d]^{-2}" + , m2popl = "p*l^phantom(1)*m[l*e*a*f+w*o*o*d]^{-2}" + , m2wom2 = "m^2*m[w*o*o*d]^{-2}" + , m2wopl = "p*l^phantom(1)*m[w*o*o*d]^{-2}" + , m3oha = "h*a^phantom(1)*m^{-3}" + , m3om2 = "m^2*m^{-3}" + , m3wom3 = "m^3*m[W]^{-3}" + , Mgcoha = "h*a^phantom(1)*M*g*C^{-1}" + , Mgoha = "h*a^phantom(1)*M*g^{-1}" + , Mgwom2 = "m^{2}*M*g*W^{-1}" + , Mjom2 = "m^{2}*M*J^{-1}" + , mmoyr = "y*r^phantom(1)*m*m^{-1}" + , mpa = "M*P*a^{-1}" + , mpaodec = "d*e*c^phantom(1)*M*P*a^{-1}" + , mwom2ok = "m^{2}*K^phantom(1)*m*W^{-1}" + , nmo.090 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" + , nmo.100 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" + , nmo.110 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" + , nmo.120 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" + , nmo.wdef = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" + , nmolomol = "m*o*l^phantom(1)*n*m*o*l^{-1}" + , oneoday = "d*a*y" + , oneom = "m" + , oneoha = "h*a" + , oneok = "K" + , oneokm2 = "k*m^{2}" + , oneokm2oday = "k*m^{2}*d*a*y" + , oneokm2omo = "k*m^{2}*m*o*n*t*h" + , oneom2 = "m^{2}" + , oneoyr = "y*r" + , oneodec = "d*e*c" + , pa = "P*a^{-1}" + , pc = "'%'^{-1}" + , pcoday = "d*a*y^phantom(1)*'%'^{-1}" + , pcodec = "d*e*c^phantom(1)*'%'^{-1}" + , pcbio = "'%'[b*i*o]^{-1}" + , pcagboyr = "y*r^phantom(1)*'%'[A*G*B]^{-1}" + , pcagboyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[A*G*B]^{-1}" + , pcagbo50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[A*G*B]^{-1}" + , pcareaoyr = "y*r^phantom(1)*'%'[a*r*e*a]^{-1}" + , pcbaoyr = "y*r^phantom(1)*'%'[B*A]^{-1}" + , pcbiooyr = "y*r^phantom(1)*'%'[b*i*o]^{-1}" + , pcbiooyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[b*i*o]^{-1}" + , pcdbhoyr = "y*r^phantom(1)*'%'[D*B*H]^{-1}" + , pcdbhoyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[D*B*H]^{-1}" + , pcetoyr = "y*r^phantom(1)*'%'[E*T]^{-1}" + , pceto50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[E*T]^{-1}" + , pcoyr = "y*r^phantom(1)*'%'^{-1}" + , pcoyrodec = "y*r^phantom(1)*d*e*c^phantom(1)*'%'^{-1}" + , pcpopoyr = "y*r^phantom(1)*'%'[p*o*p]^{-1}" + , pcsat = "'%'[S*a*t]^{-1}" + , pgc = "P*g*C^{-1}" + , pgcoyr = "y*r^phantom(1)*P*g*C^{-1}" + , plom2 = "m^2*p*l*a*n*t^{-1}" + , plom2odec = "d*e*c^phantom(1)*m^2*p*l*a*n*t^{-1}" + , ploha = "h*a^phantom(1)*p*l*a*n*t^{-1}" + , plohaoyr = "h*a^phantom(1)*y*r^phantom(1)*p*l*a*n*t^{-1}" + , plohaodec = "d*e*c^phantom(1)*h*a^phantom(1)*p*l*a*n*t^{-1}" + , s = "s^{-1}" + , t1e3 = "phantom(1)%*%10^{-3}" + , t1e6 = "phantom(1)%*%10^{-6}" + , t1e9 = "phantom(1)%*%10^{-9}" + , thkm2oyr = "y*r^phantom(1)*10^{-3*phantom(1)}*k*m^{-2}" + , umolcom2os = "m^2*s^phantom(1)*mu*m*o*l*C^{-1}" + , umologcos = "g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umologos = "g^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolokgcos = "k*g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolokgos = "k*g^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolom2 = "m^2*mu*m*o*l^{-1}" + , umolom2os = "m^2*s^phantom(1)*mu*m*o*l^{-1}" + , umolom2l = "m[l*e*a*f]^2*mu*m*o*l^{-1}" + , umolom2los = "m[l*e*a*f]^2*s^phantom(1)*mu*m*o*l^{-1}" + , umolcom2 = "m^2*mu*m*o*l*C^{-1}" + , umolcomol = "m*o*l^phantom(1)*mu*m*o*l*C^{-1}" + , umolomol = "m*o*l^phantom(1)*mu*m*o*l^{-1}" + , umolomolodec = "d*e*c^phantom(1)*m*o*l^phantom(1)*mu*m*o*l^{-1}" + , usd = "U*S*D^{-1}" + , usdoyr = "y*r^phantom(1)*U*S*D^{-1}" + , utc = "U*T*C^{-1}" + , wom2 = "m^2*W^{-1}" + , wom2l = "m[l*e*a*f]^{2}*W^phantom(1)" + , wom2oyr = "m^{2}*y*r^phantom(1)*W^{-1}" + , wom2odec = "m^{2}*d*e*c^phantom(1)*W^{-1}" + , wopl = "p*l*a*n*t^phantom(1)*W^{-1}" + , yr = "y*r^{-1}" + , zscore = "Z[s*c*o*r*e]^{-1}" + , zscoreodec = "d*e*c^phantom(1)*Z[s*c*o*r*e]^{-1}" )#end list #==========================================================================================# #==========================================================================================# diff --git a/R-utils/vcf.degrad.r b/R-utils/vcf.degrad.r index 0f76b6082..4d526a2b6 100644 --- a/R-utils/vcf.degrad.r +++ b/R-utils/vcf.degrad.r @@ -89,13 +89,13 @@ vcf.degrad <<- function(shrub,tree,bare){ #----- Create vector by classes. -------------------------------------------------------# - vc0 = tree %>=% 0.75 - vc1 = tree %>=% 0.50 & tree %<% 0.75 & bare %<% 0.20 - vc2 = tree %>=% 0.50 & tree %<% 0.75 & bare %>=% 0.20 - vc3 = tree %>=% 0.25 & tree %<% 0.50 & bare %<% 0.20 - vc4 = tree %>=% 0.25 & tree %<% 0.50 & bare %>=% 0.20 & bare %<% 0.50 - vc5 = tree %<% 0.25 & bare %<% 0.50 - vc6 = bare %>=% 0.50 + vc0 = tree %ge% 0.75 + vc1 = tree %ge% 0.50 & tree %lt% 0.75 & bare %lt% 0.20 + vc2 = tree %ge% 0.50 & tree %lt% 0.75 & bare %ge% 0.20 + vc3 = tree %ge% 0.25 & tree %lt% 0.50 & bare %lt% 0.20 + vc4 = tree %ge% 0.25 & tree %lt% 0.50 & bare %ge% 0.20 & bare %lt% 0.50 + vc5 = tree %lt% 0.25 & bare %lt% 0.50 + vc6 = bare %ge% 0.50 #---------------------------------------------------------------------------------------# diff --git a/R-utils/wapply.r b/R-utils/wapply.r index ba6ab446e..eac3503b6 100644 --- a/R-utils/wapply.r +++ b/R-utils/wapply.r @@ -12,7 +12,7 @@ wapply <<- function(X,W,FUN,cyclic=FALSE,...){ #----- Additional sanity checks. -------------------------------------------------------# if (! is.vector(X)) stop ("X must be a vector!") - if (W %>=% length(X)) stop ("W must be less than the length of X") + if (W %ge% length(X)) stop ("W must be less than the length of X") #---------------------------------------------------------------------------------------# diff --git a/R-utils/xy.density.r b/R-utils/xy.density.r index 0c481378e..faa53c275 100644 --- a/R-utils/xy.density.r +++ b/R-utils/xy.density.r @@ -169,7 +169,7 @@ xy.density <<- function( x zdens = 100. * zdens[[3]] / sum(zdens[[3]]) }#end if (method %in% "table") zlwr = zignore * max(zdens,na.rm=TRUE) - zdens = 0. * zdens + ifelse(test=zdens %>=% zlwr,yes=zdens,no=0.) + zdens = 0. * zdens + ifelse(test=zdens %ge% zlwr,yes=zdens,no=0.) #---------------------------------------------------------------------------------------# @@ -436,7 +436,7 @@ xy.density <<- function( x plot.new() plot.window(xlim=xlim,ylim=ylim,log=plog,xaxs=xaxs,yaxs=yaxs,...) zupr = zlim[1] + (1.-sqrt(.Machine$double.eps))*diff(zlim) - zdens = pmin(zupr,zdens) + ifelse(zdens %>% 0,0,NA) + 0. * zdens + zdens = pmin(zupr,zdens) + ifelse(zdens %gt% 0,0,NA) + 0. * zdens xyz = list(x=xdens,y=ydens,z=zdens) image(x=xyz,zlim=zlim,col=ccolours,breaks=clevels,add=TRUE,useRaster=useRaster) #====================================================================================# @@ -447,7 +447,7 @@ xy.density <<- function( x # Plot the main panel on existing box. # #------------------------------------------------------------------------------------# zupr = zlim[1] + (1.-sqrt(.Machine$double.eps))*diff(zlim) - zdens = pmin(zupr,zdens) + ifelse(zdens %>% 0,0,NA) + 0. * zdens + zdens = pmin(zupr,zdens) + ifelse(zdens %gt% 0,0,NA) + 0. * zdens xyz = list(x=xdens,y=ydens,z=zdens) image(x=xyz,zlim=zlim,col=ccolours,breaks=clevels,add=TRUE,useRaster=useRaster) #====================================================================================# diff --git a/R-utils/zen.r b/R-utils/zen.r index 174061bcd..9574bb81b 100644 --- a/R-utils/zen.r +++ b/R-utils/zen.r @@ -143,21 +143,131 @@ ed.zen <<- function (lon,lat,when,ed21=TRUE,zeronight=FALSE,meanval=FALSE,imetav #------ Find the cosine of the zenith angle, the zenith angle, and day/night flag. -----# - COSZ = SLAT * SDEC + CLAT * CDEC * CHRA - cosz = rowMeans(COSZ,...) - zen = acos(cosz) / pio180 - hgt = 90. - zen - declin = rowMeans(DECLIN,...) / pio180 - night = cosz < cosz.twilight - day = cosz >= cosz.min + COSZ = SLAT * SDEC + CLAT * CDEC * CHRA + cosz = rowMeans(COSZ,...) + zen = acos(cosz) / pio180 + hgt = 90. - zen + declin = rowMeans(DECLIN,...) / pio180 + night = cosz < cosz.twilight + day = cosz >= cosz.min + twilight = (! day) & (! night) if (zeronight){ cosz[night] = 0. hgt [night] = 0. zen [night] = 90. }#end if - ans = data.frame(cosz=cosz,zen=zen,hgt=hgt,declin=declin,day=day,night=night) + ans = data.frame( cosz = cosz + , zen = zen + , hgt = hgt + , declin = declin + , day = day + , night = night + , twilight = twilight + )#end data.frame return(ans) }#end function ed.zen #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Fast version to obtain the cosine of zenith angle, when no averaging is needed. This # +# accepts either one entry for longitude/latitude, and multiple times, or it takes the # +# same number of longitudes, latitudes and times. # +# # +# Input variables: # +# - lon, lat - Longitudes and latitudes. Either single values or vectors with the # +# the same length as when (see below). # +# - when - time. Mandatory, one point only or a vector. # +# - ed21 - I shall use ED-2.1 method (TRUE/FALSE). Default is TRUE # +# - zeronight - The cosine of zenith angle shall be set to zero at night. # +# Default is FALSE # +# # +# The output is going to be a vector with cosines of with the following values: # +#------------------------------------------------------------------------------------------# +fast.zen <<- function (lon,lat,when,ed21=TRUE,zeronight=FALSE){ + #------ Constants. ---------------------------------------------------------------------# + dcoeff = c( 0.006918, -0.399912, 0.070257, -0.006758, 0.000907, -0.002697, 0.001480) + #---------------------------------------------------------------------------------------# + + + #------ Ensure longitude and latitude sizes are compatible with times. -----------------# + nlon = length(lon) + nlat = length(lat) + nwhen = length(when) + if (! ( (nlon %in% c(1,nwhen)) && (nlat %in% c(1,nwhen)) ) ){ + cat0(" - Longitude size:",nlon ) + cat0(" - Latitude size: ",nlat ) + cat0(" - Time size: ",nwhen) + stop(" Longitude/latidude should be either scalars of vectors consistent with when!") + }#end if (length(unique(c(nlon,lat,nwhen))) != 1) + if (nlon == 1) lon = rep(lon,times=nwhen) + if (nlat == 1) lat = rep(lat,times=nwhen) + #---------------------------------------------------------------------------------------# + + + + #------ Find the day of year, list of leap year times, and sun hour. -------------------# + doy = dayofyear(when) + leap = is.leap (when) + fracday = hms2frac (when) + sunhr = (fracday * day.hr + lon / 15. + day.hr) %% day.hr + #---------------------------------------------------------------------------------------# + + + + #------ Find the hour angle and its cosine. --------------------------------------------# + hrangle = 15 * (sunhr - 12) * pio180 + chra = cos(hrangle) + #---------------------------------------------------------------------------------------# + + + + #------ Find the declination. ----------------------------------------------------------# + if (ed21){ + doyfun = ifelse( test = leap + , yes = 2 * pi * (doy - shsummer) / 366. + , no = 2 * pi * (doy - shsummer) / 365. + )#end ifelse + declin = capri * cos(doyfun) + }else{ + doyfun = ifelse( test = leap + , yes = 2 * pi * (doy - 1) / 366. + , no = 2 * pi * (doy - 1) / 365 + )#end ifelse + + declin = ( dcoeff[1] + + dcoeff[2] * cos(1.*doyfun) + dcoeff[3] * sin(1.*doyfun) + + dcoeff[4] * cos(2.*doyfun) + dcoeff[5] * sin(2.*doyfun) + + dcoeff[6] * cos(3.*doyfun) + dcoeff[7] * sin(3.*doyfun) ) + }#end if + #---------------------------------------------------------------------------------------# + + + #------ Find the cosine and sine of latitude and declination. --------------------------# + clat = cos(pio180*lat) + slat = sin(pio180*lat) + cdec = cos(declin) + sdec = sin(declin) + #---------------------------------------------------------------------------------------# + + + + #------ Find the cosine of the zenith angle, the zenith angle, and day/night flag. -----# + cosz = slat * sdec + clat * cdec * chra + if (zeronight){ + cosz = 0. * cosz + pmax(0.,cosz) + }#end if + #---------------------------------------------------------------------------------------# + + rm(clat,slat,cdec,sdec,doy,leap,fracday,sunhr,hrangle,chra,doyfun,declin) + return(cosz) +}#end function fast.zen +#==========================================================================================# +#==========================================================================================# diff --git a/README.md b/README.md index cb0bdb99a..d0d7881de 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ 4. Implementation Notes 5. Further Information 6. Code Development, Pull Requests, and Commits +7. Using Docker ## Model Overview @@ -38,7 +39,7 @@ The primary data structure in ED, which can be found in ed_state_vars.F90, is a - site: A collection of patches sharing a common soil system and ground hydrology. - patch: A collection of cohorts sharing a disturbance history and age. - cohort: A collection of plants of identical PFT and height. - + Note: height and age, being continuous variables, are "binned". "Identical" in this context means sufficiently similar to be placed in the same bin. These bins are dynamically defined, based on the number of classes sought by the user and the similarity along the age and height axes. ## Further Information @@ -53,3 +54,23 @@ If you plan to develop the code, please refer to the Wiki entries on Doxygen instructions, and especially the Doxygen and Git commits section, so additional documentation can be automatically generated from the source code comments. +## Using Docker + +To use ED2 with Docker use either the `Dockerfile.gnu` for the GNU compiler (works with both x86 and arm64) or `Dockerfile.intel` which compiled ED2 using the intel compiler (x86 only). For example the following command builds the GNU version (run this in the root of the ED2 source code): + +``` +docker build -t edmodel/ed2:gnu -f Dockerfile.gnu . +``` + +Once you have build ED2 model you can run it using: + +```bash +docker run -ti --rm --ulimit stack=-1 --volume ${PWD}:/data edmodel/ed2:gnu +``` + +`-ti` : tells docker to use an interactive shell session +`--rm` : will remove the container after it finishes running, make sure outputs are written to /data or current folder +`--ulimit stack=-1` : set the stack to be unlimited in size, this is needed otherwise ED2 will coredump +`--volume ${PWD}:/data` : mounts the current folder to the /data folder. This is where the container starts + +If no arguments are given it will run `ed2` in the /data folder. Otherwise you can pass in any arguments, for example you can use `ed2 -f Templates/ED2IN-tonzi.harvest` to run ed2 with the input file Templates/ED2IN-tonzi.harvest. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..6b14275d4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +ED2 is a numerical model that reads in multiple data sets and generates simulation output files. The code development is guided towards making the code safe to use and should not pose any system vulnerability. +However, we recommend using only data that come from trusted sources and to use the model with full understanding that the simulations can be memory intensive and require large storage depending on the configuration. + +Please do not post anything on issues, discussions or pull requests that can lead to data deletion or can damage operating systems. This is not acceptable through our code of conduct. + +## Supported Versions + +We strongly recommend to keep the code up to date with the most recent tags and commits. + +## Reporting a Vulnerability + +If you find a potential vulnerability in the ED2 code, the best way of reporting it is by documenting it as an issue. If you know how to fix the vulnerability, please submit a pull request and the development team will address the matter and follow up with you through GitHub. diff --git a/count_lines.sh b/count_lines.sh index 749a11e1c..9af307bdf 100755 --- a/count_lines.sh +++ b/count_lines.sh @@ -16,11 +16,13 @@ do ;; *) echo -n " - Directory ${dir}: " - files=$(/bin/ls -1 ${model}/src/${dir}) + files=$(/bin/ls -1 ${model}/src/${dir}/*.F90 2> /dev/null) + files="${files} $(/bin/ls -1 ${model}/src/${dir}/*.f90 2> /dev/null)" + files="${files} $(/bin/ls -1 ${model}/src/${dir}/*.c 2> /dev/null)" dirlines=0 for file in ${files} do - nlines=$(sed '/^ *$/ d' ${model}/src/${dir}/${file} | wc -l) + nlines=$(sed '/^ *$/ d' ${file} | wc -l | awk '{print $1}') let dirlines=${dirlines}+${nlines} done echo "${dirlines} lines" diff --git a/diff_version.sh b/diff_version.sh index 77a083c15..3e69ceee0 100755 --- a/diff_version.sh +++ b/diff_version.sh @@ -24,9 +24,11 @@ subdirs="ED BRAMS Ramspost R-utils" #------ Editor to use (I've only tested with nedit, use others at your own risk). ---------# editor="nedit" #------ Two paths with EDBRAMS (full path). -----------------------------------------------# -ours="${HOME}/EDBRAMS" -theirs="${HOME}/MainLine/EDBRAMS" -ournew=true +ours="${HOME}/Downloads/MLN-EDBRAMS" +theirs="${HOME}/Downloads/MLO-EDBRAMS" +ournew=false +#------ Working path when implementing a partial merge (otherwise, leave it blank). -------# +work="${HOME}/Models/EDBRAMS" #------------------------------------------------------------------------------------------# @@ -36,8 +38,8 @@ ournew=true # Extensions. Decide how much to check. # #------------------------------------------------------------------------------------------# case "${comptype}" in -partial) exts=".c .f90 .F90" ;; -*) exts=".c .f90 .F90 .r .txt" ;; +partial) exts=".c .F90 .f90" ;; +*) exts=".c .F90 .f90 .r .txt" ;; esac #------------------------------------------------------------------------------------------# @@ -45,7 +47,24 @@ esac #------------------------------------------------------------------------------------------# # Remove any comparison file that may exist. # #------------------------------------------------------------------------------------------# -/bin/rm -f notthesame.* +/bin/rm -f notthesame.* \~notthesame.* +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +# Add settings for partial merge (if sought). # +#------------------------------------------------------------------------------------------# +if [[ "${work}" == "" ]] +then + #---- Disable work version (preferred method, much less messy). ------------------------# + load_work=false + work=${theirs} + #---------------------------------------------------------------------------------------# +else + #---- Enable work version (more prone to complications, be careful). -------------------# + load_work=true + #---------------------------------------------------------------------------------------# +fi #------------------------------------------------------------------------------------------# @@ -60,11 +79,11 @@ do #---------------------------------------------------------------------------------------# for ext in ${exts} do - if [ ${subdir} == "R-utils" ] && [ ${ext} == ".txt" ] + if [[ ${subdir} == "R-utils" ]] && [[ ${ext} == ".txt" ]] then srcours="${ours}/${subdir}/samap" srctheirs="${theirs}/${subdir}/samap" - elif [ ${subdir} == "R-utils" ] + elif [[ ${subdir} == "R-utils" ]] then srcours="${ours}/${subdir}" srctheirs="${theirs}/${subdir}" @@ -82,12 +101,14 @@ do for fileours in ${lookuptable} do file=$(basename ${fileours}) - newpath=$(dirname ${fileours} | sed s@${ours}@${theirs}@g) + theirpath=$(dirname ${fileours} | sed s@${ours}@${theirs}@g) + workpath=$(dirname ${fileours} | sed s@${ours}@${work}@g) case "${myos}" in Darwin|Cygwin) #---- Case-insensitive file system. ---------------------------------------------# - filetheirs="${newpath}/${file}" - alt="" + filetheirs="${theirpath}/${file}" + filework="${workpath}/${file}" + theirs_alt="" ;; #--------------------------------------------------------------------------------# *) @@ -95,64 +116,154 @@ do case "${ext}" in ".f90") alt_file=$(echo ${file} | sed s@"\\.f90"@".F90"@g) - if [ -s "${newpath}/${alt_file}" ] + if [[ -s "${theirpath}/${alt_file}" ]] then - filetheirs="${newpath}/${alt_file}" - alt=".F90" + filetheirs="${theirpath}/${alt_file}" + theirs_alt=".F90" else - filetheirs="${newpath}/${file}" - alt="" + filetheirs="${theirpath}/${file}" + theirs_alt="" fi ;; ".F90") alt_file=$(echo ${file} | sed s@"\\.F90"@".f90"@g) - if [ -s "${newpath}/${alt_file}" ] + if [[ -s "${theirpath}/${alt_file}" ]] then - filetheirs="${newpath}/${alt_file}" - alt=".f90" + filetheirs="${theirpath}/${alt_file}" + theirs_alt=".f90" else - filetheirs="${newpath}/${file}" - alt="" + filetheirs="${theirpath}/${file}" + theirs_alt="" fi ;; *) - filetheirs="${newpath}/${file}" - alt="" + filetheirs="${theirpath}/${file}" + theirs_alt="" ;; esac - ;; #--------------------------------------------------------------------------------# + + + #----- Probably Linux or Unix, assume case-sensitive file system. ---------------# + case "${ext}" in + ".f90") + alt_file=$(echo ${file} | sed s@"\\.f90"@".F90"@g) + if [[ -s "${workpath}/${alt_file}" ]] + then + filework="${workpath}/${alt_file}" + work_alt=".F90" + else + filework="${workpath}/${file}" + work_alt="" + fi + ;; + ".F90") + alt_file=$(echo ${file} | sed s@"\\.F90"@".f90"@g) + if [[ -s "${workpath}/${alt_file}" ]] + then + filework="${workpath}/${alt_file}" + work_alt=".f90" + else + filework="${workpath}/${file}" + work_alt="" + fi + ;; + *) + filework="${workpath}/${file}" + work_alt="" + ;; + esac + #--------------------------------------------------------------------------------# + + ;; esac - filetheirs="${newpath}/${file}" - if [ -s ${filetheirs} ] + + + #-----------------------------------------------------------------------------------# + # If we are doing partial merge, we must check the existence three-way, # + # otherwise we compare just the "ours" and "theirs". # + #-----------------------------------------------------------------------------------# + if [[ -s ${filetheirs} ]] then - ldif=$(diff -ibB <(grep -vE "^\s*!" ${fileours}) <(grep -vE "^\s*!" ${filetheirs}) | wc -l) - if [ ${ldif} -gt 0 ] - then - woroot=$(echo ${fileours} | sed s@"${srcours}/"@""@g) - case "${alt}" in - .f90|.F90) - echo "${woroot} has changed. New extension is ${alt}." - ;; - *) - echo "${woroot} has changed." - ;; - esac - if ${ournew} - then - diff -uibB <(grep -vE "^\s*!" ${filetheirs}) <(grep -vE "^\s*!" ${fileours})\ - > notthesame${ext} - else - diff -uibB <(grep -vE "^\s*!" ${fileours}) <(grep -vE "^\s*!" ${filetheirs})\ - > notthesame${ext} - fi - ${editor} ${fileours} ${filetheirs} notthesame${ext} 1> /dev/null 2> /dev/null - /bin/rm -f notthesame${ext} - fi + #---- Check for extension change. -----------------------------------------------# + woroot=$(echo ${fileours} | sed s@"${srcours}/"@""@g) + case "${theirs_alt}" in + .f90|.F90) + if ${ournew} + then + ext_mess="Old extension was ${theirs_alt}." + else + ext_mess="New extension is ${theirs_alt}." + fi + ;; + *) + ext_mess="" + ;; + esac + #--------------------------------------------------------------------------------# + + + + #--------------------------------------------------------------------------------# + # Check for changes (ignoring spaces and commented lines). # + #--------------------------------------------------------------------------------# + ldif=$(diff -ibB <(grep -vE "^\s*!" ${fileours}) <(grep -vE "^\s*!" ${filetheirs}) | wc -l) + if [[ ${ldif} -gt 0 ]] + then + change=true + if [[ "${ext_mess}" == "" ]] + then + echo "File ${woroot}. Code has changed." + else + echo "File ${woroot}. Code has changed. ${ext_mess}" + fi + elif [[ "${ext_mess}" == "" ]] + then + change=false + else + change=false + echo "File ${woroot}. ${ext_mess}" + fi + #--------------------------------------------------------------------------------# + + + #--------------------------------------------------------------------------------# + # If files have changes, report differences. # + #--------------------------------------------------------------------------------# + if ${change} + then + #----- Write differences to a temporary file. --------------------------------# + if ${ournew} + then + diff -uibB <(grep -vE "^\s*!" ${filetheirs}) \ + <(grep -vE "^\s*!" ${fileours}) > notthesame${ext} + else + diff -uibB <(grep -vE "^\s*!" ${fileours}) \ + <(grep -vE "^\s*!" ${filetheirs}) > notthesame${ext} + fi + #-----------------------------------------------------------------------------# + + + #----- Open editor with all files needed. ------------------------------------# + if ${load_work} && [[ -s ${filework} ]] + then + ${editor} ${filework} ${filetheirs} notthesame${ext} \ + 1> /dev/null 2> /dev/null + /bin/rm -f notthesame${ext} + elif ${load_work} + then + ${editor} ${filetheirs} notthesame${ext} 1> /dev/null 2> /dev/null + echo " ---> Working file is missing!" + else + ${editor} ${fileours} ${filetheirs} notthesame${ext} \ + 1> /dev/null 2> /dev/null + fi + #-----------------------------------------------------------------------------# + fi else - woroot=$(echo ${fileours} | sed s@"${srcours}/"@""@g) - echo "${woroot} is exclusive to ${ours} version." - fi #if [ -s ${filetheirs} ] + woroot=$(echo ${fileours} | sed s@"${srcours}/"@""@g) + echo "${woroot} is exclusive to ${ours} version." + fi #if [[ -s ${filetheirs} ]] done #for fileours in ${lookuptable} #-------------------------------------------------------------------------------------# @@ -165,13 +276,13 @@ do for filetheirs in ${lookuptable} do file=$(basename ${filetheirs}) - newpath=$(dirname ${filetheirs} | sed s@${theirs}@${ours}@g) - fileours="${newpath}/${file}" - if [ ! -s ${fileours} ] + ourpath=$(dirname ${filetheirs} | sed s@${theirs}@${ours}@g) + fileours="${ourpath}/${file}" + if [[ ! -s ${fileours} ]] then woroot=$(echo ${filetheirs} | sed s@"${srctheirs}/"@""@g) echo "${woroot} is exclusive to ${theirs} version." - fi #if [ -s ${filetheirs} ] + fi #if [[ -s ${filetheirs} ]] done #for fileours in ${lookuptable} #-------------------------------------------------------------------------------------# done #for ext in ${exts}