diff --git a/.github/workflows/coupled-api.yml b/.github/workflows/coupled-api.yml index 2d99b45967..ace02ee790 100644 --- a/.github/workflows/coupled-api.yml +++ b/.github/workflows/coupled-api.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1f5a64ac56..8b3dc944bd 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/documentation-and-style.yml b/.github/workflows/documentation-and-style.yml index 3ca7f0e613..857db917b6 100644 --- a/.github/workflows/documentation-and-style.yml +++ b/.github/workflows/documentation-and-style.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/expression.yml b/.github/workflows/expression.yml index 5860d32e37..3cd19ee18c 100644 --- a/.github/workflows/expression.yml +++ b/.github/workflows/expression.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/macos-regression.yml b/.github/workflows/macos-regression.yml index d769e15131..16e2e15f80 100644 --- a/.github/workflows/macos-regression.yml +++ b/.github/workflows/macos-regression.yml @@ -17,7 +17,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/macos-stencil.yml b/.github/workflows/macos-stencil.yml index 6e77a5c4a6..a30ad17199 100644 --- a/.github/workflows/macos-stencil.yml +++ b/.github/workflows/macos-stencil.yml @@ -17,7 +17,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/other.yml b/.github/workflows/other.yml index 2cba17ae76..9a941bafa9 100644 --- a/.github/workflows/other.yml +++ b/.github/workflows/other.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/perfmon.yml b/.github/workflows/perfmon.yml index 8fd314cee3..a66ba90643 100644 --- a/.github/workflows/perfmon.yml +++ b/.github/workflows/perfmon.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 7cdd0a5cd6..107948d5da 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/stencil.yml b/.github/workflows/stencil.yml index c85945072c..d46da6e4fa 100644 --- a/.github/workflows/stencil.yml +++ b/.github/workflows/stencil.yml @@ -11,7 +11,7 @@ jobs: working-directory: .testing steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 55494696ae..39512c0dd1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,7 @@ stages: # that is unique to this pipeline. # We use the "fetch" strategy to speed up the startup of stages variables: - JOB_DIR: "/gpfs/f5/gfdl_o/scratch/oar.gfdl.ogrp-account/runner/builds/$CI_PIPELINE_ID" + JOB_DIR: "/gpfs/f5/gfdl_o/scratch/oar.gfdl.mom6-account/runner/builds/$CI_PIPELINE_ID" GIT_STRATEGY: fetch # Always eport value of $JOB_DIR @@ -20,7 +20,7 @@ before_script: p:merge: stage: setup tags: - - ncrc5 + - mom6-ci-c5 script: - git pull --no-edit https://github.com/NOAA-GFDL/MOM6.git dev/gfdl @@ -30,7 +30,7 @@ p:merge: p:clone: stage: setup tags: - - ncrc5 + - mom6-ci-c5 script: # NOTE: We could sweep any builds older than 3 days here if needed #- find $HOME/ci/[0-9]* -mtime +3 -delete 2> /dev/null || true @@ -45,7 +45,7 @@ p:clone: s:work-space:pgi: stage: setup tags: - - ncrc5 + - mom6-ci-c5 needs: ["p:clone"] script: - .gitlab/pipeline-ci-tool.sh copy-test-space pgi @@ -53,7 +53,7 @@ s:work-space:pgi: s:work-space:intel: stage: setup tags: - - ncrc5 + - mom6-ci-c5 needs: ["p:clone"] script: - .gitlab/pipeline-ci-tool.sh copy-test-space intel @@ -61,7 +61,7 @@ s:work-space:intel: s:work-space:gnu: stage: setup tags: - - ncrc5 + - mom6-ci-c5 needs: ["p:clone"] script: - .gitlab/pipeline-ci-tool.sh copy-test-space gnu @@ -69,7 +69,7 @@ s:work-space:gnu: s:work-space:gnu-restarts: stage: setup tags: - - ncrc5 + - mom6-ci-c5 needs: ["p:clone"] script: - .gitlab/pipeline-ci-tool.sh copy-test-space gnu-rst @@ -83,7 +83,7 @@ compile:pgi:repro: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh mrs-compile repro_pgi @@ -91,7 +91,7 @@ compile:intel:repro: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh mrs-compile repro_intel @@ -99,7 +99,7 @@ compile:gnu:repro: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh mrs-compile repro_gnu mrs-compile static_gnu @@ -107,7 +107,7 @@ compile:gnu:debug: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh mrs-compile debug_gnu @@ -115,7 +115,7 @@ compile:gnu:ocean-only-nolibs: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh nolibs-ocean-only-compile gnu @@ -123,7 +123,7 @@ compile:gnu:ice-ocean-nolibs: stage: builds needs: ["p:clone"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh nolibs-ocean-ice-compile gnu @@ -133,36 +133,36 @@ run:pgi: stage: run needs: ["s:work-space:pgi","compile:pgi:repro"] tags: - - ncrc5 + - mom6-ci-c5 script: - - sbatch --clusters=c5 --nodes=12 --time=15:00 --account=gfdl_o --qos=debug --job-name=mom6_pgi_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite pgi SNL && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) + - sbatch --clusters=c5 --nodes=12 --time=${MOM6_RUN_JOB_DURATION:=15:00} --account=gfdl_o --qos=debug --job-name=mom6_pgi_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite pgi SNL && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) - test -f $JOB_DIR/CI-BATCH-SUCCESS-pgi-SNL || ( echo Batch job did not complete ; exit 911 ) run:intel: stage: run needs: ["s:work-space:intel","compile:intel:repro"] tags: - - ncrc5 + - mom6-ci-c5 script: - - sbatch --clusters=c5 --nodes=12 --time=15:00 --account=gfdl_o --qos=debug --job-name=mom6_intel_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite intel SNL && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) + - sbatch --clusters=c5 --nodes=12 --time=${MOM6_RUN_JOB_DURATION:=15:00} --account=gfdl_o --qos=debug --job-name=mom6_intel_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite intel SNL && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) - test -f $JOB_DIR/CI-BATCH-SUCCESS-intel-SNL || ( echo Batch job did not complete ; exit 911 ) run:gnu: stage: run needs: ["s:work-space:gnu","compile:gnu:repro","compile:gnu:debug"] tags: - - ncrc5 + - mom6-ci-c5 script: - - sbatch --clusters=c5 --nodes=12 --time=15:00 --account=gfdl_o --qos=debug --job-name=mom6_gnu_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite gnu SNLDT && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) + - sbatch --clusters=c5 --nodes=12 --time=${MOM6_RUN_JOB_DURATION:=15:00} --account=gfdl_o --qos=debug --job-name=mom6_gnu_tests --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite gnu SNLDT && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) - test -f $JOB_DIR/CI-BATCH-SUCCESS-gnu-SNLDT || ( echo Batch job did not complete ; exit 911 ) run:gnu-restarts: stage: run needs: ["s:work-space:gnu-restarts","compile:gnu:repro"] tags: - - ncrc5 + - mom6-ci-c5 script: - - sbatch --clusters=c5 --nodes=12 --time=15:00 --account=gfdl_o --qos=debug --job-name=mom6_gnu_restarts --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite gnu R && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) + - sbatch --clusters=c5 --nodes=12 --time=${MOM6_RUN_JOB_DURATION:=15:00} --account=gfdl_o --qos=debug --job-name=mom6_gnu_restarts --output=log.$CI_JOB_ID --wait .gitlab/pipeline-ci-tool.sh run-suite gnu R && ( egrep -v 'pagefaults|HiWaterMark=' log.$CI_JOB_ID ; echo Job returned normally ) || ( cat log.$CI_JOB_ID ; echo Job failed ; exit 911 ) - test -f $JOB_DIR/CI-BATCH-SUCCESS-gnu-R || ( echo Batch job did not complete ; exit 911 ) # GH/autoconf tests (duplicates the GH actions tests) @@ -174,7 +174,7 @@ actions:gnu: stage: tests needs: [] tags: - - ncrc5 + - mom6-ci-c5 before_script: - echo -e "\e[0Ksection_start:`date +%s`:submodules[collapsed=true]\r\e[0KCloning submodules" - git submodule init ; git submodule update @@ -182,9 +182,9 @@ actions:gnu: script: - echo -e "\e[0Ksection_start:`date +%s`:compile[collapsed=true]\r\e[0KCompiling executables" - cd .testing - - module unload PrgEnv-gnu PrgEnv-intel PrgEnv-nvhpc ; module load PrgEnv-gnu ; module unload gcc ; module load gcc/12.2.0 cray-hdf5 cray-netcdf - - make -s -j - - MPIRUN= make preproc -s -j + - module unload darshan-runtime intel PrgEnv-intel ; module load PrgEnv-gnu/8.5.0 cray-hdf5 cray-netcdf ; module switch gcc-native/12.3 + - FC=ftn MPIFC=ftn CC=cc make -s -j + - MPIRUN= FC=ftn MPIFC=ftn CC=cc make preproc -s -j - echo -e "\e[0Ksection_end:`date +%s`:compile\r\e[0K" - (echo '#!/bin/bash';echo 'make MPIRUN="srun -mblock --exclusive" test -s -j') > job.sh - sbatch --clusters=c5 --nodes=2 --time=0:10:00 --account=gfdl_o --qos=debug --job-name=MOM6.gnu.testing --output=log.$CI_JOB_ID --wait job.sh || ( cat log.$CI_JOB_ID ; exit 911 ) && make test -s @@ -194,7 +194,7 @@ actions:intel: stage: tests needs: [] tags: - - ncrc5 + - mom6-ci-c5 before_script: - echo -e "\e[0Ksection_start:`date +%s`:submodules[collapsed=true]\r\e[0KCloning submodules" - git submodule init ; git submodule update @@ -202,9 +202,9 @@ actions:intel: script: - echo -e "\e[0Ksection_start:`date +%s`:compile[collapsed=true]\r\e[0KCompiling executables" - cd .testing - - module unload PrgEnv-pgi PrgEnv-intel PrgEnv-gnu ; module load PrgEnv-intel; module unload intel; module load intel-classic/2022.0.2 cray-hdf5 cray-netcdf - - make -s -j - - MPIRUN= make preproc -s -j + - module unload darshan-runtime ; module unload intel cray-libsci cray-mpich PrgEnv-intel ; module load PrgEnv-intel intel/2023.2.0 cray-hdf5 cray-netcdf cray-mpich + - FC=ftn MPIFC=ftn CC=cc make -s -j + - MPIRUN= FC=ftn MPIFC=ftn CC=cc make preproc -s -j - echo -e "\e[0Ksection_end:`date +%s`:compile\r\e[0K" - (echo '#!/bin/bash';echo 'make MPIRUN="srun -mblock --exclusive" test -s -j') > job.sh - sbatch --clusters=c5 --nodes=2 --time=0:10:00 --account=gfdl_o --qos=debug --job-name=MOM6.intel.testing --output=log.$CI_JOB_ID --wait job.sh || ( cat log.$CI_JOB_ID ; exit 911 ) && make test -s @@ -219,7 +219,7 @@ t:pgi:symmetric: stage: tests needs: ["run:pgi"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats pgi S @@ -227,7 +227,7 @@ t:pgi:non-symmetric: stage: tests needs: ["run:pgi"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats pgi N @@ -235,7 +235,7 @@ t:pgi:layout: stage: tests needs: ["run:pgi"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats pgi L @@ -243,7 +243,7 @@ t:pgi:params: stage: tests needs: ["run:pgi"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-params pgi allow_failure: true @@ -252,7 +252,7 @@ t:intel:symmetric: stage: tests needs: ["run:intel"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats intel S @@ -260,7 +260,7 @@ t:intel:non-symmetric: stage: tests needs: ["run:intel"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats intel N @@ -268,7 +268,7 @@ t:intel:layout: stage: tests needs: ["run:intel"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats intel L @@ -276,7 +276,7 @@ t:intel:params: stage: tests needs: ["run:intel"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-params intel allow_failure: true @@ -285,7 +285,7 @@ t:gnu:symmetric: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu S @@ -293,7 +293,7 @@ t:gnu:non-symmetric: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu N @@ -301,7 +301,7 @@ t:gnu:layout: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu L @@ -309,7 +309,7 @@ t:gnu:static: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu T @@ -317,7 +317,7 @@ t:gnu:symmetric-debug: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu D @@ -325,7 +325,7 @@ t:gnu:restart: stage: tests needs: ["run:gnu-restarts"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-stats gnu R @@ -333,7 +333,7 @@ t:gnu:params: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-params gnu allow_failure: true @@ -342,7 +342,7 @@ t:gnu:diags: stage: tests needs: ["run:gnu"] tags: - - ncrc5 + - mom6-ci-c5 script: - .gitlab/pipeline-ci-tool.sh check-diags gnu allow_failure: true @@ -351,7 +351,7 @@ t:gnu:diags: cleanup: stage: cleanup tags: - - ncrc5 + - mom6-ci-c5 before_script: - echo Skipping usual preamble script: diff --git a/.testing/Makefile b/.testing/Makefile index adc1a20a1e..18687a1616 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -282,7 +282,7 @@ $(BUILD)/%/MOM6: $(BUILD)/%/Makefile FORCE # Target codebase should use its own build system $(BUILD)/target/MOM6: $(BUILD)/target FORCE | $(TARGET_CODEBASE) - $(MAKE) -C $(TARGET_CODEBASE)/.testing build/symmetric/MOM6 + $(MAKE) -C $(TARGET_CODEBASE)/.testing BUILD=build build/symmetric/MOM6 $(BUILD)/target: | $(TARGET_CODEBASE) ln -s $(abspath $(TARGET_CODEBASE))/.testing/build/symmetric $@ diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 2eac007967..638ffada32 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -2710,7 +2710,7 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, & CS%tv%T => CS%T ; CS%tv%S => CS%S if (CS%tv%T_is_conT) then vd_T = var_desc(name="contemp", units="Celsius", longname="Conservative Temperature", & - cmor_field_name="thetao", cmor_longname="Sea Water Potential Temperature", & + cmor_field_name="bigthetao", cmor_longname="Sea Water Conservative Temperature", & conversion=US%Q_to_J_kg*CS%tv%C_p) else vd_T = var_desc(name="temp", units="degC", longname="Potential Temperature", & @@ -2719,7 +2719,7 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, & endif if (CS%tv%S_is_absS) then vd_S = var_desc(name="abssalt", units="g kg-1", longname="Absolute Salinity", & - cmor_field_name="so", cmor_longname="Sea Water Salinity", & + cmor_field_name="absso", cmor_longname="Sea Water Absolute Salinity", & conversion=0.001*US%S_to_ppt) else vd_S = var_desc(name="salt", units="psu", longname="Salinity", & @@ -2803,10 +2803,10 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, & CS%time_in_cycle = 0.0 ; CS%time_in_thermo_cycle = 0.0 !allocate porous topography variables - allocate(CS%pbv%por_face_areaU(IsdB:IedB,jsd:jed,nz)) ; CS%pbv%por_face_areaU(:,:,:) = 1.0 - allocate(CS%pbv%por_face_areaV(isd:ied,JsdB:JedB,nz)) ; CS%pbv%por_face_areaV(:,:,:) = 1.0 - allocate(CS%pbv%por_layer_widthU(IsdB:IedB,jsd:jed,nz+1)) ; CS%pbv%por_layer_widthU(:,:,:) = 1.0 - allocate(CS%pbv%por_layer_widthV(isd:ied,JsdB:JedB,nz+1)) ; CS%pbv%por_layer_widthV(:,:,:) = 1.0 + allocate(CS%pbv%por_face_areaU(IsdB:IedB,jsd:jed,nz), source=1.0) + allocate(CS%pbv%por_face_areaV(isd:ied,JsdB:JedB,nz), source=1.0) + allocate(CS%pbv%por_layer_widthU(IsdB:IedB,jsd:jed,nz+1), source=1.0) + allocate(CS%pbv%por_layer_widthV(isd:ied,JsdB:JedB,nz+1), source=1.0) ! Use the Wright equation of state by default, unless otherwise specified ! Note: this line and the following block ought to be in a separate diff --git a/src/core/MOM_porous_barriers.F90 b/src/core/MOM_porous_barriers.F90 index 8f872ceb15..e24d4954cb 100644 --- a/src/core/MOM_porous_barriers.F90 +++ b/src/core/MOM_porous_barriers.F90 @@ -122,16 +122,20 @@ subroutine porous_widths_layer(h, tv, G, GV, US, pbv, CS, eta_bt) A_layer_prev(I,j) = A_layer endif ; enddo ; enddo ; enddo else - do k=nk,1,-1 ; do j=js,je ; do I=Isq,Ieq ; if (do_I(I,j)) then - call calc_por_layer(G%porous_DminU(I,j), G%porous_DmaxU(I,j), G%porous_DavgU(I,j), & - eta_u(I,j,K), A_layer, do_I(I,j)) - if (eta_u(I,j,K) - (eta_u(I,j,K+1)+dz_min) > 0.0) then - pbv%por_face_areaU(I,j,k) = min(1.0, (A_layer - A_layer_prev(I,j)) / (eta_u(I,j,K) - eta_u(I,j,K+1))) + do k=nk,1,-1 ; do j=js,je ; do I=Isq,Ieq + if (do_I(I,j)) then + call calc_por_layer(G%porous_DminU(I,j), G%porous_DmaxU(I,j), G%porous_DavgU(I,j), & + eta_u(I,j,K), A_layer, do_I(I,j)) + if (eta_u(I,j,K) - (eta_u(I,j,K+1)+dz_min) > 0.0) then + pbv%por_face_areaU(I,j,k) = min(1.0, (A_layer - A_layer_prev(I,j)) / (eta_u(I,j,K) - eta_u(I,j,K+1))) + else + pbv%por_face_areaU(I,j,k) = 0.0 ! use calc_por_interface() might be a better choice + endif + A_layer_prev(I,j) = A_layer else - pbv%por_face_areaU(I,j,k) = 0.0 ! use calc_por_interface() might be a better choice + pbv%por_face_areaU(I,j,k) = 1.0 endif - A_layer_prev(I,j) = A_layer - endif ; enddo ; enddo ; enddo + enddo ; enddo ; enddo endif ! v-points @@ -154,16 +158,20 @@ subroutine porous_widths_layer(h, tv, G, GV, US, pbv, CS, eta_bt) A_layer_prev(i,J) = A_layer endif ; enddo ; enddo ; enddo else - do k=nk,1,-1 ; do J=Jsq,Jeq ; do i=is,ie ; if (do_I(i,J)) then - call calc_por_layer(G%porous_DminV(i,J), G%porous_DmaxV(i,J), G%porous_DavgV(i,J), & - eta_v(i,J,K), A_layer, do_I(i,J)) - if (eta_v(i,J,K) - (eta_v(i,J,K+1)+dz_min) > 0.0) then - pbv%por_face_areaV(i,J,k) = min(1.0, (A_layer - A_layer_prev(i,J)) / (eta_v(i,J,K) - eta_v(i,J,K+1))) + do k=nk,1,-1 ; do J=Jsq,Jeq ; do i=is,ie + if (do_I(i,J)) then + call calc_por_layer(G%porous_DminV(i,J), G%porous_DmaxV(i,J), G%porous_DavgV(i,J), & + eta_v(i,J,K), A_layer, do_I(i,J)) + if (eta_v(i,J,K) - (eta_v(i,J,K+1)+dz_min) > 0.0) then + pbv%por_face_areaV(i,J,k) = min(1.0, (A_layer - A_layer_prev(i,J)) / (eta_v(i,J,K) - eta_v(i,J,K+1))) + else + pbv%por_face_areaV(i,J,k) = 0.0 ! use calc_por_interface() might be a better choice + endif + A_layer_prev(i,J) = A_layer else - pbv%por_face_areaV(i,J,k) = 0.0 ! use calc_por_interface() might be a better choice + pbv%por_face_areaV(i,J,k) = 1.0 endif - A_layer_prev(i,J) = A_layer - endif ; enddo ; enddo ; enddo + enddo ; enddo ; enddo endif if (CS%debug) then @@ -231,10 +239,14 @@ subroutine porous_widths_interface(h, tv, G, GV, US, pbv, CS, eta_bt) eta_u(I,j,K), pbv%por_layer_widthU(I,j,K), do_I(I,j)) endif ; enddo ; enddo ; enddo else - do K=1,nk+1 ; do j=js,je ; do I=Isq,Ieq ; if (do_I(I,j)) then - call calc_por_interface(G%porous_DminU(I,j), G%porous_DmaxU(I,j), G%porous_DavgU(I,j), & - eta_u(I,j,K), pbv%por_layer_widthU(I,j,K), do_I(I,j)) - endif ; enddo ; enddo ; enddo + do K=1,nk+1 ; do j=js,je ; do I=Isq,Ieq + if (do_I(I,j)) then + call calc_por_interface(G%porous_DminU(I,j), G%porous_DmaxU(I,j), G%porous_DavgU(I,j), & + eta_u(I,j,K), pbv%por_layer_widthU(I,j,K), do_I(I,j)) + else + pbv%por_layer_widthU(I,j,K) = 1.0 + endif + enddo ; enddo ; enddo endif ! v-points @@ -249,10 +261,14 @@ subroutine porous_widths_interface(h, tv, G, GV, US, pbv, CS, eta_bt) eta_v(i,J,K), pbv%por_layer_widthV(i,J,K), do_I(i,J)) endif ; enddo ; enddo ; enddo else - do K=1,nk+1 ; do J=Jsq,Jeq ; do i=is,ie ; if (do_I(i,J)) then - call calc_por_interface(G%porous_DminV(i,J), G%porous_DmaxV(i,J), G%porous_DavgV(i,J), & - eta_v(i,J,K), pbv%por_layer_widthV(i,J,K), do_I(i,J)) - endif ; enddo ; enddo ; enddo + do K=1,nk+1 ; do J=Jsq,Jeq ; do i=is,ie + if (do_I(i,J)) then + call calc_por_interface(G%porous_DminV(i,J), G%porous_DmaxV(i,J), G%porous_DavgV(i,J), & + eta_v(i,J,K), pbv%por_layer_widthV(i,J,K), do_I(i,J)) + else + pbv%por_layer_widthV(i,J,K) = 1.0 + endif + enddo ; enddo ; enddo endif if (CS%debug) then diff --git a/src/core/MOM_variables.F90 b/src/core/MOM_variables.F90 index 5b7740230a..65e915705a 100644 --- a/src/core/MOM_variables.F90 +++ b/src/core/MOM_variables.F90 @@ -323,7 +323,6 @@ module MOM_variables end type BT_cont_type !> Container for grids modifying cell metric at porous barriers -! TODO: rename porous_barrier_type to porous_barrier_type type, public :: porous_barrier_type ! Each of the following fields has nz layers. real, allocatable :: por_face_areaU(:,:,:) !< fractional open area of U-faces [nondim] diff --git a/src/ice_shelf/MOM_ice_shelf.F90 b/src/ice_shelf/MOM_ice_shelf.F90 index 52b1ebdcea..bac5b0fce9 100644 --- a/src/ice_shelf/MOM_ice_shelf.F90 +++ b/src/ice_shelf/MOM_ice_shelf.F90 @@ -450,11 +450,11 @@ subroutine shelf_calc_flux(sfc_state_in, fluxes_in, Time, time_step_in, CS) I_au = 0.0 ; if (asu1 + asu2 > 0.0) I_au = 1.0 / (asu1 + asu2) I_av = 0.0 ; if (asv1 + asv2 > 0.0) I_av = 1.0 / (asv1 + asv2) if (allocated(sfc_state%taux_shelf) .and. allocated(sfc_state%tauy_shelf)) then - taux2 = (asu1 * sfc_state%taux_shelf(I-1,j)**2 + asu2 * sfc_state%taux_shelf(I,j)**2 ) * I_au - tauy2 = (asv1 * sfc_state%tauy_shelf(i,J-1)**2 + asv2 * sfc_state%tauy_shelf(i,J)**2 ) * I_av + taux2 = (((asu1 * (sfc_state%taux_shelf(I-1,j)**2)) + (asu2 * (sfc_state%taux_shelf(I,j)**2)) ) * I_au) + tauy2 = (((asv1 * (sfc_state%tauy_shelf(i,J-1)**2)) + (asv2 * (sfc_state%tauy_shelf(i,J)**2)) ) * I_av) endif - u2_av = (asu1 * sfc_state%u(I-1,j)**2 + asu2 * sfc_state%u(I,j)**2) * I_au - v2_av = (asv1 * sfc_state%v(i,J-1)**2 + asu2 * sfc_state%v(i,J)**2) * I_av + u2_av = (((asu1 * (sfc_state%u(I-1,j)**2)) + (asu2 * sfc_state%u(I,j)**2)) * I_au) + v2_av = (((asv1 * (sfc_state%v(i,J-1)**2)) + (asu2 * sfc_state%v(i,J)**2)) * I_av) if ((taux2 + tauy2 > 0.0) .and. .not.CS%ustar_shelf_from_vel) then if (CS%ustar_max >= 0.0) then @@ -824,7 +824,7 @@ subroutine shelf_calc_flux(sfc_state_in, fluxes_in, Time, time_step_in, CS) ISS%dhdt_shelf(i,j) = (ISS%h_shelf(i,j) - ISS%dhdt_shelf(i,j))*Itime_step enddo; enddo - call IS_dynamics_post_data(time_step, Time, CS%dCS, G) + call IS_dynamics_post_data(time_step, Time, CS%dCS, ISS, G) endif if (CS%shelf_mass_is_dynamic) & @@ -2603,7 +2603,7 @@ subroutine solo_step_ice_shelf(CS, time_interval, nsteps, Time, min_time_step_in call process_and_post_scalar_data(CS, vaf0, vaf0_A, vaf0_G, Ifull_time_step, dh_adott, dh_adott*0.0) call disable_averaging(CS%diag) - call IS_dynamics_post_data(full_time_step, Time, CS%dCS, G) + call IS_dynamics_post_data(full_time_step, Time, CS%dCS, ISS, G) end subroutine solo_step_ice_shelf !> Post_data calls for ice-sheet scalars @@ -2648,7 +2648,9 @@ subroutine process_and_post_scalar_data(CS, vaf0, vaf0_A, vaf0_G, Itime_step, dh endif if (CS%id_f_adott > 0 .or. CS%id_f_adot > 0) then !floating only: surface accumulation - surface melt call masked_var_grounded(G,CS%dCS,dh_adott,tmp) - tmp(:,:) = dh_adott(:,:) - tmp(:,:) + do j=js,je ; do i=is,ie + tmp(i,j) = dh_adott(i,j) - tmp(i,j) + enddo; enddo call integrate_over_ice_sheet_area(G, ISS, tmp, US%Z_to_m, val) if (CS%id_f_adott > 0) call post_scalar_data(CS%id_f_adott,val ,CS%diag) if (CS%id_f_adot > 0) call post_scalar_data(CS%id_f_adot ,val*Itime_step,CS%diag) @@ -2710,7 +2712,9 @@ subroutine process_and_post_scalar_data(CS, vaf0, vaf0_A, vaf0_G, Itime_step, dh endif if (CS%id_Ant_f_adott > 0 .or. CS%id_Ant_f_adot > 0) then !floating only: surface accumulation - surface melt call masked_var_grounded(G,CS%dCS,dh_adott,tmp) - tmp(:,:) = dh_adott(:,:) - tmp(:,:) + do j=js,je ; do i=is,ie + tmp(i,j) = dh_adott(i,j) - tmp(i,j) + enddo; enddo call integrate_over_ice_sheet_area(G, ISS, tmp, US%Z_to_m, val, hemisphere=0) if (CS%id_Ant_f_adott > 0) call post_scalar_data(CS%id_Ant_f_adott,val ,CS%diag) if (CS%id_Ant_f_adot > 0) call post_scalar_data(CS%id_Ant_f_adot ,val*Itime_step,CS%diag) @@ -2772,7 +2776,9 @@ subroutine process_and_post_scalar_data(CS, vaf0, vaf0_A, vaf0_G, Itime_step, dh endif if (CS%id_Gr_f_adott > 0 .or. CS%id_Gr_f_adot > 0) then !floating only: surface accumulation - surface melt call masked_var_grounded(G,CS%dCS,dh_adott,tmp) - tmp(:,:) = dh_adott(:,:) - tmp(:,:) + do j=js,je ; do i=is,ie + tmp(i,j) = dh_adott(i,j) - tmp(i,j) + enddo; enddo call integrate_over_ice_sheet_area(G, ISS, tmp, US%Z_to_m, val, hemisphere=1) if (CS%id_Gr_f_adott > 0) call post_scalar_data(CS%id_Gr_f_adott,val ,CS%diag) if (CS%id_Gr_f_adot > 0) call post_scalar_data(CS%id_Gr_f_adot ,val*Itime_step,CS%diag) diff --git a/src/ice_shelf/MOM_ice_shelf_dynamics.F90 b/src/ice_shelf/MOM_ice_shelf_dynamics.F90 index 3ed262e5f3..9c7dda22de 100644 --- a/src/ice_shelf/MOM_ice_shelf_dynamics.F90 +++ b/src/ice_shelf/MOM_ice_shelf_dynamics.F90 @@ -89,9 +89,9 @@ module MOM_ice_shelf_dynamics real, pointer, dimension(:,:) :: t_shelf => NULL() !< Vertically integrated temperature in the ice shelf/stream, !! on corner-points (B grid) [C ~> degC] real, pointer, dimension(:,:) :: tmask => NULL() !< A mask on tracer points that is 1 where there is ice. - real, pointer, dimension(:,:,:) :: ice_visc => NULL() !< Glen's law ice viscosity (Pa s), - !! in [R L2 T-1 ~> kg m-1 s-1]. - !! at either 1 (cell-centered) or 4 quadrature points per cell + real, pointer, dimension(:,:,:) :: ice_visc => NULL() !< Area and depth-integrated Glen's law ice viscosity + !! (Pa m3 s) in [R L4 Z T-1 ~> kg m2 s-1]. + !! at either 1 (cell-centered) or 4 quadrature points per cell real, pointer, dimension(:,:) :: AGlen_visc => NULL() !< Ice-stiffness parameter in Glen's law ice viscosity, !! often in [Pa-3 s-1] if n_Glen is 3. real, pointer, dimension(:,:) :: u_bdry_val => NULL() !< The zonal ice velocity at inflowing boundaries @@ -227,11 +227,17 @@ module MOM_ice_shelf_dynamics logical :: module_is_initialized = .false. !< True if this module has been initialized. !>@{ Diagnostic handles - integer :: id_u_shelf = -1, id_v_shelf = -1, id_t_shelf = -1, & - id_taudx_shelf = -1, id_taudy_shelf = -1, id_bed_elev = -1, & + integer :: id_u_shelf = -1, id_v_shelf = -1, id_shelf_speed, id_t_shelf = -1, & + id_taudx_shelf = -1, id_taudy_shelf = -1, id_taud_shelf = -1, id_bed_elev = -1, & id_ground_frac = -1, id_col_thick = -1, id_OD_av = -1, id_float_cond = -1, & id_u_mask = -1, id_v_mask = -1, id_ufb_mask =-1, id_vfb_mask = -1, id_t_mask = -1, & - id_sx_shelf = -1, id_sy_shelf = -1 + id_sx_shelf = -1, id_sy_shelf = -1, id_surf_slope_mag_shelf, & + id_duHdx = -1, id_dvHdy = -1, id_fluxdiv = -1, & + id_strainrate_xx = -1, id_strainrate_yy = -1, id_strainrate_xy = -1, & + id_pstrainrate_1 = -1, id_pstrainrate_2, & + id_devstress_xx = -1, id_devstress_yy = -1, id_devstress_xy = -1, & + id_pdevstress_1 = -1, id_pdevstress_2 = -1 + !>@} ! ids for outputting intermediate thickness in advection subroutine (debugging) !>@{ Diagnostic handles for debugging @@ -282,9 +288,9 @@ function quad_area (X, Y) ! | | ! 1 - 2 - p2 = (X(4)-X(1))**2 + (Y(4)-Y(1))**2 ; q2 = (X(3)-X(2))**2 + (Y(3)-Y(2))**2 - a2 = (X(3)-X(4))**2 + (Y(3)-Y(4))**2 ; c2 = (X(1)-X(2))**2 + (Y(1)-Y(2))**2 - b2 = (X(2)-X(4))**2 + (Y(2)-Y(4))**2 ; d2 = (X(3)-X(1))**2 + (Y(3)-Y(1))**2 + p2 = ( ((X(4)-X(1))**2) + ((Y(4)-Y(1))**2) ) ; q2 = ( ((X(3)-X(2))**2) + ((Y(3)-Y(2))**2) ) + a2 = ( ((X(3)-X(4))**2) + ((Y(3)-Y(4))**2) ) ; c2 = ( ((X(1)-X(2))**2) + ((Y(1)-Y(2))**2) ) + b2 = ( ((X(2)-X(4))**2) + ((Y(2)-Y(4))**2) ) ; d2 = ( ((X(3)-X(1))**2) + ((Y(3)-Y(1))**2) ) quad_area = .25 * sqrt(4*P2*Q2-(B2+D2-A2-C2)**2) end function quad_area @@ -552,7 +558,7 @@ subroutine initialize_ice_shelf_dyn(param_file, Time, ISS, CS, G, US, diag, new_ units="m", default=1.e-3, scale=US%m_to_Z) call get_param(param_file, mdl, "NONLIN_SOLVE_ERR_MODE", CS%nonlin_solve_err_mode, & "Choose whether nonlin error in vel solve is based on nonlinear "//& - "residual (1), relative change since last iteration (2), or change in norm (3)", default=1) + "residual (1), relative change since last iteration (2), or change in norm (3)", default=3) call get_param(param_file, mdl, "SHELF_MOVING_FRONT", CS%moving_shelf_front, & "Specify whether to advance shelf front (and calve).", & @@ -805,14 +811,20 @@ subroutine initialize_ice_shelf_dyn(param_file, Time, ISS, CS, G, US, diag, new_ 'x-velocity of ice', 'm yr-1', conversion=365.0*86400.0*US%L_T_to_m_s) CS%id_v_shelf = register_diag_field('ice_shelf_model','v_shelf',CS%diag%axesB1, Time, & 'y-velocity of ice', 'm yr-1', conversion=365.0*86400.0*US%L_T_to_m_s) + CS%id_shelf_speed = register_diag_field('ice_shelf_model','shelf_speed',CS%diag%axesB1, Time, & + 'speed of of ice shelf', 'm yr-1', conversion=365.0*86400.0*US%L_T_to_m_s) CS%id_taudx_shelf = register_diag_field('ice_shelf_model','taudx_shelf',CS%diag%axesB1, Time, & 'x-driving stress of ice', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) CS%id_taudy_shelf = register_diag_field('ice_shelf_model','taudy_shelf',CS%diag%axesB1, Time, & 'y-driving stress of ice', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + CS%id_taud_shelf = register_diag_field('ice_shelf_model','taud_shelf',CS%diag%axesB1, Time, & + 'magnitude of driving stress of ice', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) CS%id_sx_shelf = register_diag_field('ice_shelf_model','sx_shelf',CS%diag%axesB1, Time, & 'x-surface slope of ice', 'none') CS%id_sy_shelf = register_diag_field('ice_shelf_model','sy_shelf',CS%diag%axesB1, Time, & 'y-surface slope of ice', 'none') + CS%id_surf_slope_mag_shelf = register_diag_field('ice_shelf_model','surf_slope_mag_shelf', CS%diag%axesB1, Time, & + 'magnitude of surface slope of ice', 'none') CS%id_u_mask = register_diag_field('ice_shelf_model','u_mask',CS%diag%axesB1, Time, & 'mask for u-nodes', 'none') CS%id_v_mask = register_diag_field('ice_shelf_model','v_mask',CS%diag%axesB1, Time, & @@ -830,6 +842,33 @@ subroutine initialize_ice_shelf_dyn(param_file, Time, ISS, CS, G, US, diag, new_ CS%id_OD_av = register_diag_field('ice_shelf_model','OD_av',CS%diag%axesT1, Time, & 'intermediate ocean column thickness passed to ice model', 'm', conversion=US%Z_to_m) + CS%id_duHdx = register_diag_field('ice_shelf_model','duHdx',CS%diag%axesT1, Time, & + 'x-component of ice-sheet flux divergence', 'm yr-1', conversion=365.0*86400.0*US%Z_to_m*US%s_to_T) + CS%id_dvHdy = register_diag_field('ice_shelf_model','dvHdy',CS%diag%axesT1, Time, & + 'y-component of ice-sheet flux divergence', 'm yr-1', conversion=365.0*86400.0*US%Z_to_m*US%s_to_T) + CS%id_fluxdiv = register_diag_field('ice_shelf_model','fluxdiv',CS%diag%axesT1, Time, & + 'ice-sheet flux divergence', 'm yr-1', conversion=365.0*86400.0*US%Z_to_m*US%s_to_T) + CS%id_strainrate_xx = register_diag_field('ice_shelf_model','strainrate_xx',CS%diag%axesT1, Time, & + 'x-component of ice-shelf strain-rate', 'yr-1', conversion=365.0*86400.0*US%s_to_T) + CS%id_strainrate_yy = register_diag_field('ice_shelf_model','strainrate_yy',CS%diag%axesT1, Time, & + 'y-component of ice-shelf strain-rate', 'yr-1', conversion=365.0*86400.0*US%s_to_T) + CS%id_strainrate_xy = register_diag_field('ice_shelf_model','strainrate_xy',CS%diag%axesT1, Time, & + 'xy-component of ice-shelf strain-rate', 'yr-1', conversion=365.0*86400.0*US%s_to_T) + CS%id_pstrainrate_1 = register_diag_field('ice_shelf_model','pstrainrate_1',CS%diag%axesT1, Time, & + 'max principal horizontal ice-shelf strain-rate', 'yr-1', conversion=365.0*86400.0*US%s_to_T) + CS%id_pstrainrate_2 = register_diag_field('ice_shelf_model','pstrainrate_2',CS%diag%axesT1, Time, & + 'min principal horizontal ice-shelf strain-rate', 'yr-1', conversion=365.0*86400.0*US%s_to_T) + CS%id_devstress_xx = register_diag_field('ice_shelf_model','devstress_xx',CS%diag%axesT1, Time, & + 'x-component of ice-shelf deviatoric stress', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + CS%id_devstress_yy = register_diag_field('ice_shelf_model','devstress_yy',CS%diag%axesT1, Time, & + 'y-component of ice-shelf deviatoric stress', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + CS%id_devstress_xy = register_diag_field('ice_shelf_model','devstress_xy',CS%diag%axesT1, Time, & + 'xy-component of ice-shelf deviatoric stress', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + CS%id_pdevstress_1 = register_diag_field('ice_shelf_model','pdevstress_1',CS%diag%axesT1, Time, & + 'max principal horizontal ice-shelf deviatoric stress', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + CS%id_pdevstress_2 = register_diag_field('ice_shelf_model','pdevstress_2',CS%diag%axesT1, Time, & + 'min principal ice-shelf deviatoric stress', 'kPa', conversion=1.e-3*US%RLZ_T2_to_Pa) + !Update these variables so that they are nonzero in case !IS_dynamics_post_data is called before update_ice_shelf if (CS%id_taudx_shelf>0 .or. CS%id_taudy_shelf>0) & @@ -898,10 +937,10 @@ function ice_time_step_CFL(CS, ISS, G) min_vel = (1.0e-12/(365.0*86400.0)) * G%US%m_s_to_L_T do j=G%jsc,G%jec ; do i=G%isc,G%iec ; if (ISS%hmask(i,j) == 1.0 .or. ISS%hmask(i,j)==3) then dt_local = 2.0*G%areaT(i,j) / & - ((G%dyCu(I,j) * max(abs(CS%u_shelf(I,J) + CS%u_shelf(I,j-1)), min_vel) + & - G%dyCu(I-1,j)* max(abs(CS%u_shelf(I-1,J)+ CS%u_shelf(I-1,j-1)), min_vel)) + & - (G%dxCv(i,J) * max(abs(CS%v_shelf(i,J) + CS%v_shelf(i-1,J)), min_vel) + & - G%dxCv(i,J-1)* max(abs(CS%v_shelf(i,J-1)+ CS%v_shelf(i-1,J-1)), min_vel))) + (((G%dyCu(I,j) * max(abs(CS%u_shelf(I,J) + CS%u_shelf(I,j-1)), min_vel)) + & + (G%dyCu(I-1,j)* max(abs(CS%u_shelf(I-1,J)+ CS%u_shelf(I-1,j-1)), min_vel))) + & + ((G%dxCv(i,J) * max(abs(CS%v_shelf(i,J) + CS%v_shelf(i-1,J)), min_vel)) + & + (G%dxCv(i,J-1)* max(abs(CS%v_shelf(i,J-1)+ CS%v_shelf(i-1,J-1)), min_vel)))) min_dt = min(min_dt, dt_local) endif ; enddo ; enddo ! i- and j- loops @@ -1035,45 +1074,70 @@ subroutine masked_var_grounded(G,CS,var,varout) end subroutine masked_var_grounded !> Ice shelf dynamics post_data calls -subroutine IS_dynamics_post_data(time_step, Time, CS, G) +subroutine IS_dynamics_post_data(time_step, Time, CS, ISS, G) real :: time_step !< Length of time for post data averaging [T ~> s]. type(time_type), intent(in) :: Time !< The current model time type(ice_shelf_dyn_CS), intent(inout) :: CS !< The ice shelf dynamics control structure + type(ice_shelf_state), intent(inout) :: ISS !< A structure with elements that describe + !! the ice-shelf state type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. - real, dimension(SZDIB_(G),SZDJB_(G)) :: taud_x, taud_y ! Pa] - real, dimension(SZDI_(G),SZDJ_(G)) :: ice_visc !< area-averaged vertically integrated ice viscosity + real, dimension(SZDIB_(G),SZDJB_(G)) :: taud_x, taud_y, taud ! area-averaged driving stress [R L2 T-2 ~> Pa] + real, dimension(SZDI_(G),SZDJ_(G)) :: ice_visc ! area-averaged vertically integrated ice viscosity !! [R L2 Z T-1 ~> Pa s m] - real, dimension(SZDI_(G),SZDJ_(G)) :: basal_tr !< area-averaged taub_beta field related to basal traction, + real, dimension(SZDI_(G),SZDJ_(G)) :: basal_tr ! area-averaged taub_beta field related to basal traction, !! [R L1 T-1 ~> Pa s m-1] + real, dimension(SZDIB_(G),SZDJB_(G)) :: surf_slope ! the surface slope of the ice shelf/sheet [nondim] + real, dimension(SZDIB_(G),SZDJB_(G)) :: ice_speed ! ice sheet flow speed [L T-1 ~> m s-1] + + integer :: i,j call enable_averages(time_step, Time, CS%diag) if (CS%id_col_thick > 0) call post_data(CS%id_col_thick, CS%OD_av, CS%diag) if (CS%id_u_shelf > 0) call post_data(CS%id_u_shelf, CS%u_shelf, CS%diag) if (CS%id_v_shelf > 0) call post_data(CS%id_v_shelf, CS%v_shelf, CS%diag) + if (CS%id_shelf_speed > 0) then + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + ice_speed(I,J) = sqrt((CS%u_shelf(I,J)**2) + (CS%v_shelf(I,J)**2)) + enddo ; enddo + call post_data(CS%id_shelf_speed, ice_speed, CS%diag) + endif ! if (CS%id_t_shelf > 0) call post_data(CS%id_t_shelf, CS%t_shelf, CS%diag) if (CS%id_taudx_shelf > 0) then - taud_x(:,:) = CS%taudx_shelf(:,:)*G%IareaBu(:,:) + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + taud_x(I,J) = CS%taudx_shelf(I,J)*G%IareaBu(I,J) + enddo ; enddo call post_data(CS%id_taudx_shelf, taud_x, CS%diag) endif if (CS%id_taudy_shelf > 0) then - taud_y(:,:) = CS%taudy_shelf(:,:)*G%IareaBu(:,:) + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + taud_y(I,J) = CS%taudy_shelf(I,J)*G%IareaBu(I,J) + enddo ; enddo call post_data(CS%id_taudy_shelf, taud_y, CS%diag) endif + if (CS%id_taud_shelf > 0) then + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + taud(I,J) = sqrt((CS%taudx_shelf(I,J)**2)+(CS%taudy_shelf(I,J)**2))*G%IareaBu(I,J) + enddo ; enddo + call post_data(CS%id_taud_shelf, taud, CS%diag) + endif if (CS%id_sx_shelf > 0) call post_data(CS%id_sx_shelf, CS%sx_shelf, CS%diag) if (CS%id_sy_shelf > 0) call post_data(CS%id_sy_shelf, CS%sy_shelf, CS%diag) + if (CS%id_surf_slope_mag_shelf > 0) then + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + surf_slope(I,J) = sqrt((CS%sx_shelf(I,J)**2)+(CS%sy_shelf(I,J)**2)) + enddo ; enddo + call post_data(CS%id_surf_slope_mag_shelf, surf_slope, CS%diag) + endif if (CS%id_ground_frac > 0) call post_data(CS%id_ground_frac, CS%ground_frac, CS%diag) if (CS%id_float_cond > 0) call post_data(CS%id_float_cond, CS%float_cond, CS%diag) if (CS%id_OD_av >0) call post_data(CS%id_OD_av, CS%OD_av,CS%diag) if (CS%id_visc_shelf > 0) then - if (CS%visc_qps==4) then - ice_visc(:,:) = (0.25 * G%IareaT(:,:)) * & - ((CS%ice_visc(:,:,1) + CS%ice_visc(:,:,4)) + (CS%ice_visc(:,:,2) + CS%ice_visc(:,:,3))) - else - ice_visc(:,:) = CS%ice_visc(:,:,1)*G%IareaT(:,:) - endif + call ice_visc_diag(CS,G,ice_visc) call post_data(CS%id_visc_shelf, ice_visc, CS%diag) endif if (CS%id_taub > 0) then - basal_tr(:,:) = CS%basal_traction(:,:)*G%IareaT(:,:) + do j=G%jsc,G%jec ; do i=G%isc,G%iec + basal_tr(i,j) = CS%basal_traction(i,j)*G%IareaT(i,j) + enddo ; enddo call post_data(CS%id_taub, basal_tr, CS%diag) endif if (CS%id_u_mask > 0) call post_data(CS%id_u_mask, CS%umask, CS%diag) @@ -1082,9 +1146,38 @@ subroutine IS_dynamics_post_data(time_step, Time, CS, G) if (CS%id_vfb_mask > 0) call post_data(CS%id_vfb_mask, CS%v_face_mask_bdry, CS%diag) ! if (CS%id_t_mask > 0) call post_data(CS%id_t_mask, CS%tmask, CS%diag) + if (CS%id_duHdx > 0 .or. CS%id_dvHdy > 0 .or. CS%id_fluxdiv > 0 .or. & + CS%id_devstress_xx > 0 .or. CS%id_devstress_yy > 0 .or. CS%id_devstress_xy > 0 .or. & + CS%id_strainrate_xx > 0 .or. CS%id_strainrate_yy > 0 .or. CS%id_strainrate_xy > 0 .or. & + CS%id_pdevstress_1 > 0 .or. CS%id_pdevstress_2 > 0 .or. & + CS%id_pstrainrate_1 > 0 .or. CS%id_pstrainrate_2 > 0) then + call IS_dynamics_post_data_2(CS, ISS, G) + endif + call disable_averaging(CS%diag) end subroutine IS_dynamics_post_data +!> Calculate cell-centered, area-averaged, vertically integrated ice viscosity for diagnostics +subroutine ice_visc_diag(CS,G,ice_visc) + type(ice_shelf_dyn_CS), intent(in) :: CS !< The ice shelf dynamics control structure + type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. + real, dimension(SZDI_(G),SZDJ_(G)), intent(out) :: ice_visc !< area-averaged vertically integrated ice viscosity + !! [R L2 Z T-1 ~> Pa s m] + integer :: i,j + + ice_visc(:,:)=0.0 + if (CS%visc_qps==4) then + do j=G%jsc,G%jec ; do i=G%isc,G%iec + ice_visc(i,j) = (0.25 * G%IareaT(i,j)) * & + ((CS%ice_visc(i,j,1) + CS%ice_visc(i,j,4)) + (CS%ice_visc(i,j,2) + CS%ice_visc(i,j,3))) + enddo ; enddo + else + do j=G%jsc,G%jec ; do i=G%isc,G%iec + ice_visc(i,j) = CS%ice_visc(i,j,1)*G%IareaT(i,j) + enddo ; enddo + endif +end subroutine ice_visc_diag + !> Writes the total ice shelf kinetic energy and mass to an ascii file subroutine write_ice_shelf_energy(CS, G, US, mass, area, day, time_step) type(ice_shelf_dyn_CS), intent(inout) :: CS !< The ice shelf dynamics control structure @@ -1154,8 +1247,8 @@ subroutine write_ice_shelf_energy(CS, G, US, mass, area, day, time_step) KE_scale_factor = US%L_to_m**2 * (US%RZ_to_kg_m2 * US%L_T_to_m_s**2) do j=js,je ; do i=is,ie tmp1(i,j) = (KE_scale_factor * 0.03125) * (mass(i,j) * area(i,j)) * & - (((CS%u_shelf(I-1,J-1)+CS%u_shelf(I,J))+(CS%u_shelf(I,J-1)+CS%u_shelf(I-1,J)))**2 + & - ((CS%v_shelf(I-1,J-1)+CS%v_shelf(I,J))+(CS%v_shelf(I,J-1)+CS%v_shelf(I-1,J)))**2) + ((((CS%u_shelf(I-1,J-1)+CS%u_shelf(I,J))+(CS%u_shelf(I,J-1)+CS%u_shelf(I-1,J)))**2) + & + (((CS%v_shelf(I-1,J-1)+CS%v_shelf(I,J))+(CS%v_shelf(I,J-1)+CS%v_shelf(I-1,J)))**2)) enddo; enddo KE_tot = reproducing_sum(tmp1, isr, ier, jsr, jer) @@ -1447,7 +1540,7 @@ subroutine ice_shelf_solve_outer(CS, ISS, G, US, u_shlf, v_shlf, taudx, taudy, i call pass_vector(Au, Av, G%domain, TO_ALL, BGRID_NE) err_init = 0 ; err_tempu = 0 ; err_tempv = 0 - do J=G%IscB,G%JecB ; do I=G%IscB,G%IecB + do J=G%JscB,G%JecB ; do I=G%IscB,G%IecB if (CS%umask(I,J) == 1) then err_tempu = ABS(Au(I,J) - taudx(I,J)) if (err_tempu >= err_init) err_init = err_tempu @@ -1529,7 +1622,7 @@ subroutine ice_shelf_solve_outer(CS, ISS, G, US, u_shlf, v_shlf, taudx, taudy, i err_max = 0 - do J=G%jscB,G%jecB ; do I=G%jscB,G%iecB + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB if (CS%umask(I,J) == 1) then err_tempu = ABS(Au(I,J) - taudx(I,J)) if (err_tempu >= err_max) err_max = err_tempu @@ -1556,7 +1649,7 @@ subroutine ice_shelf_solve_outer(CS, ISS, G, US, u_shlf, v_shlf, taudx, taudy, i if (CS%vmask(I,J) == 1) then err_tempv = MAX(ABS(v_last(I,J)-v_shlf(I,J)), err_tempu) if (err_tempv >= err_max) err_max = err_tempv - tempv = SQRT(v_shlf(I,J)**2 + tempu**2) + tempv = SQRT((v_shlf(I,J)**2) + (tempu**2)) endif if (tempv >= max_vel) max_vel = tempv enddo ; enddo @@ -2540,8 +2633,7 @@ subroutine CG_action(CS, uret, vret, u_shlf, v_shlf, Phi, Phisub, umask, vmask, !! partly or fully covered by an ice-shelf real, dimension(SZDI_(G),SZDJ_(G),CS%visc_qps), & intent(in) :: ice_visc !< A field related to the ice viscosity from Glen's - !! flow law [R L4 Z T-1 ~> kg m2 s-1]. The exact form - !! and units depend on the basal law exponent. + !! flow law [R L4 Z T-1 ~> kg m2 s-1]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: float_cond !< If GL_regularize=true, an array indicating where the ice !! shelf is floating: 0 if floating, 1 if not @@ -2608,53 +2700,53 @@ subroutine CG_action(CS, uret, vret, u_shlf, v_shlf, Phi, Phisub, umask, vmask, qp = 2*(jq-1)+iq !current quad point - uq = (u_shlf(I-1,J-1) * (xquad(3-iq) * xquad(3-jq)) + & - u_shlf(I,J) * (xquad(iq) * xquad(jq))) + & - (u_shlf(I,J-1) * (xquad(iq) * xquad(3-jq)) + & - u_shlf(I-1,J) * (xquad(3-iq) * xquad(jq))) + uq = ((u_shlf(I-1,J-1) * (xquad(3-iq) * xquad(3-jq))) + & + (u_shlf(I,J) * (xquad(iq) * xquad(jq)))) + & + ((u_shlf(I,J-1) * (xquad(iq) * xquad(3-jq))) + & + (u_shlf(I-1,J) * (xquad(3-iq) * xquad(jq)))) - vq = (v_shlf(I-1,J-1) * (xquad(3-iq) * xquad(3-jq)) + & - v_shlf(I,J) * (xquad(iq) * xquad(jq))) + & - (v_shlf(I,J-1) * (xquad(iq) * xquad(3-jq)) + & - v_shlf(I-1,J) * (xquad(3-iq) * xquad(jq))) + vq = ((v_shlf(I-1,J-1) * (xquad(3-iq) * xquad(3-jq))) + & + (v_shlf(I,J) * (xquad(iq) * xquad(jq)))) + & + ((v_shlf(I,J-1) * (xquad(iq) * xquad(3-jq))) + & + (v_shlf(I-1,J) * (xquad(3-iq) * xquad(jq)))) - ux = (u_shlf(I-1,J-1) * Phi(1,qp,i,j) + & - u_shlf(I,J) * Phi(7,qp,i,j)) + & - (u_shlf(I,J-1) * Phi(3,qp,i,j) + & - u_shlf(I-1,J) * Phi(5,qp,i,j)) + ux = ((u_shlf(I-1,J-1) * Phi(1,qp,i,j)) + & + (u_shlf(I,J) * Phi(7,qp,i,j))) + & + ((u_shlf(I,J-1) * Phi(3,qp,i,j)) + & + (u_shlf(I-1,J) * Phi(5,qp,i,j))) - vx = (v_shlf(I-1,J-1) * Phi(1,qp,i,j) + & - v_shlf(I,J) * Phi(7,qp,i,j)) + & - (v_shlf(I,J-1) * Phi(3,qp,i,j) + & - v_shlf(I-1,J) * Phi(5,qp,i,j)) + vx = ((v_shlf(I-1,J-1) * Phi(1,qp,i,j)) + & + (v_shlf(I,J) * Phi(7,qp,i,j))) + & + ((v_shlf(I,J-1) * Phi(3,qp,i,j)) + & + (v_shlf(I-1,J) * Phi(5,qp,i,j))) - uy = (u_shlf(I-1,J-1) * Phi(2,qp,i,j) + & - u_shlf(I,J) * Phi(8,qp,i,j)) + & - (u_shlf(I,J-1) * Phi(4,qp,i,j) + & - u_shlf(I-1,J) * Phi(6,qp,i,j)) + uy = ((u_shlf(I-1,J-1) * Phi(2,qp,i,j)) + & + (u_shlf(I,J) * Phi(8,qp,i,j))) + & + ((u_shlf(I,J-1) * Phi(4,qp,i,j)) + & + (u_shlf(I-1,J) * Phi(6,qp,i,j))) - vy = (v_shlf(I-1,J-1) * Phi(2,qp,i,j) + & - v_shlf(I,J) * Phi(8,qp,i,j)) + & - (v_shlf(I,J-1) * Phi(4,qp,i,j) + & - v_shlf(I-1,J) * Phi(6,qp,i,j)) + vy = ((v_shlf(I-1,J-1) * Phi(2,qp,i,j)) + & + (v_shlf(I,J) * Phi(8,qp,i,j))) + & + ((v_shlf(I,J-1) * Phi(4,qp,i,j)) + & + (v_shlf(I-1,J) * Phi(6,qp,i,j))) if (visc_qp4) qpv = qp !current quad point for viscosity do jphi=1,2 ; Jtgt = J-2+jphi ; do iphi=1,2 ; Itgt = I-2+iphi if (umask(Itgt,Jtgt) == 1) uret_qp(iphi,jphi,qp) = ice_visc(i,j,qpv) * & - ((4*ux+2*vy) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j) + & - (uy+vx) * Phi(2*(2*(jphi-1)+iphi),qp,i,j)) + (((4*ux+2*vy) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j)) + & + ((uy+vx) * Phi(2*(2*(jphi-1)+iphi),qp,i,j))) if (vmask(Itgt,Jtgt) == 1) vret_qp(iphi,jphi,qp) = ice_visc(i,j,qpv) * & - ((uy+vx) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j) + & - (4*vy+2*ux) * Phi(2*(2*(jphi-1)+iphi),qp,i,j)) + (((uy+vx) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j)) + & + ((4*vy+2*ux) * Phi(2*(2*(jphi-1)+iphi),qp,i,j))) if (float_cond(i,j) == 0) then ilq = 1 ; if (iq == iphi) ilq = 2 jlq = 1 ; if (jq == jphi) jlq = 2 if (umask(Itgt,Jtgt) == 1) uret_qp(iphi,jphi,qp) = uret_qp(iphi,jphi,qp) + & - (basal_trac(i,j) * uq) * (xquad(ilq) * xquad(jlq)) + ((basal_trac(i,j) * uq) * (xquad(ilq) * xquad(jlq))) if (vmask(Itgt,Jtgt) == 1) vret_qp(iphi,jphi,qp) = vret_qp(iphi,jphi,qp) + & - (basal_trac(i,j) * vq) * (xquad(ilq) * xquad(jlq)) + ((basal_trac(i,j) * vq) * (xquad(ilq) * xquad(jlq))) endif enddo ; enddo enddo ; enddo @@ -2732,13 +2824,13 @@ subroutine CG_action_subgrid_basal(Phisub, H, U, V, bathyT, dens_ratio, Ucontr, uloc_arr(:,:,:,:) = 0.0; vloc_arr(:,:,:,:)=0.0 do j=1,nsub ; do i=1,nsub; do qy=1,2 ; do qx=1,2 - hloc = (Phisub(qx,qy,i,j,1,1)*H(1,1) + Phisub(qx,qy,i,j,2,2)*H(2,2)) + & - (Phisub(qx,qy,i,j,1,2)*H(1,2) + Phisub(qx,qy,i,j,2,1)*H(2,1)) + hloc = ((Phisub(qx,qy,i,j,1,1)*H(1,1)) + (Phisub(qx,qy,i,j,2,2)*H(2,2))) + & + ((Phisub(qx,qy,i,j,1,2)*H(1,2)) + (Phisub(qx,qy,i,j,2,1)*H(2,1))) if (dens_ratio * hloc - bathyT > 0) then - uloc_arr(qx,qy,i,j) = ((Phisub(qx,qy,i,j,1,1) * U(1,1) + Phisub(qx,qy,i,j,2,2) * U(2,2)) + & - (Phisub(qx,qy,i,j,1,2) * U(1,2) + Phisub(qx,qy,i,j,2,1) * U(2,1))) - vloc_arr(qx,qy,i,j) = ((Phisub(qx,qy,i,j,1,1) * V(1,1) + Phisub(qx,qy,i,j,2,2) * V(2,2)) + & - (Phisub(qx,qy,i,j,1,2) * V(1,2) + Phisub(qx,qy,i,j,2,1) * V(2,1))) + uloc_arr(qx,qy,i,j) = (((Phisub(qx,qy,i,j,1,1) * U(1,1)) + (Phisub(qx,qy,i,j,2,2) * U(2,2))) + & + ((Phisub(qx,qy,i,j,1,2) * U(1,2)) + (Phisub(qx,qy,i,j,2,1) * U(2,1)))) + vloc_arr(qx,qy,i,j) = (((Phisub(qx,qy,i,j,1,1) * V(1,1)) + (Phisub(qx,qy,i,j,2,2) * V(2,2))) + & + ((Phisub(qx,qy,i,j,1,2) * V(1,2)) + (Phisub(qx,qy,i,j,2,1) * V(2,1)))) endif enddo; enddo ; enddo ; enddo @@ -2817,12 +2909,10 @@ subroutine matrix_diagonal(CS, G, US, float_cond, H_node, ice_visc, basal_trac, !! (corner) points [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),CS%visc_qps), & intent(in) :: ice_visc !< A field related to the ice viscosity from Glen's - !! flow law [R L4 Z T-1 ~> kg m2 s-1]. The exact form - !! and units depend on the basal law exponent. + !! flow law [R L4 Z T-1 ~> kg m2 s-1]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: basal_trac !< Area-integrated taub_beta field related to the nonlinear !! part of the "linearized" basal stress [R L3 T-1 ~> kg s-1]. - real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -2891,8 +2981,8 @@ subroutine matrix_diagonal(CS, G, US, float_cond, H_node, ice_visc, basal_trac, vy = 0. u_diag_qp(iphi,jphi,qp) = & - ice_visc(i,j,qpv) * ((4*ux+2*vy) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j) + & - (uy+vx) * Phi(2*(2*(jphi-1)+iphi),qp,i,j)) + ice_visc(i,j,qpv) * (((4*ux+2*vy) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j)) + & + ((uy+vx) * Phi(2*(2*(jphi-1)+iphi),qp,i,j))) if (float_cond(i,j) == 0) then uq = xquad(ilq) * xquad(jlq) @@ -2909,8 +2999,8 @@ subroutine matrix_diagonal(CS, G, US, float_cond, H_node, ice_visc, basal_trac, uy = 0. v_diag_qp(iphi,jphi,qp) = & - ice_visc(i,j,qpv) * ((uy+vx) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j) + & - (4*vy+2*ux) * Phi(2*(2*(jphi-1)+iphi),qp,i,j)) + ice_visc(i,j,qpv) * (((uy+vx) * Phi(2*(2*(jphi-1)+iphi)-1,qp,i,j)) + & + ((4*vy+2*ux) * Phi(2*(2*(jphi-1)+iphi),qp,i,j))) if (float_cond(i,j) == 0) then vq = xquad(ilq) * xquad(jlq) @@ -2941,15 +3031,15 @@ subroutine matrix_diagonal(CS, G, US, float_cond, H_node, ice_visc, basal_trac, Hcell(:,:) = H_node(i-1:i,j-1:j) call CG_diagonal_subgrid_basal(Phisub, Hcell, CS%bed_elev(i,j), dens_ratio, sub_ground) - if (CS%umask(I-1,J-1) == 1) u_diag_b(I-1,J-1,4) = u_diag_b(I-1,J-1,4) + sub_ground(1,1) * basal_trac(i,j) - if (CS%umask(I-1,J ) == 1) u_diag_b(I-1,J ,2) = u_diag_b(I-1,J ,2) + sub_ground(1,2) * basal_trac(i,j) - if (CS%umask(I ,J-1) == 1) u_diag_b(I ,J-1,3) = u_diag_b(I ,J-1,3) + sub_ground(2,1) * basal_trac(i,j) - if (CS%umask(I ,J ) == 1) u_diag_b(I ,J ,1) = u_diag_b(I ,J ,1) + sub_ground(2,2) * basal_trac(i,j) + if (CS%umask(I-1,J-1) == 1) u_diag_b(I-1,J-1,4) = u_diag_b(I-1,J-1,4) + (sub_ground(1,1) * basal_trac(i,j)) + if (CS%umask(I-1,J ) == 1) u_diag_b(I-1,J ,2) = u_diag_b(I-1,J ,2) + (sub_ground(1,2) * basal_trac(i,j)) + if (CS%umask(I ,J-1) == 1) u_diag_b(I ,J-1,3) = u_diag_b(I ,J-1,3) + (sub_ground(2,1) * basal_trac(i,j)) + if (CS%umask(I ,J ) == 1) u_diag_b(I ,J ,1) = u_diag_b(I ,J ,1) + (sub_ground(2,2) * basal_trac(i,j)) - if (CS%vmask(I-1,J-1) == 1) v_diag_b(I-1,J-1,4) = v_diag_b(I-1,J-1,4) + sub_ground(1,1) * basal_trac(i,j) - if (CS%vmask(I-1,J ) == 1) v_diag_b(I-1,J ,2) = v_diag_b(I-1,J ,2) + sub_ground(1,2) * basal_trac(i,j) - if (CS%vmask(I ,J-1) == 1) v_diag_b(I ,J-1,3) = v_diag_b(I ,J-1,3) + sub_ground(2,1) * basal_trac(i,j) - if (CS%vmask(I ,J ) == 1) v_diag_b(I ,J ,1) = v_diag_b(I ,J ,1) + sub_ground(2,2) * basal_trac(i,j) + if (CS%vmask(I-1,J-1) == 1) v_diag_b(I-1,J-1,4) = v_diag_b(I-1,J-1,4) + (sub_ground(1,1) * basal_trac(i,j)) + if (CS%vmask(I-1,J ) == 1) v_diag_b(I-1,J ,2) = v_diag_b(I-1,J ,2) + (sub_ground(1,2) * basal_trac(i,j)) + if (CS%vmask(I ,J-1) == 1) v_diag_b(I ,J-1,3) = v_diag_b(I ,J-1,3) + (sub_ground(2,1) * basal_trac(i,j)) + if (CS%vmask(I ,J ) == 1) v_diag_b(I ,J ,1) = v_diag_b(I ,J ,1) + (sub_ground(2,2) * basal_trac(i,j)) endif endif ; enddo ; enddo @@ -2986,8 +3076,8 @@ subroutine CG_diagonal_subgrid_basal (Phisub, H_node, bathyT, dens_ratio, f_grnd grnd_stat(:,:,:,:)=0 do j=1,nsub ; do i=1,nsub; do qy=1,2 ; do qx=1,2 - hloc = (Phisub(qx,qy,i,j,1,1)*H_node(1,1) + Phisub(qx,qy,i,j,2,2)*H_node(2,2)) + & - (Phisub(qx,qy,i,j,1,2)*H_node(1,2) + Phisub(qx,qy,i,j,2,1)*H_node(2,1)) + hloc = ((Phisub(qx,qy,i,j,1,1)*H_node(1,1)) + (Phisub(qx,qy,i,j,2,2)*H_node(2,2))) + & + ((Phisub(qx,qy,i,j,1,2)*H_node(1,2)) + (Phisub(qx,qy,i,j,2,1)*H_node(2,1))) if (dens_ratio * hloc - bathyT > 0) grnd_stat(qx,qy,i,j) = 1 enddo; enddo ; enddo ; enddo @@ -3006,6 +3096,140 @@ subroutine CG_diagonal_subgrid_basal (Phisub, H_node, bathyT, dens_ratio, f_grnd end subroutine CG_diagonal_subgrid_basal +!> Post_data calls related to ice-sheet flux divergence, strain-rate, and deviatoric stress +subroutine IS_dynamics_post_data_2(CS, ISS, G) + type(ice_shelf_dyn_CS), intent(inout) :: CS !< A pointer to the ice shelf control structure + type(ice_shelf_state), intent(in) :: ISS !< A structure with elements that describe + !! the ice-shelf state + type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. + real, dimension(SZDIB_(G),SZDJB_(G)) :: H_node ! Ice shelf thickness at corners [Z ~> m]. + real, dimension(SZDIB_(G),SZDJB_(G)) :: Hu ! Ice shelf u_flux at corners [Z L T-1 ~> m2 s-1]. + real, dimension(SZDIB_(G),SZDJB_(G)) :: Hv ! Ice shelf v_flux at corners [Z L T-1 ~> m2 s-1]. + real, dimension(SZDI_(G),SZDJ_(G)) :: Hux ! Ice shelf d(u_flux)/dx at cell centers [Z T-1 ~> m s-1]. + real, dimension(SZDI_(G),SZDJ_(G)) :: Hvy ! Ice shelf d(v_flux)/dy at cell centers [Z T-1 ~> m s-1]. + real, dimension(SZDI_(G),SZDJ_(G)) :: flux_div ! horizontal flux divergence div(uH) [Z T-1 ~> m s-1]. + real, dimension(SZDI_(G),SZDJ_(G),3) :: strain_rate ! strain-rate components xx,yy, and xy [T-1 ~> s-1] + real, dimension(SZDI_(G),SZDJ_(G),2) :: p_strain_rate ! horizontal principal strain-rates [T-1 ~> s-1] + real, dimension(SZDI_(G),SZDJ_(G),3) :: dev_stress ! deviatoric stress components xx,yy, and xy [R L Z T-2 ~> Pa] + real, dimension(SZDI_(G),SZDJ_(G),2) :: p_dev_stress ! horizontal principal deviatoric stress [R L Z T-2 ~> Pa] + real, dimension(SZDI_(G),SZDJ_(G)) :: ice_visc ! area-averaged ice viscosity [R L2 T-1 ~> Pa s] + real :: p1,p2 ! Used to calculate strain-rate principal components [T-1 ~> s-1] + integer :: i, j + + !Allocate the gradient basis functions for 1 cell-centered quadrature point per cell + if (.not. associated(CS%PhiC)) then + allocate(CS%PhiC(1:8,G%isc:G%iec,G%jsc:G%jec), source=0.0) + do j=G%jsc,G%jec ; do i=G%isc,G%iec + call bilinear_shape_fn_grid_1qp(G, i, j, CS%PhiC(:,i,j)) + enddo; enddo + endif + + !Calculate flux divergence and its components + if (CS%id_duHdx > 0 .or. CS%id_dvHdy > 0 .or. CS%id_fluxdiv > 0) then + call interpolate_H_to_B(G, ISS%h_shelf, ISS%hmask, H_node, CS%min_h_shelf) + + Hu(:,:) = 0.0; Hv(:,:) = 0.0; Hux(:,:) = 0.0 ; Hvy(:,:) = 0.0 ; flux_div(:,:) = 0.0 + do J=G%jscB,G%jecB ; do I=G%iscB,G%iecB + if (CS%umask(I,J) > 0) then + Hu(I,J) = (H_node(I,J) * CS%u_shelf(I,J)) + endif + if (CS%vmask(I,J) > 0) then + Hv(I,J) = (H_node(I,J) * CS%v_shelf(I,J)) + endif + enddo; enddo + + do j=G%jsc,G%jec ; do i=G%isc,G%iec + if ((ISS%hmask(i,j) == 1) .or. (ISS%hmask(i,j) == 3)) then + !components of flux divergence at cell centers + Hux(i,j) = (((Hu(I-1,J-1) * CS%PhiC(1,i,j)) + (Hu(I,J ) * CS%PhiC(7,i,j))) + & + ((Hu(I-1,J ) * CS%PhiC(5,i,j)) + (Hu(I,J-1) * CS%PhiC(3,i,j)))) + + Hvy(i,j) = (((Hv(I-1,J-1) * CS%PhiC(2,i,j)) + (Hv(I,J ) * CS%PhiC(8,i,j))) + & + ((Hv(I-1,J ) * CS%PhiC(6,i,j)) + (Hv(I,J-1) * CS%PhiC(4,i,j)))) + flux_div(i,j) = Hux(i,j) + Hvy(i,j) + endif + enddo ; enddo + + if (CS%id_duHdx > 0) call post_data(CS%id_duHdx, Hux, CS%diag) + if (CS%id_dvHdy > 0) call post_data(CS%id_dvHdy, Hvy, CS%diag) + if (CS%id_fluxdiv > 0) call post_data(CS%id_fluxdiv, flux_div, CS%diag) + endif + + if (CS%id_devstress_xx > 0 .or. CS%id_devstress_yy > 0 .or. CS%id_devstress_xy > 0 .or. & + CS%id_strainrate_xx > 0 .or. CS%id_strainrate_yy > 0 .or. CS%id_strainrate_xy > 0 .or. & + CS%id_pdevstress_1 > 0 .or. CS%id_pdevstress_2 > 0 .or. & + CS%id_pstrainrate_1 > 0 .or. CS%id_pstrainrate_2 > 0) then + + strain_rate(:,:,:) = 0.0 + do j=G%jsc,G%jec ; do i=G%isc,G%iec + !strain-rates at cell centers + if ((ISS%hmask(i,j) == 1) .or. (ISS%hmask(i,j) == 3)) then + !strain_rate(:,:,1) = strain_rate_xx(:,:) = ux(:,:) + strain_rate(i,j,1) = (((CS%u_shelf(I-1,J-1) * CS%PhiC(1,i,j)) + (CS%u_shelf(I,J ) * CS%PhiC(7,i,j))) + & + ((CS%u_shelf(I-1,J ) * CS%PhiC(5,i,j)) + (CS%u_shelf(I,J-1) * CS%PhiC(3,i,j)))) + !strain_rate(:,:,2) = strain_rate_yy(:,:) = uy(:,:) + strain_rate(i,j,2) = (((CS%v_shelf(I-1,J-1) * CS%PhiC(2,i,j)) + (CS%v_shelf(I,J ) * CS%PhiC(8,i,j))) + & + ((CS%v_shelf(I-1,J ) * CS%PhiC(6,i,j)) + (CS%v_shelf(I,J-1) * CS%PhiC(4,i,j)))) + !strain_rate(:,:,3) = strain_rate_xy(:,:) = 0.5 * (uy(:,:) + vy(:,:)) + strain_rate(i,j,3) = 0.5 * ((((CS%u_shelf(I-1,J-1) * CS%PhiC(2,i,j)) + (CS%u_shelf(I,J ) * CS%PhiC(8,i,j))) + & + ((CS%u_shelf(I-1,J ) * CS%PhiC(6,i,j)) + (CS%u_shelf(I,J-1) * CS%PhiC(4,i,j))))+ & + (((CS%v_shelf(I-1,J-1) * CS%PhiC(1,i,j)) + (CS%v_shelf(I,J ) * CS%PhiC(7,i,j))) + & + ((CS%v_shelf(I-1,J ) * CS%PhiC(5,i,j)) + (CS%v_shelf(I,J-1) * CS%PhiC(3,i,j))))) + endif + enddo ; enddo + + + if (CS%id_strainrate_xx > 0) call post_data(CS%id_strainrate_xx, strain_rate(:,:,1), CS%diag) + if (CS%id_strainrate_yy > 0) call post_data(CS%id_strainrate_yy, strain_rate(:,:,2), CS%diag) + if (CS%id_strainrate_xy > 0) call post_data(CS%id_strainrate_xy, strain_rate(:,:,3), CS%diag) + + if (CS%id_pstrainrate_1 > 0 .or. CS%id_pstrainrate_2 > 0 .or. & + CS%id_pdevstress_1 > 0 .or. CS%id_pdevstress_2 > 0) then + p_strain_rate(:,:,:) = 0.0 + do j=G%jsc,G%jec ; do i=G%isc,G%iec + p1 = 0.5*( strain_rate(i,j,1) + strain_rate(i,j,2)) + p2 = sqrt( (( 0.5 * (strain_rate(i,j,1) - strain_rate(i,j,2)) )**2) + (strain_rate(i,j,3)**2) ) + p_strain_rate(i,j,1) = p1+p2 !Max horizontal principal strain-rate + p_strain_rate(i,j,2) = p1-p2 !Min horizontal principal strain-rate + enddo ; enddo + + if (CS%id_pstrainrate_1 > 0) call post_data(CS%id_pstrainrate_1, p_strain_rate(:,:,1), CS%diag) + if (CS%id_pstrainrate_2 > 0) call post_data(CS%id_pstrainrate_2, p_strain_rate(:,:,2), CS%diag) + endif + + if (CS%id_devstress_xx > 0 .or. CS%id_devstress_yy > 0 .or. CS%id_devstress_xy > 0 .or. & + CS%id_pdevstress_1 > 0 .or. CS%id_pdevstress_2 > 0) then + + call ice_visc_diag(CS,G,ice_visc) + + if (CS%id_devstress_xx > 0 .or. CS%id_devstress_yy > 0 .or. CS%id_devstress_xy > 0) then + dev_stress(:,:,:)=0.0 + do j=G%jsc,G%jec ; do i=G%isc,G%iec + if (ISS%h_shelf(i,j)>0) then + dev_stress(i,j,1) = 2*ice_visc(i,j)*strain_rate(i,j,1)/ISS%h_shelf(i,j) !deviatoric stress xx + dev_stress(i,j,2) = 2*ice_visc(i,j)*strain_rate(i,j,2)/ISS%h_shelf(i,j) !deviatoric stress yy + dev_stress(i,j,3) = 2*ice_visc(i,j)*strain_rate(i,j,3)/ISS%h_shelf(i,j) !deviatoric stress xy + endif + enddo; enddo + if (CS%id_devstress_xx > 0) call post_data(CS%id_devstress_xx, dev_stress(:,:,1), CS%diag) + if (CS%id_devstress_yy > 0) call post_data(CS%id_devstress_yy, dev_stress(:,:,2), CS%diag) + if (CS%id_devstress_xy > 0) call post_data(CS%id_devstress_xy, dev_stress(:,:,3), CS%diag) + endif + + if (CS%id_pdevstress_1 > 0 .or. CS%id_pdevstress_2 > 0) then + p_dev_stress(:,:,:)=0.0 + do j=G%jsc,G%jec ; do i=G%isc,G%iec + if (ISS%h_shelf(i,j)>0) then + p_dev_stress(i,j,1) = 2*ice_visc(i,j)*p_strain_rate(i,j,1)/ISS%h_shelf(i,j) !max horiz principal dev stress + p_dev_stress(i,j,2) = 2*ice_visc(i,j)*p_strain_rate(i,j,2)/ISS%h_shelf(i,j) !min horiz principal dev stress + endif + enddo; enddo + if (CS%id_pdevstress_1 > 0) call post_data(CS%id_pdevstress_1, p_dev_stress(:,:,1), CS%diag) + if (CS%id_pdevstress_2 > 0) call post_data(CS%id_pdevstress_2, p_dev_stress(:,:,2), CS%diag) + endif + endif + endif +end subroutine IS_dynamics_post_data_2 !> Update depth integrated viscosity, based on horizontal strain rates subroutine calc_shelf_visc(CS, ISS, G, US, u_shlf, v_shlf) @@ -3061,8 +3285,8 @@ subroutine calc_shelf_visc(CS, ISS, G, US, u_shlf, v_shlf) ! constant viscocity for debugging elseif (trim(CS%ice_viscosity_compute) == "OBS") then if (CS%AGlen_visc(i,j) >0) then - CS%ice_visc(i,j,1) = max(CS%AGlen_visc(i,j) * (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)),& - CS%min_ice_visc) + CS%ice_visc(i,j,1) = (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)) * & + max(CS%AGlen_visc(i,j) ,CS%min_ice_visc) endif ! Here CS%Aglen_visc(i,j) is the ice viscosity [Pa s ~> R L2 T-1] computed from obs and read from a file elseif (model_qp1) then @@ -3071,28 +3295,29 @@ subroutine calc_shelf_visc(CS, ISS, G, US, u_shlf, v_shlf) Visc_coef = (CS%AGlen_visc(i,j))**(-1./n_g) ! Units of Aglen_visc [Pa-(n_g) s-1] - ux = (u_shlf(I-1,J-1) * CS%PhiC(1,i,j) + & - u_shlf(I,J) * CS%PhiC(7,i,j)) + & - (u_shlf(I-1,J) * CS%PhiC(5,i,j) + & - u_shlf(I,J-1) * CS%PhiC(3,i,j)) - - vx = (v_shlf(I-1,J-1) * CS%PhiC(1,i,j) + & - v_shlf(I,J) * CS%PhiC(7,i,j)) + & - (v_shlf(I-1,J) * CS%PhiC(5,i,j) + & - v_shlf(I,J-1) * CS%PhiC(3,i,j)) - - uy = (u_shlf(I-1,J-1) * CS%PhiC(2,i,j) + & - u_shlf(I,J) * CS%PhiC(8,i,j)) + & - (u_shlf(I-1,J) * CS%PhiC(6,i,j) + & - u_shlf(I,J-1) * CS%PhiC(4,i,j)) - - vy = (v_shlf(I-1,J-1) * CS%PhiC(2,i,j) + & - v_shlf(I,J) * CS%PhiC(8,i,j)) + & - (v_shlf(I-1,J) * CS%PhiC(6,i,j) + & - v_shlf(I,J-1) * CS%PhiC(4,i,j)) - - CS%ice_visc(i,j,1) = max(0.5 * Visc_coef * (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)) * & - (US%s_to_T**2 * ((ux**2 + vy**2) + (ux*vy + 0.25*(uy+vx)**2) + eps_min**2))**((1.-n_g)/(2.*n_g)) * & + ux = ((u_shlf(I-1,J-1) * CS%PhiC(1,i,j)) + & + (u_shlf(I,J) * CS%PhiC(7,i,j))) + & + ((u_shlf(I-1,J) * CS%PhiC(5,i,j)) + & + (u_shlf(I,J-1) * CS%PhiC(3,i,j))) + + vx = ((v_shlf(I-1,J-1) * CS%PhiC(1,i,j)) + & + (v_shlf(I,J) * CS%PhiC(7,i,j))) + & + ((v_shlf(I-1,J) * CS%PhiC(5,i,j)) + & + (v_shlf(I,J-1) * CS%PhiC(3,i,j))) + + uy = ((u_shlf(I-1,J-1) * CS%PhiC(2,i,j)) + & + (u_shlf(I,J) * CS%PhiC(8,i,j))) + & + ((u_shlf(I-1,J) * CS%PhiC(6,i,j)) + & + (u_shlf(I,J-1) * CS%PhiC(4,i,j))) + + vy = ((v_shlf(I-1,J-1) * CS%PhiC(2,i,j)) + & + (v_shlf(I,J) * CS%PhiC(8,i,j))) + & + ((v_shlf(I-1,J) * CS%PhiC(6,i,j)) + & + (v_shlf(I,J-1) * CS%PhiC(4,i,j))) + + CS%ice_visc(i,j,1) = (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)) * & + max(0.5 * Visc_coef * & + (US%s_to_T**2 * (((ux**2) + (vy**2)) + ((ux*vy) + 0.25*((uy+vx)**2)) + eps_min**2))**((1.-n_g)/(2.*n_g)) * & (US%Pa_to_RL2_T2*US%s_to_T),CS%min_ice_visc) elseif (model_qp4) then !calculate viscosity at 4 quadrature points per cell @@ -3101,28 +3326,29 @@ subroutine calc_shelf_visc(CS, ISS, G, US, u_shlf, v_shlf) do iq=1,2 ; do jq=1,2 - ux = (u_shlf(I-1,J-1) * CS%Phi(1,2*(jq-1)+iq,i,j) + & - u_shlf(I,J) * CS%Phi(7,2*(jq-1)+iq,i,j)) + & - (u_shlf(I,J-1) * CS%Phi(3,2*(jq-1)+iq,i,j) + & - u_shlf(I-1,J) * CS%Phi(5,2*(jq-1)+iq,i,j)) - - vx = (v_shlf(I-1,J-1) * CS%Phi(1,2*(jq-1)+iq,i,j) + & - v_shlf(I,J) * CS%Phi(7,2*(jq-1)+iq,i,j)) + & - (v_shlf(I,J-1) * CS%Phi(3,2*(jq-1)+iq,i,j) + & - v_shlf(I-1,J) * CS%Phi(5,2*(jq-1)+iq,i,j)) - - uy = (u_shlf(I-1,J-1) * CS%Phi(2,2*(jq-1)+iq,i,j) + & - u_shlf(I,J) * CS%Phi(8,2*(jq-1)+iq,i,j)) + & - (u_shlf(I,J-1) * CS%Phi(4,2*(jq-1)+iq,i,j) + & - u_shlf(I-1,J) * CS%Phi(6,2*(jq-1)+iq,i,j)) - - vy = (v_shlf(I-1,J-1) * CS%Phi(2,2*(jq-1)+iq,i,j) + & - v_shlf(I,J) * CS%Phi(8,2*(jq-1)+iq,i,j)) + & - (v_shlf(I,J-1) * CS%Phi(4,2*(jq-1)+iq,i,j) + & - v_shlf(I-1,J) * CS%Phi(6,2*(jq-1)+iq,i,j)) - - CS%ice_visc(i,j,2*(jq-1)+iq) = max(0.5 * Visc_coef * (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)) * & - (US%s_to_T**2 * ((ux**2 + vy**2) + (ux*vy + 0.25*(uy+vx)**2) + eps_min**2))**((1.-n_g)/(2.*n_g)) * & + ux = ((u_shlf(I-1,J-1) * CS%Phi(1,2*(jq-1)+iq,i,j)) + & + (u_shlf(I,J) * CS%Phi(7,2*(jq-1)+iq,i,j))) + & + ((u_shlf(I,J-1) * CS%Phi(3,2*(jq-1)+iq,i,j)) + & + (u_shlf(I-1,J) * CS%Phi(5,2*(jq-1)+iq,i,j))) + + vx = ((v_shlf(I-1,J-1) * CS%Phi(1,2*(jq-1)+iq,i,j)) + & + (v_shlf(I,J) * CS%Phi(7,2*(jq-1)+iq,i,j))) + & + ((v_shlf(I,J-1) * CS%Phi(3,2*(jq-1)+iq,i,j)) + & + (v_shlf(I-1,J) * CS%Phi(5,2*(jq-1)+iq,i,j))) + + uy = ((u_shlf(I-1,J-1) * CS%Phi(2,2*(jq-1)+iq,i,j)) + & + (u_shlf(I,J) * CS%Phi(8,2*(jq-1)+iq,i,j))) + & + ((u_shlf(I,J-1) * CS%Phi(4,2*(jq-1)+iq,i,j)) + & + (u_shlf(I-1,J) * CS%Phi(6,2*(jq-1)+iq,i,j))) + + vy = ((v_shlf(I-1,J-1) * CS%Phi(2,2*(jq-1)+iq,i,j)) + & + (v_shlf(I,J) * CS%Phi(8,2*(jq-1)+iq,i,j))) + & + ((v_shlf(I,J-1) * CS%Phi(4,2*(jq-1)+iq,i,j)) + & + (v_shlf(I-1,J) * CS%Phi(6,2*(jq-1)+iq,i,j))) + + CS%ice_visc(i,j,2*(jq-1)+iq) = (G%areaT(i,j) * max(ISS%h_shelf(i,j),CS%min_h_shelf)) * & + max(0.5 * Visc_coef * & + (US%s_to_T**2 * (((ux**2) + (vy**2)) + ((ux*vy) + 0.25*((uy+vx)**2)) + eps_min**2))**((1.-n_g)/(2.*n_g)) * & (US%Pa_to_RL2_T2*US%s_to_T),CS%min_ice_visc) enddo; enddo endif @@ -3181,7 +3407,7 @@ subroutine calc_shelf_taub(CS, ISS, G, US, u_shlf, v_shlf) if ((ISS%hmask(i,j) == 1) .OR. (ISS%hmask(i,j) == 3)) then umid = ((u_shlf(I,J) + u_shlf(I-1,J-1)) + (u_shlf(I,J-1) + u_shlf(I-1,J))) * 0.25 vmid = ((v_shlf(I,J) + v_shlf(I-1,J-1)) + (v_shlf(I,J-1) + v_shlf(I-1,J))) * 0.25 - unorm = US%L_T_to_m_s * sqrt( (umid**2 + vmid**2) + (eps_min**2 * (G%dxT(i,j)**2 + G%dyT(i,j)**2)) ) + unorm = US%L_T_to_m_s * sqrt( ((umid**2) + (vmid**2)) + (eps_min**2 * (G%dxT(i,j)**2 + G%dyT(i,j)**2)) ) !Coulomb friction (Schoof 2005, Gagliardini et al 2007) if (CS%CoulombFriction) then @@ -3358,10 +3584,10 @@ subroutine bilinear_shape_functions (X, Y, Phi, area) do qpoint=1,4 - a = -X(1)*(1-yquad(qpoint)) + X(2)*(1-yquad(qpoint)) - X(3)*yquad(qpoint) + X(4)*yquad(qpoint) ! d(x)/d(x*) - b = -Y(1)*(1-yquad(qpoint)) + Y(2)*(1-yquad(qpoint)) - Y(3)*yquad(qpoint) + Y(4)*yquad(qpoint) ! d(y)/d(x*) - c = -X(1)*(1-xquad(qpoint)) - X(2)*xquad(qpoint) + X(3)*(1-xquad(qpoint)) + X(4)*xquad(qpoint) ! d(x)/d(y*) - d = -Y(1)*(1-xquad(qpoint)) - Y(2)*xquad(qpoint) + Y(3)*(1-xquad(qpoint)) + Y(4)*xquad(qpoint) ! d(y)/d(y*) + a = ((-X(1)*(1-yquad(qpoint)))+(X(4)*yquad(qpoint))) + ((X(2)*(1-yquad(qpoint)))-(X(3)*yquad(qpoint))) !d(x)/d(x*) + b = ((-Y(1)*(1-yquad(qpoint)))+(Y(4)*yquad(qpoint))) + ((Y(2)*(1-yquad(qpoint)))-(Y(3)*yquad(qpoint))) !d(y)/d(x*) + c = ((-X(1)*(1-xquad(qpoint)))+(X(4)*xquad(qpoint))) + ((-X(2)*xquad(qpoint))+(X(3)*(1-xquad(qpoint))))!d(x)/d(y*) + d = ((-Y(1)*(1-xquad(qpoint)))+(Y(4)*xquad(qpoint))) + ((-Y(2)*xquad(qpoint))+(Y(3)*(1-xquad(qpoint))))!d(y)/d(y*) do node=1,4 @@ -3379,8 +3605,8 @@ subroutine bilinear_shape_functions (X, Y, Phi, area) xexp = xquad(qpoint) endif - Phi(2*node-1,qpoint) = ( d * (2 * xnode - 3) * yexp - b * (2 * ynode - 3) * xexp) / (a*d-b*c) - Phi(2*node,qpoint) = (-c * (2 * xnode - 3) * yexp + a * (2 * ynode - 3) * xexp) / (a*d-b*c) + Phi(2*node-1,qpoint) = ( d * (2 * xnode - 3) * yexp - b * (2 * ynode - 3) * xexp) / ((a*d)-(b*c)) + Phi(2*node,qpoint) = (-c * (2 * xnode - 3) * yexp + a * (2 * ynode - 3) * xexp) / ((a*d)-(b*c)) enddo enddo @@ -3420,12 +3646,12 @@ subroutine bilinear_shape_fn_grid(G, i, j, Phi) do qpoint=1,4 if (J>1) then - a = G%dxCv(i,J-1) * (1-yquad(qpoint)) + G%dxCv(i,J) * yquad(qpoint) ! d(x)/d(x*) + a = (G%dxCv(i,J-1) * (1-yquad(qpoint))) + (G%dxCv(i,J) * yquad(qpoint)) ! d(x)/d(x*) else a = G%dxCv(i,J) !* yquad(qpoint) ! d(x)/d(x*) endif if (I>1) then - d = G%dyCu(I-1,j) * (1-xquad(qpoint)) + G%dyCu(I,j) * xquad(qpoint) ! d(y)/d(y*) + d = (G%dyCu(I-1,j) * (1-xquad(qpoint))) + (G%dyCu(I,j) * xquad(qpoint)) ! d(y)/d(y*) else d = G%dyCu(I,j) !* xquad(qpoint) endif @@ -3707,7 +3933,7 @@ end subroutine update_velocity_masks !> Interpolate the ice shelf thickness from tracer point to nodal points, !! subject to a mask. subroutine interpolate_H_to_B(G, h_shelf, hmask, H_node, min_h_shelf) - type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. + type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: h_shelf !< The ice shelf thickness at tracer points [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & @@ -3942,8 +4168,8 @@ subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux) elseif (hmask(i-1,j) * hmask(i-2,j) == 1) then ! h(i-2) and h(i-1) are valid phi = slope_limiter(stencil(-1)-stencil(-2), stencil(0)-stencil(-1)) - flux_diff = flux_diff + ABS(u_face) * G%dyCu(I-1,j)* time_step / G%areaT(i,j) * & - (stencil(-1) - phi * (stencil(-1)-stencil(0))/2) + flux_diff = flux_diff + ((ABS(u_face) * G%dyCu(I-1,j)* time_step / G%areaT(i,j)) * & + (stencil(-1) - (phi * (stencil(-1)-stencil(0))/2))) else ! h(i-1) is valid ! (o.w. flux would most likely be out of cell) @@ -3956,8 +4182,8 @@ subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux) elseif (u_face < 0) then !flux is out of cell - we need info from h(i-1), h(i+1) if available if (hmask(i-1,j) * hmask(i+1,j) == 1) then ! h(i-1) and h(i+1) are both valid phi = slope_limiter(stencil(0)-stencil(1), stencil(-1)-stencil(0)) - flux_diff = flux_diff - ABS(u_face) * G%dyCu(I-1,j) * time_step / G%areaT(i,j) * & - (stencil(0) - phi * (stencil(0)-stencil(-1))/2) + flux_diff = flux_diff - ((ABS(u_face) * G%dyCu(I-1,j) * time_step / G%areaT(i,j)) * & + (stencil(0) - (phi * (stencil(0)-stencil(-1))/2))) else flux_diff = flux_diff - ABS(u_face) * G%dyCu(I-1,j) * time_step / G%areaT(i,j) * stencil(0) @@ -3987,8 +4213,8 @@ subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux) elseif (hmask(i+1,j) * hmask(i+2,j) == 1) then ! h(i+2) and h(i+1) are valid phi = slope_limiter(stencil(1)-stencil(2), stencil(0)-stencil(1)) - flux_diff = flux_diff + ABS(u_face) * G%dyCu(I,j) * time_step / G%areaT(i,j) * & - (stencil(1) - phi * (stencil(1)-stencil(0))/2) + flux_diff = flux_diff + ((ABS(u_face) * G%dyCu(I,j) * time_step / G%areaT(i,j)) * & + (stencil(1) - (phi * (stencil(1)-stencil(0))/2))) else ! h(i+1) is valid ! (o.w. flux would most likely be out of cell) @@ -4003,8 +4229,8 @@ subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux) if (hmask(i-1,j) * hmask(i+1,j) == 1) then ! h(i-1) and h(i+1) are both valid phi = slope_limiter(stencil(0)-stencil(-1), stencil(1)-stencil(0)) - flux_diff = flux_diff - ABS(u_face) * G%dyCu(I,j) * time_step / G%areaT(i,j) * & - (stencil(0) - phi * (stencil(0)-stencil(1))/2) + flux_diff = flux_diff - ((ABS(u_face) * G%dyCu(I,j) * time_step / G%areaT(i,j)) * & + (stencil(0) - (phi * (stencil(0)-stencil(1))/2))) else ! h(i+1) is valid (o.w. flux would most likely be out of cell) but h(i+2) is not @@ -4108,8 +4334,8 @@ subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_aft elseif (hmask(i,j-1) * hmask(i,j-2) == 1) then ! h(j-2) and h(j-1) are valid phi = slope_limiter(stencil(-1)-stencil(-2), stencil(0)-stencil(-1)) - flux_diff = flux_diff + ABS(v_face) * G%dxCv(i,J-1) * time_step / G%areaT(i,j) * & - (stencil(-1) - phi * (stencil(-1)-stencil(0))/2) + flux_diff = flux_diff + ((ABS(v_face) * G%dxCv(i,J-1) * time_step / G%areaT(i,j)) * & + (stencil(-1) - (phi * (stencil(-1)-stencil(0))/2))) else ! h(j-1) is valid ! (o.w. flux would most likely be out of cell) @@ -4121,8 +4347,8 @@ subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_aft if (hmask(i,j-1) * hmask(i,j+1) == 1) then ! h(j-1) and h(j+1) are both valid phi = slope_limiter(stencil(0)-stencil(1), stencil(-1)-stencil(0)) - flux_diff = flux_diff - ABS(v_face) * G%dxCv(i,J-1) * time_step / G%areaT(i,j) * & - (stencil(0) - phi * (stencil(0)-stencil(-1))/2) + flux_diff = flux_diff - ((ABS(v_face) * G%dxCv(i,J-1) * time_step / G%areaT(i,j)) * & + (stencil(0) - (phi * (stencil(0)-stencil(-1))/2))) else flux_diff = flux_diff - ABS(v_face) * G%dxCv(i,J-1) * time_step / G%areaT(i,j) * stencil(0) endif @@ -4148,8 +4374,8 @@ subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_aft flux_diff = flux_diff + ABS(v_face) * G%dxCv(i,J) * time_step * stencil(1) / G%areaT(i,j) elseif (hmask(i,j+1) * hmask(i,j+2) == 1) then ! h(j+2) and h(j+1) are valid phi = slope_limiter (stencil(1)-stencil(2), stencil(0)-stencil(1)) - flux_diff = flux_diff + ABS(v_face) * G%dxCv(i,J) * time_step / G%areaT(i,j) * & - (stencil(1) - phi * (stencil(1)-stencil(0))/2) + flux_diff = flux_diff + ((ABS(v_face) * G%dxCv(i,J) * time_step / G%areaT(i,j)) * & + (stencil(1) - (phi * (stencil(1)-stencil(0))/2))) else ! h(j+1) is valid ! (o.w. flux would most likely be out of cell) ! but h(j+2) is not @@ -4160,8 +4386,8 @@ subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_aft if (hmask(i,j-1) * hmask(i,j+1) == 1) then ! h(j-1) and h(j+1) are both valid phi = slope_limiter (stencil(0)-stencil(-1), stencil(1)-stencil(0)) - flux_diff = flux_diff - ABS(v_face) * G%dxCv(i,J) * time_step / G%areaT(i,j) * & - (stencil(0) - phi * (stencil(0)-stencil(1))/2) + flux_diff = flux_diff - ((ABS(v_face) * G%dxCv(i,J) * time_step / G%areaT(i,j)) * & + (stencil(0) - (phi * (stencil(0)-stencil(1))/2))) else ! h(j+1) is valid ! (o.w. flux would most likely be out of cell) ! but h(j+2) is not diff --git a/src/initialization/MOM_fixed_initialization.F90 b/src/initialization/MOM_fixed_initialization.F90 index ea45e0cc2f..f54eb8a638 100644 --- a/src/initialization/MOM_fixed_initialization.F90 +++ b/src/initialization/MOM_fixed_initialization.F90 @@ -146,6 +146,7 @@ subroutine MOM_initialize_fixed(G, US, OBC, PF, write_geom, output_dir) endif ! Read sub-grid scale topography parameters at velocity points used for porous barrier calculation + ! TODO: The following routine call may eventually be merged as one of the CHANNEL_CONFIG options call get_param(PF, mdl, "SUBGRID_TOPO_AT_VEL", read_porous_file, & "If true, use variables from TOPO_AT_VEL_FILE as parameters for porous barrier.", & default=.False.)