diff --git a/reg_tests/cpld_gridgen/rt.conf b/reg_tests/cpld_gridgen/rt.conf index 7c263f631..64b2a617f 100644 --- a/reg_tests/cpld_gridgen/rt.conf +++ b/reg_tests/cpld_gridgen/rt.conf @@ -1,6 +1,32 @@ -# C384_025 needs to be the first test due to dependency +################################################################# +# Baseline configurations +# C384_025 needs to be the first test due to dependency of +# the weight-generation from 1/4deg ocean to lower resolution +################################################################# + # TEST_NAME | DEP_NAME # C384_025 | C192_050 | C384_025 C096_100 | C384_025 + +################################################################# +# Non-baseline configurations. +# These configurations have been tested on hera. For hera, the +# memory use for the C3072 config is approx 60% of the full node, +# C1152 is 12% of the full node and C768 is 8% of the full node. +# The default is set as 12g on RDHPCS platforms and should be +# sufficient for all but C3072. On hera C3072 requires approx 50min +# of wall clock and using --exclusive. See C3072 settings in rt.sh +# +# Note that the 5deg ocean cases are currently only supported on +# hera +################################################################# + + #C3072_025 | + #C1152_025 | + #C768_025 | + + #C192_025 | + #C048_500 | C384_025 + #C096_500 | C384_025 diff --git a/reg_tests/cpld_gridgen/rt.sh b/reg_tests/cpld_gridgen/rt.sh index 9a947391a..b08cbac7c 100755 --- a/reg_tests/cpld_gridgen/rt.sh +++ b/reg_tests/cpld_gridgen/rt.sh @@ -1,98 +1,100 @@ #!/bin/bash set -eu +SECONDS=0 + error() { - echo - echo "$@" 1>&2 - exit 1 + echo + echo "$@" 1>&2 + exit 1 } usage() { - echo - echo "Usage: $program [-c] [-m] [-h] [-b]" - echo - echo " -b build the executable" - echo - echo " -c create a new baseline" - echo - echo " -m compare against the new baseline" - echo - echo " -h display this help and exit" - echo - echo " Examples" - echo - echo " './rt.sh -b' build exe file. compare against the existing baseline" - echo " './rt.sh -bc' build exe file. create a new baseline" - echo " './rt.sh -m' do not build exe file. compare against the new baseline" - echo + echo + echo "Usage: $program [-c] [-m] [-h] [-b]" + echo + echo " -b build the executable" + echo + echo " -c create a new baseline" + echo + echo " -m compare against the new baseline" + echo + echo " -h display this help and exit" + echo + echo " Examples" + echo + echo " './rt.sh -b' build exe file. compare against the existing baseline" + echo " './rt.sh -bc' build exe file. create a new baseline" + echo " './rt.sh -m' do not build exe file. compare against the new baseline" + echo } usage_and_exit() { - usage - exit $1 + usage + exit $1 } check_results() { - [ -o xtrace ] && set_x='set -x' || set_x='set +x' - set +x - - local test_status=PASS - # verification run - if [[ $CREATE_BASELINE = false ]]; then - - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo "Working dir = $RUNDIR" | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo "Baseline dir = $BASELINE" | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo "Checking test $TEST_NAME results ...." | tee -a $PATHRT/$REGRESSIONTEST_LOG - - for file in $BASELINE/*.nc; do - printf %s "Comparing " $(basename ${file}) "...." | tee -a $PATHRT/$REGRESSIONTEST_LOG - - if [[ ! -f $RUNDIR/$(basename ${file}) ]]; then - echo "....MISSING file" | tee -a $PATHRT/$REGRESSIONTEST_LOG - test_status=FAIL - else - $NCCMP -dmfqS $(basename ${file}) $file >>${PATHRT}/nccmp_${TEST_NAME}.log 2>&1 && d=$? || d=$? - if [[ $d -ne 0 ]]; then - echo "....NOT OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG - test_status=FAIL - else - echo "....OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG - fi - fi - done - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - - # baseline creation run - else - - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo "Working dir = $RUNDIR" | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo "Moving baseline files to $NEW_BASELINE ...." | tee -a $PATHRT/$REGRESSIONTEST_LOG - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - - mkdir -p $NEW_BASELINE - - for file in *.nc; do - printf %s "Moving " $file "...." | tee -a $PATHRT/$REGRESSIONTEST_LOG + [ -o xtrace ] && set_x='set -x' || set_x='set +x' + set +x + + local test_status=PASS + # verification run + if [[ $CREATE_BASELINE = false ]]; then + + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo "Working dir = $RUNDIR" | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo "Baseline dir = $BASELINE" | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo "Checking test $TEST_NAME results ...." | tee -a $PATHRT/$REGRESSIONTEST_LOG + + for file in $BASELINE/*.nc; do + printf %s "Comparing " $(basename ${file}) "...." | tee -a $PATHRT/$REGRESSIONTEST_LOG + + if [[ ! -f $RUNDIR/$(basename ${file}) ]]; then + echo "....MISSING file" | tee -a $PATHRT/$REGRESSIONTEST_LOG + test_status=FAIL + else + $NCCMP -dmfqS -w format $(basename ${file}) $file >>${PATHRT}/nccmp_${TEST_NAME}.log 2>&1 && d=$? || d=$? + if [[ $d -ne 0 ]]; then + echo "....NOT OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG + test_status=FAIL + else + echo "....OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG + fi + fi + done + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG + + # baseline creation run + else + + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo "Working dir = $RUNDIR" | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo "Moving baseline files to $NEW_BASELINE ...." | tee -a $PATHRT/$REGRESSIONTEST_LOG + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG + + mkdir -p $NEW_BASELINE + + for file in *.nc; do + printf %s "Moving " $file "...." | tee -a $PATHRT/$REGRESSIONTEST_LOG + + cp $file $NEW_BASELINE/$file && d=$? || d=$? + if [[ $d -ne 0 ]]; then + echo "....NOT OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG + test_status=FAIL + else + echo "....OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG + fi + done + echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - cp $file $NEW_BASELINE/$file && d=$? || d=$? - if [[ $d -ne 0 ]]; then - echo "....NOT OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG - test_status=FAIL - else - echo "....OK" | tee -a $PATHRT/$REGRESSIONTEST_LOG - fi - done - echo | tee -a $PATHRT/$REGRESSIONTEST_LOG - - fi + fi - if [[ $test_status == FAIL ]]; then - echo "$TEST_NAME failed" >> $PATHRT/fail_test_$TEST_NAME - fi + if [[ $test_status == FAIL ]]; then + echo "$TEST_NAME failed" >> $PATHRT/fail_test_$TEST_NAME + fi } readonly program=$(basename $0) @@ -105,6 +107,12 @@ export PATHTR TESTS_FILE="$PATHRT/rt.conf" export TEST_NAME= +# for C3072 on hera, use WLCLK=60 and MEM="--exclusive" +WLCLK_dflt=10 +export WLCLK=$WLCLK_dflt +MEM_dflt="--mem=12g" +export MEM=$MEM_dflt + cd $PATHRT export compiler=${compiler:-intel} source $PATHTR/sorc/machine-setup.sh >/dev/null 2>&1 @@ -116,43 +124,43 @@ REGRESSIONTEST_LOG=RegressionTests_$target.$compiler.log rm -f fail_test* $COMPILE_LOG run_*.log nccmp_*.log summary.log if [[ $target = wcoss2 ]]; then - STMP=${STMP:-/lfs/h2/emc/stmp/$USER} - export MOM6_FIXDIR=/lfs/h2/emc/nems/noscrub/emc.nems/UFS_UTILS/reg_tests/cpld_gridgen/fix_mom6 - BASELINE_ROOT=/lfs/h2/emc/nems/noscrub/emc.nems/UFS_UTILS/reg_tests/cpld_gridgen/baseline_data - ACCOUNT=${ACCOUNT:-GFS-DEV} - export APRUN="mpiexec -n 1 -ppn 1 --cpu-bind core" - QUEUE=${QUEUE:-dev} - SBATCH_COMMAND="./cpld_gridgen.sh" - NCCMP=/lfs/h2/emc/global/noscrub/George.Gayno/util/nccmp/nccmp-1.8.5.0/src/nccmp + STMP=${STMP:-/lfs/h2/emc/stmp/$USER} + export MOM6_FIXDIR=/lfs/h2/emc/nems/noscrub/emc.nems/UFS_UTILS/reg_tests/cpld_gridgen/fix_mom6 + BASELINE_ROOT=/lfs/h2/emc/nems/noscrub/emc.nems/UFS_UTILS/reg_tests/cpld_gridgen/baseline_data + ACCOUNT=${ACCOUNT:-GFS-DEV} + export APRUN="mpiexec -n 1 -ppn 1 --cpu-bind core" + QUEUE=${QUEUE:-dev} + SBATCH_COMMAND="./cpld_gridgen.sh" + NCCMP=/lfs/h2/emc/global/noscrub/George.Gayno/util/nccmp/nccmp-1.8.5.0/src/nccmp elif [[ $target = hera ]]; then - STMP=${STMP:-/scratch1/NCEPDEV/stmp4/$USER} - export MOM6_FIXDIR=/scratch1/NCEPDEV/nems/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 - BASELINE_ROOT=/scratch1/NCEPDEV/nems/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/baseline_data - ACCOUNT=${ACCOUNT:-nems} - QUEUE=${QUEUE:-batch} - NCCMP=nccmp - PARTITION=hera - SBATCH_COMMAND="./cpld_gridgen.sh" + STMP=${STMP:-/scratch1/NCEPDEV/stmp4/$USER} + export MOM6_FIXDIR=/scratch1/NCEPDEV/nems/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 + BASELINE_ROOT=/scratch1/NCEPDEV/nems/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/baseline_data + ACCOUNT=${ACCOUNT:-nems} + QUEUE=${QUEUE:-batch} + NCCMP=nccmp + PARTITION=hera + SBATCH_COMMAND="./cpld_gridgen.sh" elif [[ $target = orion ]]; then - STMP=${STMP:-/work/noaa/stmp/$USER} - export MOM6_FIXDIR=/work/noaa/nems/role-nems/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 - BASELINE_ROOT=/work/noaa/nems/role-nems/ufs_utils/reg_tests/cpld_gridgen/baseline_data - ACCOUNT=${ACCOUNT:-nems} - QUEUE=${QUEUE:-batch} - NCCMP=nccmp - PARTITION=orion - ulimit -s unlimited - SBATCH_COMMAND="./cpld_gridgen.sh" + STMP=${STMP:-/work/noaa/stmp/$USER} + export MOM6_FIXDIR=/work/noaa/nems/role-nems/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 + BASELINE_ROOT=/work/noaa/nems/role-nems/ufs_utils/reg_tests/cpld_gridgen/baseline_data + ACCOUNT=${ACCOUNT:-nems} + QUEUE=${QUEUE:-batch} + NCCMP=nccmp + PARTITION=orion + ulimit -s unlimited + SBATCH_COMMAND="./cpld_gridgen.sh" elif [[ $target = jet ]]; then - STMP=${STMP:-/lfs4/HFIP/h-nems/$USER} - export MOM6_FIXDIR=/lfs4/HFIP/hfv3gfs/emc.nemspara/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 - BASELINE_ROOT=/lfs4/HFIP/hfv3gfs/emc.nemspara/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/baseline_data - ACCOUNT=${ACCOUNT:-h-nems} - QUEUE=${QUEUE:-batch} - NCCMP=nccmp - PARTITION=xjet - ulimit -s unlimited - SBATCH_COMMAND="./cpld_gridgen.sh" + STMP=${STMP:-/lfs4/HFIP/h-nems/$USER} + export MOM6_FIXDIR=/lfs4/HFIP/hfv3gfs/emc.nemspara/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/fix_mom6 + BASELINE_ROOT=/lfs4/HFIP/hfv3gfs/emc.nemspara/role.ufsutils/ufs_utils/reg_tests/cpld_gridgen/baseline_data + ACCOUNT=${ACCOUNT:-h-nems} + QUEUE=${QUEUE:-batch} + NCCMP=nccmp + PARTITION=xjet + ulimit -s unlimited + SBATCH_COMMAND="./cpld_gridgen.sh" fi NEW_BASELINE_ROOT=$STMP/CPLD_GRIDGEN/BASELINE RUNDIR_ROOT=$STMP/CPLD_GRIDGEN/rt_$$ @@ -160,41 +168,41 @@ RUNDIR_ROOT=$STMP/CPLD_GRIDGEN/rt_$$ BUILD_EXE=false CREATE_BASELINE=false while getopts :bcmh opt; do - case $opt in - b) - BUILD_EXE=true - ;; - c) - CREATE_BASELINE=true - ;; - m) - BASELINE_ROOT=$NEW_BASELINE_ROOT - ;; - h) - usage_and_exit 0 - ;; - '?') - error "$program: invalid option" - ;; - esac + case $opt in + b) + BUILD_EXE=true + ;; + c) + CREATE_BASELINE=true + ;; + m) + BASELINE_ROOT=$NEW_BASELINE_ROOT + ;; + h) + usage_and_exit 0 + ;; + '?') + error "$program: invalid option" + ;; + esac done # Build the executable file if [[ $BUILD_EXE = true ]]; then - cd $PATHTR - rm -rf $PATHTR/build $PATHTR/exec $PATHTR/lib - ./build_all.sh >$PATHRT/$COMPILE_LOG 2>&1 && d=$? || d=$? - if [[ d -ne 0 ]]; then - error "Build did not finish successfully. Check $COMPILE_LOG" - else - echo "Build was successful" - fi + cd $PATHTR + rm -rf $PATHTR/build $PATHTR/exec $PATHTR/lib + ./build_all.sh >$PATHRT/$COMPILE_LOG 2>&1 && d=$? || d=$? + if [[ d -ne 0 ]]; then + error "Build did not finish successfully. Check $COMPILE_LOG" + else + echo "Build was successful" + fi fi if [[ ! -f $PATHTR/exec/cpld_gridgen ]]; then - error "cpld_gridgen exe file is not found in $PATHTR/exe/. Try -b to build or -h for help." + error "cpld_gridgen exe file is not found in $PATHTR/exe/. Try -b to build or -h for help." else - echo "cpld_gridgen exe file is found in $PATHTR/exec/" + echo "cpld_gridgen exe file is found in $PATHTR/exec/" fi module use $PATHTR/modulefiles @@ -202,8 +210,8 @@ module load build.$target.$compiler module list if [[ $CREATE_BASELINE = true ]]; then - rm -rf $NEW_BASELINE_ROOT - mkdir -p $NEW_BASELINE_ROOT + rm -rf $NEW_BASELINE_ROOT + mkdir -p $NEW_BASELINE_ROOT fi date > $PATHRT/$REGRESSIONTEST_LOG @@ -212,92 +220,98 @@ echo "Start Regression test" | tee -a $PATHRT/$REGRESSIONTEST_LOG # Run tests specified in $TESTS_FILE while read -r line || [ "$line" ]; do - line="${line#"${line%%[![:space:]]*}"}" - [[ ${#line} == 0 ]] && continue - [[ $line =~ \# ]] && continue - - TEST_NAME=$(echo $line | cut -d'|' -f1 | sed -e 's/^ *//' -e 's/ *$//') - DEP_NAME=$(echo $line | cut -d'|' -f2 | sed -e 's/^ *//' -e 's/ *$//') - TEST_NAME=${TEST_NAME##*_} - DEP_NAME=${DEP_NAME##*_} - - cd $PATHRT - RUNDIR=$RUNDIR_ROOT/$TEST_NAME - BASELINE=$BASELINE_ROOT/$TEST_NAME - NEW_BASELINE=$NEW_BASELINE_ROOT/$TEST_NAME - DEPDIR=$RUNDIR_ROOT/$DEP_NAME - mkdir -p $RUNDIR - - # OUTDIR_PATH is passed down to $PATHTR/ush/cpld_gridgen.sh - # It MUST be set - export OUTDIR_PATH=$RUNDIR - - if [[ -n $DEP_NAME ]]; then - cp $DEPDIR/Ct.mx025_SCRIP.nc $RUNDIR >/dev/null 2>&1 && d=$? || d=$? - if [[ $d -eq 1 ]]; then - error "DEPDIR $DEPDIR does not exist. Dependency not met" + line="${line#"${line%%[![:space:]]*}"}" + [[ ${#line} == 0 ]] && continue + [[ $line =~ \# ]] && continue + + TEST_NAME=$(echo $line | cut -d'|' -f1 | sed -e 's/^ *//' -e 's/ *$//') + DEP_NAME=$(echo $line | cut -d'|' -f2 | sed -e 's/^ *//' -e 's/ *$//') + MOSAICRES=${TEST_NAME%_*} + TEST_NAME=${TEST_NAME##*_} + DEP_NAME=${DEP_NAME##*_} + + cd $PATHRT + RUNDIR=$RUNDIR_ROOT/$TEST_NAME + BASELINE=$BASELINE_ROOT/$TEST_NAME + NEW_BASELINE=$NEW_BASELINE_ROOT/$TEST_NAME + DEPDIR=$RUNDIR_ROOT/$DEP_NAME + mkdir -p $RUNDIR + + # OUTDIR_PATH is passed down to $PATHTR/ush/cpld_gridgen.sh + # It MUST be set + export OUTDIR_PATH=$RUNDIR + export MOSAICRES=$MOSAICRES + + if [[ -n $DEP_NAME ]]; then + cp $DEPDIR/Ct.mx025_SCRIP.nc $RUNDIR >/dev/null 2>&1 && d=$? || d=$? + if [[ $d -eq 1 ]]; then + error "DEPDIR $DEPDIR does not exist. Dependency not met" + fi fi - fi - cp $PATHTR/exec/cpld_gridgen $RUNDIR - cp $PATHTR/ush/cpld_gridgen.sh $RUNDIR - cp $PATHRT/parm/grid.nml.IN $RUNDIR - cd $RUNDIR + cp $PATHTR/exec/cpld_gridgen $RUNDIR + cp $PATHTR/ush/cpld_gridgen.sh $RUNDIR + cp $PATHRT/parm/grid.nml.IN $RUNDIR + cd $RUNDIR - if [[ $target = wcoss2 ]]; then + if [[ $target = wcoss2 ]]; then -# rm -f $RUNDIR/bad.${TEST_NAME} + # rm -f $RUNDIR/bad.${TEST_NAME} - TEST=$(qsub -V -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log -q $QUEUE -A $ACCOUNT \ - -Wblock=true -l walltime=00:05:00 -N $TEST_NAME -l select=1:ncpus=1:mem=8GB -v RESNAME=$TEST_NAME $SBATCH_COMMAND) + TEST=$(qsub -V -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log -q $QUEUE -A $ACCOUNT \ + -Wblock=true -l walltime=00:${WLCLK}:00 -N $TEST_NAME -l select=1:ncpus=1:mem=12GB -v RESNAME=$TEST_NAME $SBATCH_COMMAND) -# qsub -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log -q $QUEUE -A $ACCOUNT \ -# -Wblock=true -l walltime=00:01:00 -N chgres_summary -l select=1:ncpus=1:mem=100MB -W depend=afternotok:$TEST << EOF -#!/bin/bash -# touch $RUNDIR/bad.${TEST_NAME} -#EOF -# if [[ -f $RUNDIR/bad.${TEST_NAME} ]]; then -# error "Batch job for test $TEST_NAME did not finish successfully. Refer to run_${TEST_NAME}.log" -# fi + # qsub -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log -q $QUEUE -A $ACCOUNT \ + # -Wblock=true -l walltime=00:01:00 -N chgres_summary -l select=1:ncpus=1:mem=100MB -W depend=afternotok:$TEST << EOF + #!/bin/bash + # touch $RUNDIR/bad.${TEST_NAME} + #EOF + # if [[ -f $RUNDIR/bad.${TEST_NAME} ]]; then + # error "Batch job for test $TEST_NAME did not finish successfully. Refer to run_${TEST_NAME}.log" + # fi - else - sbatch --wait --ntasks-per-node=1 --nodes=1 --mem=4G -t 0:05:00 -A $ACCOUNT -q $QUEUE -J $TEST_NAME \ - --partition=$PARTITION -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log \ - --wrap "$SBATCH_COMMAND $TEST_NAME" && d=$? || d=$? + else + sbatch --wait --ntasks-per-node=1 --nodes=1 ${MEM} -t 00:${WLCLK}:00 -A $ACCOUNT -q $QUEUE -J $TEST_NAME \ + --partition=$PARTITION -o $PATHRT/run_${TEST_NAME}.log -e $PATHRT/run_${TEST_NAME}.log \ + --wrap "time $SBATCH_COMMAND $TEST_NAME" && d=$? || d=$? - if [[ d -ne 0 ]]; then - error "Batch job for test $TEST_NAME did not finish successfully. Refer to run_${TEST_NAME}.log" - fi + if [[ d -ne 0 ]]; then + error "Batch job for test $TEST_NAME did not finish successfully. Refer to run_${TEST_NAME}.log" + fi - fi + fi - check_results + check_results done <$TESTS_FILE if [[ $? -ne 0 ]]; then - error "Run test while loop did not finish properly" + error "Run test while loop did not finish properly" fi cd $PATHRT FAIL_FILES="fail_test_*" for file in $FAIL_FILES; do - if [[ -f "$file" ]]; then - cat "$file" >> fail_test - fi + if [[ -f "$file" ]]; then + cat "$file" >> fail_test + fi done if [[ -e fail_test ]]; then - echo | tee -a $REGRESSIONTEST_LOG - for file in fail_test_*; do - cat $file >>$REGRESSIONTEST_LOG - cat $file >>summary.log - done - - echo | tee -a $REGRESSIONTEST_LOG - echo "REGRESSION TEST FAILED" | tee -a $REGRESSIONTEST_LOG + echo | tee -a $REGRESSIONTEST_LOG + for file in fail_test_*; do + cat $file >>$REGRESSIONTEST_LOG + cat $file >>summary.log + done + + echo | tee -a $REGRESSIONTEST_LOG + echo "REGRESSION TEST FAILED" | tee -a $REGRESSIONTEST_LOG else - echo | tee -a $REGRESSIONTEST_LOG - echo "REGRESSION TEST WAS SUCCESSFUL" | tee -a $REGRESSIONTEST_LOG - echo "All tests passed" >>summary.log + echo | tee -a $REGRESSIONTEST_LOG + echo "REGRESSION TEST WAS SUCCESSFUL" | tee -a $REGRESSIONTEST_LOG + echo "All tests passed" >>summary.log fi date >> $REGRESSIONTEST_LOG + +elapsed_time=$( printf '%02dh:%02dm:%02ds\n' $((SECONDS%86400/3600)) $((SECONDS%3600/60)) $((SECONDS%60)) ) +echo "Elapsed time: ${elapsed_time}. Have a nice day!" >> ${REGRESSIONTEST_LOG} +echo "Elapsed time: ${elapsed_time}. Have a nice day!" diff --git a/sorc/cpld_gridgen.fd/angles.F90 b/sorc/cpld_gridgen.fd/angles.F90 index 99d323f3d..31ac0bbcb 100644 --- a/sorc/cpld_gridgen.fd/angles.F90 +++ b/sorc/cpld_gridgen.fd/angles.F90 @@ -14,179 +14,177 @@ module angles use grdvars, only : x,y,xsgp1,ysgp1,sg_maxlat use grdvars, only : latBu,lonBu,lonCt use grdvars, only : angq,anglet - use grdvars, only : mastertask, debug + use grdvars, only : debug implicit none - contains -!> Find the rotation angle on corner grid (Bu) points using the full MOM6 supergrid -!! -!! @author Denise.Worthen@noaa.gov +contains + !> Find the rotation angle on corner grid (Bu) points using the full MOM6 supergrid + !! + !! @author Denise.Worthen@noaa.gov subroutine find_angq ! local variables integer :: i,j,i1,i2,m,n - + ! pole locations on SG integer(int_kind) :: ipolesg(2) - + ! from geolonB fix in MOM6 real(dbl_kind) :: len_lon ! The periodic range of longitudes, usually 360 degrees. real(dbl_kind) :: pi_720deg ! One quarter the conversion factor from degrees to radians. real(dbl_kind) :: lonB(2,2) ! The longitude of a point, shifted to have about the same value. real(dbl_kind) :: lon_scale = 0.0 -!--------------------------------------------------------------------- -! to find angleq on seam, replicate supergrid values across seam -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! to find angleq on seam, replicate supergrid values across seam + !--------------------------------------------------------------------- - angq = 0.0 + angq = 0.0 xsgp1 = 0.0; ysgp1 = 0.0 !pole on supergrid ipolesg = -1 - j = ny + j = ny do i = 1,nx/2 - if(y(i,j) .eq. sg_maxlat)ipolesg(1) = i + if(y(i,j) .eq. sg_maxlat)ipolesg(1) = i enddo do i = nx/2+1,nx - if(y(i,j) .eq. sg_maxlat)ipolesg(2) = i + if(y(i,j) .eq. sg_maxlat)ipolesg(2) = i enddo - if(mastertask .and. debug)print *,'poles found at ',ipolesg + if(debug)print *,'poles found at ',ipolesg xsgp1(:,0:ny) = x(:,0:ny) ysgp1(:,0:ny) = y(:,0:ny) !check do i = ipolesg(1)-5,ipolesg(1)+5 - i2 = ipolesg(2)+(ipolesg(1)-i)+1 - if(mastertask .and. debug)print *,i,i2 + i2 = ipolesg(2)+(ipolesg(1)-i)+1 + if(debug)print *,i,i2 enddo - print * + print * do i = ipolesg(2)-5,ipolesg(2)+5 - i2 = ipolesg(2)+(ipolesg(1)-i)+1 - if(mastertask .and. debug)print *,i,i2 + i2 = ipolesg(2)+(ipolesg(1)-i)+1 + if(debug)print *,i,i2 enddo - + !replicate supergrid across pole do i = 1,nx - i2 = ipolesg(2)+(ipolesg(1)-i) - xsgp1(i,ny+1) = xsgp1(i2,ny) - ysgp1(i,ny+1) = ysgp1(i2,ny) + i2 = ipolesg(2)+(ipolesg(1)-i) + xsgp1(i,ny+1) = xsgp1(i2,ny) + ysgp1(i,ny+1) = ysgp1(i2,ny) enddo - + !check - if(mastertask .and. debug)then - j = ny+1 + j = ny+1 i1 = ipolesg(1); i2 = ipolesg(2)-(ipolesg(1)-i1) - print *,'replicate X across seam on SG' - print *,xsgp1(i1-2,j),xsgp1(i2+2,j) - print *,xsgp1(i1-1,j),xsgp1(i2+1,j) - print *,xsgp1(i1, j),xsgp1(i2, j) - print *,xsgp1(i1+1,j),xsgp1(i2-1,j) - print *,xsgp1(i1+2,j),xsgp1(i2-2,j) - - print *,'replicate Y across seam on SG' - print *,ysgp1(i1-2,j),ysgp1(i2+2,j) - print *,ysgp1(i1-1,j),ysgp1(i2+1,j) - print *,ysgp1(i1, j),ysgp1(i2, j) - print *,ysgp1(i1+1,j),ysgp1(i2-1,j) - print *,ysgp1(i1+2,j),ysgp1(i2-2,j) - end if - -!--------------------------------------------------------------------- -! rotation angle on supergrid vertices -! lonB: x(i-1,j-1) has same relationship to x(i,j) on SG as -! geolonT(i,j) has to geolonBu(i,j) on the reduced grid -!--------------------------------------------------------------------- - - ! constants as defined in MOM - pi_720deg = atan(1.0) / 180.0 - len_lon = 360.0 + print *,'replicate X across seam on SG' + print *,xsgp1(i1-2,j),xsgp1(i2+2,j) + print *,xsgp1(i1-1,j),xsgp1(i2+1,j) + print *,xsgp1(i1, j),xsgp1(i2, j) + print *,xsgp1(i1+1,j),xsgp1(i2-1,j) + print *,xsgp1(i1+2,j),xsgp1(i2-2,j) + + print *,'replicate Y across seam on SG' + print *,ysgp1(i1-2,j),ysgp1(i2+2,j) + print *,ysgp1(i1-1,j),ysgp1(i2+1,j) + print *,ysgp1(i1, j),ysgp1(i2, j) + print *,ysgp1(i1+1,j),ysgp1(i2-1,j) + print *,ysgp1(i1+2,j),ysgp1(i2-2,j) + + !--------------------------------------------------------------------- + ! rotation angle on supergrid vertices + ! lonB: x(i-1,j-1) has same relationship to x(i,j) on SG as + ! geolonT(i,j) has to geolonBu(i,j) on the reduced grid + !--------------------------------------------------------------------- + + ! constants as defined in MOM + pi_720deg = atan(1.0) / 180.0 + len_lon = 360.0 do j=1,ny ; do i=1,nx-1 - do n=1,2 ; do m=1,2 - lonB(m,n) = modulo_around_point(xsgp1(I+m-2,J+n-2), xsgp1(i-1,j-1), len_lon) - enddo ; enddo - lon_scale = cos(pi_720deg*(ysgp1(i-1,j-1) + ysgp1(i+1,j-1) + & - ysgp1(i-1,j+1) + ysgp1(i+1,j+1)) ) - angq(i,j) = atan2(lon_scale*((lonB(1,2) - lonB(2,1)) + (lonB(2,2) - lonB(1,1))), & - ysgp1(i-1,j+1) + ysgp1(i+1,j+1) - & - ysgp1(i-1,j-1) - ysgp1(i+1,j-1) ) - enddo ; enddo + do n=1,2 ; do m=1,2 + lonB(m,n) = modulo_around_point(xsgp1(I+m-2,J+n-2), xsgp1(i-1,j-1), len_lon) + enddo; enddo + lon_scale = cos(pi_720deg*(ysgp1(i-1,j-1) + ysgp1(i+1,j-1) + & + ysgp1(i-1,j+1) + ysgp1(i+1,j+1)) ) + angq(i,j) = atan2(lon_scale*((lonB(1,2) - lonB(2,1)) + (lonB(2,2) - lonB(1,1))), & + ysgp1(i-1,j+1) + ysgp1(i+1,j+1) - & + ysgp1(i-1,j-1) - ysgp1(i+1,j-1) ) + enddo; enddo !check - if(mastertask .and. debug) then + if(debug) then j = ny - i1 = ipolesg(1); i2 = ipolesg(2)-(ipolesg(1)-i1) - print *,'angq along seam on SG' - print *,angq(i1-2,j),angq(i2+2,j) - print *,angq(i1-1,j),angq(i2+1,j) - print *,angq(i1, j),angq(i2, j) - print *,angq(i1+1,j),angq(i2-1,j) - print *,angq(i1+2,j),angq(i2-2,j) + i1 = ipolesg(1); i2 = ipolesg(2)-(ipolesg(1)-i1) + print *,'angq along seam on SG' + print *,angq(i1-2,j),angq(i2+2,j) + print *,angq(i1-1,j),angq(i2+1,j) + print *,angq(i1, j),angq(i2, j) + print *,angq(i1+1,j),angq(i2-1,j) + print *,angq(i1+2,j),angq(i2-2,j) end if end subroutine find_angq -!> Find the rotation angle on center (Ct) grid points -!! -!! @author Denise.Worthen@noaa.gov + !> Find the rotation angle on center (Ct) grid points + !! + !! @author Denise.Worthen@noaa.gov subroutine find_ang ! local variables integer :: i,j,m,n integer :: ii,jj - + ! from geolonB fix in MOM6 real(dbl_kind) :: len_lon ! The periodic range of longitudes, usually 360 degrees. real(dbl_kind) :: pi_720deg ! One quarter the conversion factor from degrees to radians. real(dbl_kind) :: lonB(2,2) ! The longitude of a point, shifted to have about the same value. real(dbl_kind) :: lon_scale = 0.0 - -!--------------------------------------------------------------------- -! rotation angle for "use_bugs" = false case from MOM6 -! src/initialization/MOM_shared_initialization.F90 but allow for not -! having halo values -! note this does not reproduce sin_rot,cos_rot found in MOM6 output -! differences are ~O 10-6 -!--------------------------------------------------------------------- - - anglet = 0.0 - pi_720deg = atan(1.0) / 180.0 - len_lon = 360.0 - do j=1,nj; do i = 1,ni - do n=1,2 ; do m=1,2 - jj = J+n-2; ii = I+m-2 - if(jj .eq. 0)jj = 1 - if(ii .eq. 0)ii = ni + + !--------------------------------------------------------------------- + ! rotation angle for "use_bugs" = false case from MOM6 + ! src/initialization/MOM_shared_initialization.F90 but allow for not + ! having halo values + ! note this does not reproduce sin_rot,cos_rot found in MOM6 output + ! differences are ~O 10-6 + !--------------------------------------------------------------------- + + anglet = 0.0 + pi_720deg = atan(1.0) / 180.0 + len_lon = 360.0 + do j=1,nj; do i = 1,ni + do n=1,2 ; do m=1,2 + jj = J+n-2; ii = I+m-2 + if(jj .eq. 0)jj = 1 + if(ii .eq. 0)ii = ni lonB(m,n) = modulo_around_point(LonBu(ii,jj), LonCt(i,j), len_lon) - ! lonB(m,n) = modulo_around_point(LonBu(I+m-2,J+n-2), LonCt(i,j), len_lon) - enddo ; enddo - jj = j-1; ii = i-1 - if(jj .eq. 0)jj = 1 - if(ii .eq. 0)ii = ni - lon_scale = cos(pi_720deg*((LatBu(ii,jj) + LatBu(I,J)) + & - (LatBu(I,jj) + LatBu(ii,J)) ) ) + ! lonB(m,n) = modulo_around_point(LonBu(I+m-2,J+n-2), LonCt(i,j), len_lon) + enddo; enddo + jj = j-1; ii = i-1 + if(jj .eq. 0)jj = 1 + if(ii .eq. 0)ii = ni + lon_scale = cos(pi_720deg*((LatBu(ii,jj) + LatBu(I,J)) + & + (LatBu(I,jj) + LatBu(ii,J)) ) ) anglet(i,j) = atan2(lon_scale*((lonB(1,2) - lonB(2,1)) + (lonB(2,2) - lonB(1,1))), & - (LatBu(ii,J) - LatBu(I,jj)) + & - (LatBu(I,J) - LatBu(ii,jj)) ) - - !lon_scale = cos(pi_720deg*((LatBu(I-1,J-1) + LatBu(I,J)) + & - ! (LatBu(I,J-1) + LatBu(I-1,J)) ) ) + (LatBu(ii,J) - LatBu(I,jj)) + & + (LatBu(I,J) - LatBu(ii,jj)) ) + + !lon_scale = cos(pi_720deg*((LatBu(I-1,J-1) + LatBu(I,J)) + & + ! (LatBu(I,J-1) + LatBu(I-1,J)) ) ) !anglet(i,j) = atan2(lon_scale*((lonB(1,2) - lonB(2,1)) + (lonB(2,2) - lonB(1,1))), & ! (LatBu(I-1,J) - LatBu(I,J-1)) + & ! (LatBu(I,J) - LatBu(I-1,J-1)) ) - enddo ; enddo + enddo; enddo end subroutine find_ang -! ----------------------------------------------------------------------------- -!> Return the modulo value of x in an interval [xc-(Lx/2) xc+(Lx/2)] -!! If Lx<=0, then it returns x without applying modulo arithmetic. -!! -!! From src/initialization/MOM_shared_initialization.F90: -!! @param[in] x Value to which to apply modulo arithmetic -!! @param[in] xc Center of modulo range -!! @param[in] Lx Modulo range width -!! @return x_mod Value x shifted by an integer multiple of Lx to be close to xc + ! ----------------------------------------------------------------------------- + !> Return the modulo value of x in an interval [xc-(Lx/2) xc+(Lx/2)] + !! If Lx<=0, then it returns x without applying modulo arithmetic. + !! + !! From src/initialization/MOM_shared_initialization.F90: + !! @param[in] x Value to which to apply modulo arithmetic + !! @param[in] xc Center of modulo range + !! @param[in] Lx Modulo range width + !! @return x_mod Value x shifted by an integer multiple of Lx to be close to xc function modulo_around_point(x, xc, Lx) result(x_mod) use gengrid_kinds, only : dbl_kind @@ -196,9 +194,9 @@ function modulo_around_point(x, xc, Lx) result(x_mod) real(dbl_kind) :: x_mod if (Lx > 0.0) then - x_mod = modulo(x - (xc - 0.5*Lx), Lx) + (xc - 0.5*Lx) + x_mod = modulo(x - (xc - 0.5*Lx), Lx) + (xc - 0.5*Lx) else - x_mod = x + x_mod = x endif end function modulo_around_point end module angles diff --git a/sorc/cpld_gridgen.fd/charstrings.F90 b/sorc/cpld_gridgen.fd/charstrings.F90 index 93c6b304c..00deab1b4 100644 --- a/sorc/cpld_gridgen.fd/charstrings.F90 +++ b/sorc/cpld_gridgen.fd/charstrings.F90 @@ -14,8 +14,8 @@ module charstrings character(len=CL) :: dirsrc !< The source directory containing the fix files for MOM6 character(len=CL) :: dirout !< The directory where output files will be written character(len=CL) :: fv3dir !< The directory containing the FV3 mosaic files - character(len=CS) :: res !< The Ocean/Ice resolution, e.g. 100 (1deg), 050 (1/2deg), - !! 025 (1/4deg) + character(len=CS) :: res !< The Ocean/Ice resolution, e.g. 500 (5deg), 100 (1deg) + !! 050 (1/2deg), 025 (1/4deg) character(len=CS) :: atmres !< The ATM resolution, e.g. C96, C192, C384 character(len=CL) :: logmsg !< An informational message diff --git a/sorc/cpld_gridgen.fd/cicegrid.F90 b/sorc/cpld_gridgen.fd/cicegrid.F90 index aaca257da..bd7c366f2 100644 --- a/sorc/cpld_gridgen.fd/cicegrid.F90 +++ b/sorc/cpld_gridgen.fd/cicegrid.F90 @@ -7,7 +7,7 @@ module cicegrid - use grdvars, only: ni,nj,ulat,ulon,htn,hte,angle,wet4,mastertask + use grdvars, only: ni,nj,ulat,ulon,htn,hte,angle,wet4 use charstrings, only: history, logmsg use vartypedefs, only: maxvars, cicevars, cicevars_typedefine use gengrid_kinds, only: CM @@ -18,80 +18,78 @@ module cicegrid public write_cicegrid - contains -!> Write the CICE6 grid file -!! -!! @param[in] fname the name of the CICE6 grid file to write -!! -!! @author Denise.Worthen@noaa.gov - +contains + !> Write the CICE6 grid file + !! + !! @param[in] fname the name of the CICE6 grid file to write + !! + !! @author Denise.Worthen@noaa.gov + subroutine write_cicegrid(fname) - character(len=*), intent(in) :: fname + character(len=*), intent(in) :: fname - ! local variables - integer :: ii,id,rc, ncid, dim2(2) - integer :: idimid,jdimid + ! local variables + integer :: ii,id,rc, ncid, dim2(2) + integer :: idimid,jdimid - character(len=2) :: vtype - character(len=CM) :: vname - character(len=CM) :: vlong - character(len=CM) :: vunit + character(len=2) :: vtype + character(len=CM) :: vname + character(len=CM) :: vlong + character(len=CM) :: vunit -!--------------------------------------------------------------------- -! create the netcdf file -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! create the netcdf file + !--------------------------------------------------------------------- - ! define the output variables and file name - call cicevars_typedefine + ! define the output variables and file name + call cicevars_typedefine - rc = nf90_create(fname, nf90_write, ncid) - if(mastertask) then + rc = nf90_create(fname, nf90_write, ncid) logmsg = '==> writing CICE grid to '//trim(fname) print '(a)', trim(logmsg) if(rc .ne. 0)print '(a)', 'nf90_create = '//trim(nf90_strerror(rc)) - end if - - rc = nf90_def_dim(ncid, 'ni', ni, idimid) - rc = nf90_def_dim(ncid, 'nj', nj, jdimid) - - do ii = 1,maxvars - if(len_trim(cicevars(ii)%var_name) .gt. 0)then - vname = trim(cicevars(ii)%var_name) - vlong = trim(cicevars(ii)%long_name) - vunit = trim(cicevars(ii)%unit_name) - vtype = trim(cicevars(ii)%var_type) - - dim2(:) = (/idimid, jdimid/) - if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) - if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim2, id) - if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim2, id) - rc = nf90_put_att(ncid, id, 'units', vunit) - rc = nf90_put_att(ncid, id, 'long_name', vlong) - end if - enddo - rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) - rc = nf90_enddef(ncid) - - rc = nf90_inq_varid(ncid, 'ulon', id) - rc = nf90_put_var(ncid, id, ulon) - - rc = nf90_inq_varid(ncid, 'ulat', id) - rc = nf90_put_var(ncid, id, ulat) - - rc = nf90_inq_varid(ncid, 'htn', id) - rc = nf90_put_var(ncid, id, htn) - - rc = nf90_inq_varid(ncid, 'hte', id) - rc = nf90_put_var(ncid, id, hte) - - rc = nf90_inq_varid(ncid, 'angle', id) - rc = nf90_put_var(ncid, id, angle) - - rc = nf90_inq_varid(ncid, 'kmt', id) - rc = nf90_put_var(ncid, id, int(wet4)) - - rc = nf90_close(ncid) + + rc = nf90_def_dim(ncid, 'ni', ni, idimid) + rc = nf90_def_dim(ncid, 'nj', nj, jdimid) + + do ii = 1,maxvars + if(len_trim(cicevars(ii)%var_name) .gt. 0)then + vname = trim(cicevars(ii)%var_name) + vlong = trim(cicevars(ii)%long_name) + vunit = trim(cicevars(ii)%unit_name) + vtype = trim(cicevars(ii)%var_type) + + dim2(:) = (/idimid, jdimid/) + if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) + if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim2, id) + if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim2, id) + rc = nf90_put_att(ncid, id, 'units', vunit) + rc = nf90_put_att(ncid, id, 'long_name', vlong) + end if + enddo + rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) + rc = nf90_enddef(ncid) + + rc = nf90_inq_varid(ncid, 'ulon', id) + rc = nf90_put_var(ncid, id, ulon) + + rc = nf90_inq_varid(ncid, 'ulat', id) + rc = nf90_put_var(ncid, id, ulat) + + rc = nf90_inq_varid(ncid, 'htn', id) + rc = nf90_put_var(ncid, id, htn) + + rc = nf90_inq_varid(ncid, 'hte', id) + rc = nf90_put_var(ncid, id, hte) + + rc = nf90_inq_varid(ncid, 'angle', id) + rc = nf90_put_var(ncid, id, angle) + + rc = nf90_inq_varid(ncid, 'kmt', id) + rc = nf90_put_var(ncid, id, int(wet4)) + + rc = nf90_close(ncid) end subroutine write_cicegrid end module cicegrid diff --git a/sorc/cpld_gridgen.fd/debugprint.F90 b/sorc/cpld_gridgen.fd/debugprint.F90 index 93f0d98b9..71b9c289a 100644 --- a/sorc/cpld_gridgen.fd/debugprint.F90 +++ b/sorc/cpld_gridgen.fd/debugprint.F90 @@ -18,22 +18,22 @@ module debugprint private public :: checkseam, checkxlatlon, checkpoint - - contains -!> Print values across the tripole seam -!! -!! @author Denise.Worthen@noaa.gov - + +contains + !> Print values across the tripole seam + !! + !! @author Denise.Worthen@noaa.gov + subroutine checkseam - ! local variables - integer :: j,i1,i2 + ! local variables + integer :: j,i1,i2 j = nj i1 = ipole(1); i2 = ipole(2)+1 !htn must be the same along seam - j = nj + j = nj i1 = ipole(1); i2 = ipole(2)+1 print *,'HTN across seam ' print *,htn(i1-2,j),htn(i2+2,j) @@ -41,21 +41,21 @@ subroutine checkseam print *,htn(i1, j),htn(i2, j) print *,htn(i1+1,j),htn(i2-1,j) print *,htn(i1+2,j),htn(i2-2,j) - + print *,'latCv across seam ' print *,latCv(i1-2,j),latCv(i2+2,j) print *,latCv(i1-1,j),latCv(i2+1,j) print *,latCv(i1, j),latCv(i2, j) print *,latCv(i1+1,j),latCv(i2-1,j) print *,latCv(i1+2,j),latCv(i2-2,j) - + print *,'lonCv across seam ' print *,lonCv(i1-2,j),lonCv(i2+2,j) print *,lonCv(i1-1,j),lonCv(i2+1,j) print *,lonCv(i1, j),lonCv(i2, j) print *,lonCv(i1+1,j),lonCv(i2-1,j) print *,lonCv(i1+2,j),lonCv(i2-2,j) - + print *,'angleT across seam ' print *,angleT(i1-2,j),angleT(i2+2,j) print *,angleT(i1-1,j),angleT(i2+1,j) @@ -100,38 +100,38 @@ subroutine checkseam print *,lonCt(i1+3,j),lonCt(i2-3,j) print * end subroutine checkseam - + !> Print values near the poles and along the domain edges !! !! @author Denise.Worthen@noaa.gov - + subroutine checkxlatlon - - ! local variables - integer :: i + + ! local variables + integer :: i print *,'============== Ct grid ===============' print *,'============== Left pole ============' do i = ipole(1)-3,ipole(1)+3 - print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) + print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) enddo print * print *,'============ Right pole ============' do i = ipole(2)-3,ipole(2)+3 - print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) + print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) enddo print * print *,'============== Ct grid ===============' print *,'============== Left edge ============' do i = 1,5 - print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) + print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) enddo print * print *,'============== Right edge ===========' do i = ni-4,ni - print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) + print '(i5,6f12.5)',i,lonCt(i,nj),xlonCt(i),lonCt(i,nj)+xlonCt(i),latCt(i,nj),xlatCt(i),latCt(i,nj)-xlatCt(i) enddo print * @@ -139,38 +139,38 @@ subroutine checkxlatlon print *,'============== Cu grid ===============' print *,'============== Left pole =============' do i = ipole(1)-3,ipole(1)+3 - print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) + print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) enddo print * print *,'============ Right pole ============' do i = ipole(2)-3,ipole(2)+3 - print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) + print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) enddo print * print *,'============== Cu grid ===============' print *,'============== Left edge ============' do i = 1,5 - print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) + print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) enddo print * print *,'============== Right edge ===========' do i = ni-4,ni - print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) + print '(i5,6f12.5)',i,lonCu(i,nj),xlonCu(i),lonCu(i,nj)+xlonCu(i),latCu(i,nj),xlatCu(i),latCu(i,nj)-xlatCu(i) enddo print * end subroutine checkxlatlon - -!> Print values at specified point -!! -!! @author Denise.Worthen@noaa.gov - + + !> Print values at specified point + !! + !! @author Denise.Worthen@noaa.gov + subroutine checkpoint - ! local variables - integer :: i,j + ! local variables + integer :: i,j ! check i = 1; j = nj @@ -183,7 +183,7 @@ subroutine checkpoint print '(f12.5,a,f12.5)',lonBu_vert(i,j,3),' ',lonBu_vert(i,j,4) print * print * - ! check + ! check print '(f12.5,a,f12.5)',latCv_vert(i,j,2),' ',latCv_vert(i,j,1) print '(a12,f12.5)',' ',latCv(i,j) print '(f12.5,a,f12.5)',latCv_vert(i,j,3),' ',latCv_vert(i,j,4) @@ -239,9 +239,9 @@ subroutine checkpoint print *,"latCv minmax ",minval(latCv),maxval(latCv) print *,"latBu minmax ",minval(latBu),maxval(latBu) - ! print *,minval(latCt_vert),maxval(latCt_vert) - ! print *,minval(lonCt_vert),maxval(lonCt_vert) - ! print *,minval(latBu_vert),maxval(latBu_vert) - ! print *,minval(lonBu_vert),maxval(lonBu_vert) + ! print *,minval(latCt_vert),maxval(latCt_vert) + ! print *,minval(lonCt_vert),maxval(lonCt_vert) + ! print *,minval(latBu_vert),maxval(latBu_vert) + ! print *,minval(lonBu_vert),maxval(lonBu_vert) end subroutine checkpoint end module debugprint diff --git a/sorc/cpld_gridgen.fd/gen_fixgrid.F90 b/sorc/cpld_gridgen.fd/gen_fixgrid.F90 index 5d1b2d72b..2fcffb126 100644 --- a/sorc/cpld_gridgen.fd/gen_fixgrid.F90 +++ b/sorc/cpld_gridgen.fd/gen_fixgrid.F90 @@ -4,7 +4,7 @@ !! @author Denise.Worthen@noaa.gov !> Generate fixed grid files required for coupled model using the MOM6 super grid file and ocean mask file. It creates -!! a master grid file which is then used to create subsequent files which are required to create the fix and IC +!! a main grid file which is then used to create subsequent files which are required to create the fix and IC !! files required for the S2S or S2SW application. !! !! This executable created with this source code runs within the shell scrip cpld_gridgen.sh in ../../ush, which @@ -41,7 +41,7 @@ program gen_fixgrid real(kind=dbl_kind), parameter :: pi = 3.14159265358979323846_dbl_kind real(kind=dbl_kind), parameter :: deg2rad = pi/180.0_dbl_kind - real(real_kind), allocatable, dimension(:,:) :: ww3dpth + real(real_kind), allocatable, dimension(:,:) :: ww3dpth integer(int_kind), allocatable, dimension(:,:) :: ww3mask character(len=CL) :: fsrc, fdst, fwgt @@ -61,88 +61,82 @@ program gen_fixgrid character(len=CS) :: form1 character(len=CS) :: form2 character(len= 6) :: cnx - -!------------------------------------------------------------------------- -! Initialize esmf environment. -!------------------------------------------------------------------------- - - call ESMF_VMGetGlobal(vm, rc=rc) - call ESMF_Initialize(VM=vm, logkindflag=ESMF_LOGKIND_MULTI, rc=rc) - call ESMF_VMGet(vm, localPet=localPet, peCount=nPet, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) - mastertask = .false. - if (localPet == 0) mastertask=.true. - if (nPet /= 1) then - print *,npet,' More than one task specified; Aborting ' - call ESMF_Finalize(endflag=ESMF_END_ABORT) - end if - -!--------------------------------------------------------------------- -! -!--------------------------------------------------------------------- + + !------------------------------------------------------------------------- + ! Initialize esmf environment. + !------------------------------------------------------------------------- + + call ESMF_VMGetGlobal(vm, rc=rc) + call ESMF_Initialize(VM=vm, logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + call ESMF_VMGet(vm, localPet=localPet, peCount=nPet, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) + roottask = .false. + if (localPet == 0) roottask =.true. + if (nPet /= 1) then + print *,npet,' More than one task specified; Aborting ' + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + + !--------------------------------------------------------------------- + ! + !--------------------------------------------------------------------- call read_inputnml('grid.nml') - if(mastertask) then - print '(a,2i6)',' output grid requested ',ni,nj - print '(a,2i6)',' supergrid size used ', nx,ny - print '(a)',' output grid tag '//trim(res) - print '(a)',' supergrid source directory '//trim(dirsrc) - print '(a)',' output grid directory '//trim(dirout) - print '(a)',' atm resolution '//trim(atmres) - print '(a,i6)',' fv3 tile grid size ',npx - print '(a)',' atm mosaic directory '//trim(fv3dir) - print '(a)',' MOM6 topography file '//trim(topofile) - print '(a)',' MOM6 edits file '//trim(editsfile) - print *,'editmask flag ',editmask - print *,'debug flag ',debug - print *,'do_postwgts flag ',do_postwgts - print * - end if + print '(a,2i6)',' output grid requested ',ni,nj + print '(a,2i6)',' supergrid size used ', nx,ny + print '(a)',' output grid tag '//trim(res) + print '(a)',' supergrid source directory '//trim(dirsrc) + print '(a)',' output grid directory '//trim(dirout) + print '(a)',' atm resolution '//trim(atmres) + print '(a,i6)',' fv3 tile grid size ',npx + print '(a)',' atm mosaic directory '//trim(fv3dir) + print '(a)',' MOM6 topography file '//trim(topofile) + print '(a)',' MOM6 edits file '//trim(editsfile) + print *,'editmask flag ',editmask + print *,'debug flag ',debug + print *,'do_postwgts flag ',do_postwgts + print * call allocate_all - + call ESMF_LogWrite("Starting gen_fixgrid", ESMF_LOGMSG_INFO) -!--------------------------------------------------------------------- -! set up the arrays to retrieve the vertices -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! set up the arrays to retrieve the vertices + !--------------------------------------------------------------------- iVertCu = iVertCt + 1; jVertCu = jVertCt + 0 iVertCv = iVertCt + 0; jVertCv = jVertCt + 1 iVertBu = iVertCt + 1; jVertBu = jVertCt + 1 - if(mastertask) then - print '(a8,4i6)','iVertCt ',(iVertCt(i),i=1,4) - print '(a8,4i6)','jVertCt ',(jVertCt(i),i=1,4) - print * - print '(a8,4i6)','iVertCu ',(iVertCu(i),i=1,4) - print '(a8,4i6)','jVertCu ',(jVertCu(i),i=1,4) - print * - print '(a8,4i6)','iVertCv ',(iVertCv(i),i=1,4) - print '(a8,4i6)','jVertCv ',(jVertCv(i),i=1,4) - print * - print '(a8,4i6)','iVertBu ',(iVertBu(i),i=1,4) - print '(a8,4i6)','jVertBu ',(jVertBu(i),i=1,4) - print * - end if + print '(a8,4i6)','iVertCt ',(iVertCt(i),i=1,4) + print '(a8,4i6)','jVertCt ',(jVertCt(i),i=1,4) + print * + print '(a8,4i6)','iVertCu ',(iVertCu(i),i=1,4) + print '(a8,4i6)','jVertCu ',(jVertCu(i),i=1,4) + print * + print '(a8,4i6)','iVertCv ',(iVertCv(i),i=1,4) + print '(a8,4i6)','jVertCv ',(jVertCv(i),i=1,4) + print * + print '(a8,4i6)','iVertBu ',(iVertBu(i),i=1,4) + print '(a8,4i6)','jVertBu ',(jVertBu(i),i=1,4) + print * latCt_vert = -9999.0 ; lonCt_vert = -9999.0 latCu_vert = -9999.0 ; lonCu_vert = -9999.0 latCv_vert = -9999.0 ; lonCv_vert = -9999.0 latBu_vert = -9999.0 ; lonBu_vert = -9999.0 -!--------------------------------------------------------------------- -! read the MOM6 land mask -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! read the MOM6 land mask + !--------------------------------------------------------------------- fsrc = trim(dirsrc)//'/'//trim(maskfile) rc = nf90_open(fsrc, nf90_nowrite, ncid) - if(mastertask) then - print '(a)', 'reading ocean mask from '//trim(fsrc) - if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) - end if + print '(a)', 'reading ocean mask from '//trim(fsrc) + if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) wet4 = 0.0; wet8 = 0.0 rc = nf90_inq_varid(ncid, trim(maskname), id) @@ -156,17 +150,15 @@ program gen_fixgrid !print *,minval(wet8),maxval(wet8) !print *,minval(wet4),maxval(wet4) -!--------------------------------------------------------------------- -! read the MOM6 depth file -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! read the MOM6 depth file + !--------------------------------------------------------------------- fsrc = trim(dirsrc)//'/'//trim(topofile) rc = nf90_open(fsrc, nf90_nowrite, ncid) - if(mastertask) then - print '(a)', 'reading ocean topography from '//trim(fsrc) - if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) - end if + print '(a)', 'reading ocean topography from '//trim(fsrc) + if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) dp4 = 0.0; dp8 = 0.0 rc = nf90_inq_varid(ncid, trim(toponame), id) @@ -181,45 +173,43 @@ program gen_fixgrid !print *,minval(dp4),maxval(dp4) if(editmask)then -!--------------------------------------------------------------------- -! apply topoedits run time mask changes if required for this config -!--------------------------------------------------------------------- - - if(trim(editsfile) == 'none')then - print '(a)', 'Need a valid editsfile to make mask edits ' - stop - end if - - fsrc = trim(dirsrc)//'/'//trim(editsfile) - fdst = trim(dirout)//'/'//'ufs.'//trim(editsfile) - call add_topoedits(fsrc,fdst) + !--------------------------------------------------------------------- + ! apply topoedits run time mask changes if required for this config + !--------------------------------------------------------------------- + + if(trim(editsfile) == 'none')then + print '(a)', 'Need a valid editsfile to make mask edits ' + stop + end if + + fsrc = trim(dirsrc)//'/'//trim(editsfile) + fdst = trim(dirout)//'/'//'ufs.'//trim(editsfile) + call add_topoedits(fsrc,fdst) endif -!--------------------------------------------------------------------- -! MOM6 reads the depth file, applies the topo edits and then adjusts -! depth using masking_depth and min/max depth. This call mimics -! MOM6 routines apply_topography_edits_from_file and limit_topography -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! MOM6 reads the depth file, applies the topo edits and then adjusts + ! depth using masking_depth and min/max depth. This call mimics + ! MOM6 routines apply_topography_edits_from_file and limit_topography + !--------------------------------------------------------------------- - fsrc = trim(dirsrc)//'/'//trim(editsfile) - if(editmask)fsrc = trim(dirout)//'/'//'ufs.'//trim(editsfile) - call apply_topoedits(fsrc) + fsrc = trim(dirsrc)//'/'//trim(editsfile) + if(editmask)fsrc = trim(dirout)//'/'//'ufs.'//trim(editsfile) + call apply_topoedits(fsrc) -!--------------------------------------------------------------------- -! read MOM6 supergrid file -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! read MOM6 supergrid file + !--------------------------------------------------------------------- fsrc = trim(dirsrc)//'/'//'ocean_hgrid.nc' rc = nf90_open(fsrc, nf90_nowrite, ncid) - if(mastertask) then - print '(a)', 'reading supergrid from '//trim(fsrc) - if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) - end if - + print '(a)', 'reading supergrid from '//trim(fsrc) + if(rc .ne. 0)print '(a)', 'nf90_open = '//trim(nf90_strerror(rc)) + rc = nf90_inq_varid(ncid, 'x', id) !lon rc = nf90_get_var(ncid, id, x) - + rc = nf90_inq_varid(ncid, 'y', id) !lat rc = nf90_get_var(ncid, id, y) @@ -234,136 +224,127 @@ program gen_fixgrid !print *,'max lat in super grid ',maxval(y) sg_maxlat = maxval(y) -!--------------------------------------------------------------------- -! find the angle on corners---this requires the supergrid -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! find the angle on corners---this requires the supergrid + !--------------------------------------------------------------------- - call find_angq + call find_angq -!--------------------------------------------------------------------- -! fill grid variables -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! fill grid variables + !--------------------------------------------------------------------- do j = 1,nj - do i = 1,ni - i2 = 2*i ; j2 = 2*j - !deg->rad - ulon(i,j) = x(i2,j2)*deg2rad - ulat(i,j) = y(i2,j2)*deg2rad - !in rad already - angle(i,j) = -angq(i2,j2) - !m->cm - htn(i,j) = (dx(i2-1,j2) + dx(i2,j2))*100._dbl_kind - hte(i,j) = (dy(i2,j2-1) + dy(i2,j2))*100._dbl_kind - !deg - lonBu(i,j) = x(i2,j2) - latBu(i,j) = y(i2,j2) - !deg - lonCt(i,j) = x(i2-1,j2-1) - lonCu(i,j) = x(i2, j2-1) - lonCv(i,j) = x(i2-1,j2 ) - !deg - latCt(i,j) = y(i2-1,j2-1) - latCu(i,j) = y(i2, j2-1) - latCv(i,j) = y(i2-1,j2 ) - !m2 - dxT = dx(i2-1,j2-1) + dx(i2,j2-1) - dyT = dy(i2-1,j2-1) + dy(i2-1,j2) - areaCt(i,j) = dxT*dyT - enddo + do i = 1,ni + i2 = 2*i ; j2 = 2*j + !deg->rad + ulon(i,j) = x(i2,j2)*deg2rad + ulat(i,j) = y(i2,j2)*deg2rad + !in rad already + angle(i,j) = -angq(i2,j2) + !m->cm + htn(i,j) = (dx(i2-1,j2) + dx(i2,j2))*100._dbl_kind + hte(i,j) = (dy(i2,j2-1) + dy(i2,j2))*100._dbl_kind + !deg + lonBu(i,j) = x(i2,j2) + latBu(i,j) = y(i2,j2) + !deg + lonCt(i,j) = x(i2-1,j2-1) + lonCu(i,j) = x(i2, j2-1) + lonCv(i,j) = x(i2-1,j2 ) + !deg + latCt(i,j) = y(i2-1,j2-1) + latCu(i,j) = y(i2, j2-1) + latCv(i,j) = y(i2-1,j2 ) + !m2 + dxT = dx(i2-1,j2-1) + dx(i2,j2-1) + dyT = dy(i2-1,j2-1) + dy(i2-1,j2) + areaCt(i,j) = dxT*dyT + enddo enddo -!--------------------------------------------------------------------- -! find the angle on centers---this does not requires the supergrid -!--------------------------------------------------------------------- - - call find_ang - - if(mastertask) then - print *,'ANGLET ',minval(anglet),maxval(anglet) - print *,'ANGLE ',minval(angle),maxval(angle) - end if - -!--------------------------------------------------------------------- -! For the 1/4deg grid, hte at j=720 and j = 1440 is identically=0.0 for -! j > 840 (64.0N). These are land points, but since CICE uses hte to -! generate remaining variables, setting them to zero will cause problems -! For 1deg grid, hte at ni/2 and ni are very small O~10-12, so test for -! hte < 1.0 -!--------------------------------------------------------------------- - - if(mastertask) then - write(logmsg,'(a,2e12.5)')'min vals of hte at folds ', & - minval(hte(ni/2,:)),minval(hte(ni,:)) - print '(a)',trim(logmsg) - end if - do j = 1,nj - ii = ni/2 - if(hte(ii,j) .le. 1.0)hte(ii,j) = 0.5*(hte(ii-1,j) + hte(ii+1,j)) - ii = ni - if(hte(ii,j) .le. 1.0)hte(ii,j) = 0.5*(hte(ii-1,j) + hte( 1,j)) - enddo - if(mastertask) then - write(logmsg,'(a,2e12.5)')'min vals of hte at folds ', & - minval(hte(ni/2,:)),minval(hte(ni,:)) - print '(a)',trim(logmsg) - end if + !--------------------------------------------------------------------- + ! find the angle on centers---this does not requires the supergrid + !--------------------------------------------------------------------- + + call find_ang + print *,'ANGLET ',minval(anglet),maxval(anglet) + print *,'ANGLE ',minval(angle),maxval(angle) + + !--------------------------------------------------------------------- + ! For the 1/4deg grid, hte at j=720 and j = 1440 is identically=0.0 for + ! j > 840 (64.0N). These are land points, but since CICE uses hte to + ! generate remaining variables, setting them to zero will cause problems + ! For 1deg grid, hte at ni/2 and ni are very small O~10-12, so test for + ! hte < 1.0 + !--------------------------------------------------------------------- + + write(logmsg,'(a,2e12.5)')'min vals of hte at folds ', & + minval(hte(ni/2,:)),minval(hte(ni,:)) + print '(a)',trim(logmsg) + do j = 1,nj + ii = ni/2 + if(hte(ii,j) .le. 1.0)hte(ii,j) = 0.5*(hte(ii-1,j) + hte(ii+1,j)) + ii = ni + if(hte(ii,j) .le. 1.0)hte(ii,j) = 0.5*(hte(ii-1,j) + hte( 1,j)) + enddo + write(logmsg,'(a,2e12.5)')'min vals of hte at folds ', & + minval(hte(ni/2,:)),minval(hte(ni,:)) + print '(a)',trim(logmsg) -!--------------------------------------------------------------------- -! -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! + !--------------------------------------------------------------------- where(lonCt .lt. 0.0)lonCt = lonCt + 360._dbl_kind where(lonCu .lt. 0.0)lonCu = lonCu + 360._dbl_kind where(lonCv .lt. 0.0)lonCv = lonCv + 360._dbl_kind where(lonBu .lt. 0.0)lonBu = lonBu + 360._dbl_kind -!--------------------------------------------------------------------- -! some basic error checking -! find the i-th index of the poles at j= nj -! the corner points must lie on the pole -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! some basic error checking + ! find the i-th index of the poles at j= nj + ! the corner points must lie on the pole + !--------------------------------------------------------------------- - ipole = -1 - j = nj - do i = 1,ni/2 + ipole = -1 + j = nj + do i = 1,ni/2 if(latBu(i,j) .eq. sg_maxlat)ipole(1) = i - enddo - do i = ni/2+1,ni + enddo + do i = ni/2+1,ni if(latBu(i,j) .eq. sg_maxlat)ipole(2) = i - enddo - if(mastertask) then - write(logmsg,'(a,2i6,2f12.2)')'poles found at i = ',ipole,latBu(ipole(1),nj), & - latBu(ipole(2),nj) - print '(a)',trim(logmsg) - end if - - if(mastertask .and. debug)call checkseam - - do i = 1,ni - i2 = ipole(2)+(ipole(1)-i)+1 - xlonCt(i) = lonCt(i2,nj) - xlatCt(i) = latCt(i2,nj) - enddo - - do i = 1,ni - i2 = ipole(2)+(ipole(1)-i) - if(i2 .lt. 1)i2 = ni + enddo + write(logmsg,'(a,2i6,2f12.2)')'poles found at i = ',ipole,latBu(ipole(1),nj), & + latBu(ipole(2),nj) + print '(a)',trim(logmsg) + + if(debug)call checkseam + + do i = 1,ni + i2 = ipole(2)+(ipole(1)-i)+1 + xlonCt(i) = lonCt(i2,nj) + xlatCt(i) = latCt(i2,nj) + enddo + + do i = 1,ni + i2 = ipole(2)+(ipole(1)-i) + if(i2 .lt. 1)i2 = ni xlonCu(i) = lonCu(i2,nj) xlatCu(i) = latCu(i2,nj) - enddo - - if(mastertask .and. debug)call checkxlatlon + enddo + + if(debug)call checkxlatlon - !approx lat at grid bottom - do i = 1,ni + !approx lat at grid bottom + do i = 1,ni dlatBu(i) = latBu(i,1) + 2.0*(latCu(i,1) - latBu(i,1)) dlatCv(i) = latCt(i,1) + 2.0*(latCt(i,1) - latCv(i,1)) - enddo + enddo -!--------------------------------------------------------------------- -! fill grid vertices variables -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! fill grid vertices variables + !--------------------------------------------------------------------- !Ct and Cu grids align in j call fill_vertices(2,nj , iVertCt,jVertCt, latBu,lonBu, latCt_vert,lonCt_vert) @@ -378,8 +359,8 @@ program gen_fixgrid call fill_vertices(1,nj-1, iVertBu,jVertBu, latCt,lonCt, latBu_vert,lonBu_vert) call fill_top(iVertBu,jVertBu, latCt,lonCt, latBu_vert,lonBu_vert, xlatCt, xlonCt) - - if(mastertask .and. debug)call checkpoint + + if(debug)call checkpoint if(minval(latCt_vert) .lt. -1.e3)stop if(minval(lonCt_vert) .lt. -1.e3)stop @@ -391,52 +372,48 @@ program gen_fixgrid if(minval(lonBu_vert) .lt. -1.e3)stop deallocate(xlonCt, xlatCt, xlonCu, xlatCu, dlatBu, dlatCv) -!--------------------------------------------------------------------- -! write out grid file files -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! write out grid file files + !--------------------------------------------------------------------- ! create a history attribute - call date_and_time(date=cdate) - history = 'created on '//trim(cdate)//' from '//trim(fsrc) - - ! write fix grid - fdst = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.nc' - call write_tripolegrid(trim(fdst)) - - ! write cice grid - fdst = trim(dirout)//'/'//'grid_cice_NEMS_mx'//trim(res)//'.nc' - call write_cicegrid(trim(fdst)) - deallocate(ulon, ulat, htn, hte) - ! write scrip grids; only the Ct is required, the remaining - ! staggers are used only in the postweights generation - do k = 1,nv - cstagger = trim(staggerlocs(k)) - fdst = trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP.nc' - if(mastertask) then - logmsg = 'creating SCRIP file '//trim(fdst) - print '(a)',trim(logmsg) - end if - call write_scripgrid(trim(fdst),trim(cstagger)) - end do - deallocate(latCv_vert, lonCv_vert) - deallocate(latCu_vert, lonCu_vert) - deallocate(latBu_vert, lonBu_vert) - - ! write SCRIP file with land mask, used for mapped ocean mask - ! and mesh creation - cstagger = trim(staggerlocs(1)) - fdst= trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP_land.nc' - if(mastertask) then + call date_and_time(date=cdate) + history = 'created on '//trim(cdate)//' from '//trim(fsrc) + + ! write fix grid + fdst = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.nc' + call write_tripolegrid(trim(fdst)) + + ! write cice grid + fdst = trim(dirout)//'/'//'grid_cice_NEMS_mx'//trim(res)//'.nc' + call write_cicegrid(trim(fdst)) + deallocate(ulon, ulat, htn, hte) + ! write scrip grids; only the Ct is required, the remaining + ! staggers are used only in the postweights generation + do k = 1,nv + cstagger = trim(staggerlocs(k)) + fdst = trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP.nc' logmsg = 'creating SCRIP file '//trim(fdst) print '(a)',trim(logmsg) - end if - call write_scripgrid(trim(fdst),trim(cstagger),imask=int(wet4)) - deallocate(latCt_vert, lonCt_vert) - -!--------------------------------------------------------------------- -! write lat,lon,depth and mask arrays required by ww3 in creating -! mod_def file -!--------------------------------------------------------------------- + call write_scripgrid(trim(fdst),trim(cstagger)) + end do + deallocate(latCv_vert, lonCv_vert) + deallocate(latCu_vert, lonCu_vert) + deallocate(latBu_vert, lonBu_vert) + + ! write SCRIP file with land mask, used for mapped ocean mask + ! and mesh creation + cstagger = trim(staggerlocs(1)) + fdst= trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP_land.nc' + logmsg = 'creating SCRIP file '//trim(fdst) + print '(a)',trim(logmsg) + call write_scripgrid(trim(fdst),trim(cstagger),imask=int(wet4)) + deallocate(latCt_vert, lonCt_vert) + + !--------------------------------------------------------------------- + ! write lat,lon,depth and mask arrays required by ww3 in creating + ! mod_def file + !--------------------------------------------------------------------- write(cnx,i4fmt)nx write(form1,'(a)')'('//trim(cnx)//'f14.8)' @@ -457,98 +434,88 @@ program gen_fixgrid open(unit=25,file=trim(dirout)//'/'//'ww3.mx'//trim(res)//'_obstr.inp',form='formatted') do j = 1,nj - write( 21,trim(form1))lonCt(:,j) - write( 22,trim(form1))latCt(:,j) + write( 21,trim(form1))lonCt(:,j) + write( 22,trim(form1))latCt(:,j) end do do j = 1,nj - write( 23,trim(form1))ww3dpth(:,j) - write( 24,trim(form2))ww3mask(:,j) - !'obsx' and 'obsy' arrays ??? - write( 25,trim(form2))ww3mask(:,j)*0 - write( 25,trim(form2))ww3mask(:,j)*0 + write( 23,trim(form1))ww3dpth(:,j) + write( 24,trim(form2))ww3mask(:,j) + !'obsx' and 'obsy' arrays ??? + write( 25,trim(form2))ww3mask(:,j)*0 + write( 25,trim(form2))ww3mask(:,j)*0 end do close(21); close(22); close(23); close(24); close(25) deallocate(ww3mask); deallocate(ww3dpth) deallocate(wet4, wet8) -!--------------------------------------------------------------------- -! use ESMF regridding to produce mapped ocean mask; first generate -! conservative regrid weights from ocean to tiles; then generate the -! tiled files containing the mapped ocean mask -!--------------------------------------------------------------------- - - method=ESMF_REGRIDMETHOD_CONSERVE - fsrc = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP_land.nc' - fdst = trim(fv3dir)//'/'//trim(atmres)//'/'//trim(atmres)//'_mosaic.nc' - fwgt = trim(dirout)//'/'//'Ct.mx'//trim(res)//'.to.'//trim(atmres)//'.nc' - if(mastertask) then - logmsg = 'creating weight file '//trim(fwgt) - print '(a)',trim(logmsg) - end if - - call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & - weightFile=trim(fwgt), regridmethod=method, & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - ignoreDegenerate=.true., & - tileFilePath=trim(fv3dir)//'/'//trim(atmres)//'/', rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) - - if(mastertask) then - logmsg = 'creating mapped ocean mask for '//trim(atmres) - print '(a)',trim(logmsg) - end if - call make_frac_land(trim(fsrc), trim(fwgt)) - -!--------------------------------------------------------------------- -! use ESMF to find the tripole:tripole weights for creation -! of CICE ICs; the source grid is always mx025; don't create this -! file if destination is also mx025 -!--------------------------------------------------------------------- - - if(trim(res) .ne. '025') then + !--------------------------------------------------------------------- + ! use ESMF regridding to produce mapped ocean mask; first generate + ! conservative regrid weights from ocean to tiles; then generate the + ! tiled files containing the mapped ocean mask + !--------------------------------------------------------------------- + + method=ESMF_REGRIDMETHOD_CONSERVE + fsrc = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP_land.nc' + fdst = trim(fv3dir)//'/'//trim(atmres)//'/'//trim(atmres)//'_mosaic.nc' + fwgt = trim(dirout)//'/'//'Ct.mx'//trim(res)//'.to.'//trim(atmres)//'.nc' + logmsg = 'creating weight file '//trim(fwgt) + print '(a)',trim(logmsg) + + call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & + weightFile=trim(fwgt), regridmethod=method, & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, ignoreDegenerate=.true., & + netcdf4fileFlag=.true., tileFilePath=trim(fv3dir)//'/'//trim(atmres)//'/', rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + logmsg = 'creating mapped ocean mask for '//trim(atmres) + print '(a)',trim(logmsg) + call make_frac_land(trim(fsrc), trim(fwgt)) + + !--------------------------------------------------------------------- + ! use ESMF to find the tripole:tripole weights for creation + ! of CICE ICs; the source grid is always mx025; don't create this + ! file if destination is also mx025 + !--------------------------------------------------------------------- + + if(trim(res) .ne. '025') then fsrc = trim(dirout)//'/'//'Ct.mx025_SCRIP.nc' inquire(FILE=trim(fsrc), EXIST=fexist) if (fexist ) then - method=ESMF_REGRIDMETHOD_NEAREST_STOD - fdst = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' - fwgt = trim(dirout)//'/'//'tripole.mx025.Ct.to.mx'//trim(res)//'.Ct.neareststod.nc' - if(mastertask) then - logmsg = 'creating weight file '//trim(fwgt) - print '(a)',trim(logmsg) - end if - - call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & - weightFile=trim(fwgt), regridmethod=method, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) + method=ESMF_REGRIDMETHOD_NEAREST_STOD + fdst = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' + fwgt = trim(dirout)//'/'//'tripole.mx025.Ct.to.mx'//trim(res)//'.Ct.neareststod.nc' + logmsg = 'creating weight file '//trim(fwgt) + print '(a)',trim(logmsg) + + call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & + weightFile=trim(fwgt), regridmethod=method, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) else - if(mastertask) then - logmsg = 'ERROR: '//trim(fsrc)//' is required to generate tripole:triple weights' - print '(a)',trim(logmsg) - end if - stop + logmsg = 'ERROR: '//trim(fsrc)//' is required to generate tripole:triple weights' + print '(a)',trim(logmsg) + stop end if - end if + end if -!--------------------------------------------------------------------- -! -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! + !--------------------------------------------------------------------- - if(do_postwgts)call make_postwgts + if(do_postwgts)call make_postwgts -!--------------------------------------------------------------------- -! clean up -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! clean up + !--------------------------------------------------------------------- - deallocate(x,y, angq, dx, dy, xsgp1, ysgp1) - deallocate(areaCt, anglet, angle) - deallocate(latCt, lonCt) - deallocate(latCv, lonCv) - deallocate(latCu, lonCu) - deallocate(latBu, lonBu) + deallocate(x,y, angq, dx, dy, xsgp1, ysgp1) + deallocate(areaCt, anglet, angle) + deallocate(latCt, lonCt) + deallocate(latCv, lonCv) + deallocate(latCu, lonCu) + deallocate(latBu, lonBu) end program gen_fixgrid diff --git a/sorc/cpld_gridgen.fd/grdvars.F90 b/sorc/cpld_gridgen.fd/grdvars.F90 index 7946b07c2..578ac269a 100644 --- a/sorc/cpld_gridgen.fd/grdvars.F90 +++ b/sorc/cpld_gridgen.fd/grdvars.F90 @@ -6,202 +6,202 @@ !! @author Denise.Worthen@noaa.gov module grdvars - + use gengrid_kinds, only : dbl_kind, real_kind, int_kind - + implicit none - integer :: ni !< i-dimension of output grid - integer :: nj !< j-dimension of output grid - integer :: npx !< i or j-dimension of fv3 tile - - integer :: nx !< i-dimension of MOM6 supergrid - integer :: ny !< j-dimension of MOM6 supergrid - - logical :: editmask !< flag indicating whether the MOM6 land mask - !! should be edited. Default is false - logical :: debug !< flag indicating whether grid information - !! should be printed for debugging purposes - !! Default is false - logical :: do_postwgts !< flag indicating whether then ESMF weights to - !! regrid from the tripole grid to a rectilinear - !! grid should be generated. Default is false. - logical :: mastertask !< flag indicating whether this is the mastertask - - integer, parameter :: nv = 4. !< the number of vertices for each stagger location - integer, parameter :: ncoord = 2*4. !< the number of coord pairs (lat,lon) for each of - !! 4 stagger locations - integer, parameter :: nverts = 2*4. !< the number of coord pairs (lat,lon) for the - !! vertices of each stagger location - integer, parameter :: nvars = ncoord + nverts !< the total number of cooridinate variables - - - real(dbl_kind) :: sg_maxlat !< the maximum latitute present in the supergrid - !! file - integer(int_kind) :: ipole(2) !< the i-index for both pole locations - !! along the top-most row - - integer, parameter, dimension(nv) :: iVertCt = (/0, -1, -1, 0/) !< The i-offsets of the Bu grid at each Ct(i,j) - !! which determine the 4 vertices of each Ct grid - !! grid point in i - integer, parameter, dimension(nv) :: jVertCt = (/0, 0, -1, -1/) !< The j-offsets of the Bu grid at each Ct(i,j) - !! which determine the 4 vertices of each Ct - !! grid point in j - integer, dimension(nv) :: iVertCv !< The i-offsets of the Cu grid at each Cv(i,j) - !! which determine the 4 vertices of each Cv - !! grid point in i - integer, dimension(nv) :: jVertCv !< The j-offsets of the Cu grid at each Cv(i,j) - !! which determine the 4 vertices of each Cv - !! grid point in j - integer, dimension(nv) :: iVertCu !< The i-offsets of the Cv grid at each Cu(i,j) - !! which determine the 4 vertices of each Cu - !! grid point in i - integer, dimension(nv) :: jVertCu !< The j-offsets of the Cv grid at each Cu(i,j) - !! which determine the 4 vertices of each Cu - !! grid point in j - integer, dimension(nv) :: iVertBu !< The i-offsets of the Ct grid at each Bu(i,j) - !! which determine the 4 vertices of each Bu - !! grid point in i - integer, dimension(nv) :: jVertBu !< The j-offsets of the Ct grid at each Bu(i,j) - !! which determine the 4 vertices of each Bu - !! grid point in j + integer :: ni !< i-dimension of output grid + integer :: nj !< j-dimension of output grid + integer :: npx !< i or j-dimension of fv3 tile + + integer :: nx !< i-dimension of MOM6 supergrid + integer :: ny !< j-dimension of MOM6 supergrid + + logical :: editmask !< flag indicating whether the MOM6 land mask + !! should be edited. Default is false + logical :: debug !< flag indicating whether grid information + !! should be printed for debugging purposes + !! Default is false + logical :: do_postwgts !< flag indicating whether then ESMF weights to + !! regrid from the tripole grid to a rectilinear + !! grid should be generated. Default is false. + logical :: roottask !< flag indicating whether this is the roottask + + integer, parameter :: nv = 4. !< the number of vertices for each stagger location + integer, parameter :: ncoord = 2*4. !< the number of coord pairs (lat,lon) for each of + !! 4 stagger locations + integer, parameter :: nverts = 2*4. !< the number of coord pairs (lat,lon) for the + !! vertices of each stagger location + integer, parameter :: nvars = ncoord + nverts !< the total number of cooridinate variables + + + real(dbl_kind) :: sg_maxlat !< the maximum latitute present in the supergrid + !! file + integer(int_kind) :: ipole(2) !< the i-index for both pole locations + !! along the top-most row + + integer, parameter, dimension(nv) :: iVertCt = (/0, -1, -1, 0/) !< The i-offsets of the Bu grid at each Ct(i,j) + !! which determine the 4 vertices of each Ct grid + !! grid point in i + integer, parameter, dimension(nv) :: jVertCt = (/0, 0, -1, -1/) !< The j-offsets of the Bu grid at each Ct(i,j) + !! which determine the 4 vertices of each Ct + !! grid point in j + integer, dimension(nv) :: iVertCv !< The i-offsets of the Cu grid at each Cv(i,j) + !! which determine the 4 vertices of each Cv + !! grid point in i + integer, dimension(nv) :: jVertCv !< The j-offsets of the Cu grid at each Cv(i,j) + !! which determine the 4 vertices of each Cv + !! grid point in j + integer, dimension(nv) :: iVertCu !< The i-offsets of the Cv grid at each Cu(i,j) + !! which determine the 4 vertices of each Cu + !! grid point in i + integer, dimension(nv) :: jVertCu !< The j-offsets of the Cv grid at each Cu(i,j) + !! which determine the 4 vertices of each Cu + !! grid point in j + integer, dimension(nv) :: iVertBu !< The i-offsets of the Ct grid at each Bu(i,j) + !! which determine the 4 vertices of each Bu + !! grid point in i + integer, dimension(nv) :: jVertBu !< The j-offsets of the Ct grid at each Bu(i,j) + !! which determine the 4 vertices of each Bu + !! grid point in j ! Super-grid source grid variables - real(dbl_kind), allocatable, dimension(:,:) :: x !< The longitudes of the MOM6 supergrid - real(dbl_kind), allocatable, dimension(:,:) :: y !< The latitudes of the MOM6 supergrid - real(dbl_kind), allocatable, dimension(:,:) :: angq !< The grid rotation angle at the Bu (or corner) - !! grid points of the super grid - - real(dbl_kind), allocatable, dimension(:,:) :: dx !< The grid cell width in meters of the supergrid - !! in the x-direction (i-dimension) - real(dbl_kind), allocatable, dimension(:,:) :: dy !< The grid cell width in meters of the supergrid - !! in the y-direction (j-dimension) - real(dbl_kind), allocatable, dimension(:,:) :: xsgp1 !< The longitudes of the super-grid replicated - !! across the tripole seam - real(dbl_kind), allocatable, dimension(:,:) :: ysgp1 !< The latitudes of the super-grid replicated - !! across the tripole seam - + real(dbl_kind), allocatable, dimension(:,:) :: x !< The longitudes of the MOM6 supergrid + real(dbl_kind), allocatable, dimension(:,:) :: y !< The latitudes of the MOM6 supergrid + real(dbl_kind), allocatable, dimension(:,:) :: angq !< The grid rotation angle at the Bu (or corner) + !! grid points of the super grid + + real(dbl_kind), allocatable, dimension(:,:) :: dx !< The grid cell width in meters of the supergrid + !! in the x-direction (i-dimension) + real(dbl_kind), allocatable, dimension(:,:) :: dy !< The grid cell width in meters of the supergrid + !! in the y-direction (j-dimension) + real(dbl_kind), allocatable, dimension(:,:) :: xsgp1 !< The longitudes of the super-grid replicated + !! across the tripole seam + real(dbl_kind), allocatable, dimension(:,:) :: ysgp1 !< The latitudes of the super-grid replicated + !! across the tripole seam + ! Output grid variables - real(dbl_kind), allocatable, dimension(:,:) :: latCt !< The latitude of the center (tracer) grid points - !! on the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: lonCt !< The longitude of the center (tracer) grid - !! points on the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: latCv !< The latitude of the v-velocity grid points on - !! the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: lonCv !< The longitude of the v-velocity grid points on - !! the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: latCu !< The latitude of the u-velocity grid points on - !! the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: lonCu !< The longitude of the u-velocity grid points on - !! the C-grid - real(dbl_kind), allocatable, dimension(:,:) :: latBu !< The latitude of the corner points on the C-grid. - !! These are equivalent to u,v velocity grid - !! points on the B-grid - real(dbl_kind), allocatable, dimension(:,:) :: lonBu !< The longitude of the corner points on the - !! C-grid. These are equivalent to u,v velocity - !! grid points on the B-grid - real(dbl_kind), allocatable, dimension(:,:) :: areaCt !< The grid areas of the Ct grid cell in m2 - real(dbl_kind), allocatable, dimension(:,:) :: anglet !< The rotation angle on Ct points (opposite sense - !! from angle) - real(dbl_kind), allocatable, dimension(:,:) :: angle !< The rotation angle on Bu points - - real(dbl_kind), allocatable, dimension(:,:,:) :: latCt_vert !< The latitudes of the 4 vertices of each Ct grid - !! point - real(dbl_kind), allocatable, dimension(:,:,:) :: lonCt_vert !< The longitudes of the 4 vertices of each Ct - !! grid point - - real(dbl_kind), allocatable, dimension(:,:,:) :: latCv_vert !< The latitudes of the 4 vertices of each Cv grid - !! point - real(dbl_kind), allocatable, dimension(:,:,:) :: lonCv_vert !< The longitudes of the 4 vertices of each Cv - !! grid point - - real(dbl_kind), allocatable, dimension(:,:,:) :: latCu_vert !< The latitudes of the 4 vertices of each Cu grid - !! point - real(dbl_kind), allocatable, dimension(:,:,:) :: lonCu_vert !< The longitudes of the 4 vertices of each Cu - !! grid point - - real(dbl_kind), allocatable, dimension(:,:,:) :: latBu_vert !< The latitudes of the 4 vertices of each Bu grid - !! point - real(dbl_kind), allocatable, dimension(:,:,:) :: lonBu_vert !< The longitudes of the 4 vertices of each Bu - !! grid point - - - real(dbl_kind), allocatable, dimension(:) :: xlonCt !< The longitude of the Ct grid points on the - !! opposite side of the tripole seam - real(dbl_kind), allocatable, dimension(:) :: xlatCt !< The latitude of the Ct grid points on the - !! opposite side of the tripole seam - real(dbl_kind), allocatable, dimension(:) :: xlonCu !< The longitude of the Cu grid points on the - !! opposite side of the tripole seam - real(dbl_kind), allocatable, dimension(:) :: xlatCu !< The latitude of the Cu grid points on the - !! opposite side of the tripole seam - real(dbl_kind), allocatable, dimension(:) :: dlatBu !< The latitude spacing between Bu points at the - !! grid bottom - real(dbl_kind), allocatable, dimension(:) :: dlatCv !< The latitude spacing between Cv points at the - !! grid bottom + real(dbl_kind), allocatable, dimension(:,:) :: latCt !< The latitude of the center (tracer) grid points + !! on the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: lonCt !< The longitude of the center (tracer) grid + !! points on the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: latCv !< The latitude of the v-velocity grid points on + !! the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: lonCv !< The longitude of the v-velocity grid points on + !! the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: latCu !< The latitude of the u-velocity grid points on + !! the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: lonCu !< The longitude of the u-velocity grid points on + !! the C-grid + real(dbl_kind), allocatable, dimension(:,:) :: latBu !< The latitude of the corner points on the C-grid. + !! These are equivalent to u,v velocity grid + !! points on the B-grid + real(dbl_kind), allocatable, dimension(:,:) :: lonBu !< The longitude of the corner points on the + !! C-grid. These are equivalent to u,v velocity + !! grid points on the B-grid + real(dbl_kind), allocatable, dimension(:,:) :: areaCt !< The grid areas of the Ct grid cell in m2 + real(dbl_kind), allocatable, dimension(:,:) :: anglet !< The rotation angle on Ct points (opposite sense + !! from angle) + real(dbl_kind), allocatable, dimension(:,:) :: angle !< The rotation angle on Bu points + + real(dbl_kind), allocatable, dimension(:,:,:) :: latCt_vert !< The latitudes of the 4 vertices of each Ct grid + !! point + real(dbl_kind), allocatable, dimension(:,:,:) :: lonCt_vert !< The longitudes of the 4 vertices of each Ct + !! grid point + + real(dbl_kind), allocatable, dimension(:,:,:) :: latCv_vert !< The latitudes of the 4 vertices of each Cv grid + !! point + real(dbl_kind), allocatable, dimension(:,:,:) :: lonCv_vert !< The longitudes of the 4 vertices of each Cv + !! grid point + + real(dbl_kind), allocatable, dimension(:,:,:) :: latCu_vert !< The latitudes of the 4 vertices of each Cu grid + !! point + real(dbl_kind), allocatable, dimension(:,:,:) :: lonCu_vert !< The longitudes of the 4 vertices of each Cu + !! grid point + + real(dbl_kind), allocatable, dimension(:,:,:) :: latBu_vert !< The latitudes of the 4 vertices of each Bu grid + !! point + real(dbl_kind), allocatable, dimension(:,:,:) :: lonBu_vert !< The longitudes of the 4 vertices of each Bu + !! grid point + + + real(dbl_kind), allocatable, dimension(:) :: xlonCt !< The longitude of the Ct grid points on the + !! opposite side of the tripole seam + real(dbl_kind), allocatable, dimension(:) :: xlatCt !< The latitude of the Ct grid points on the + !! opposite side of the tripole seam + real(dbl_kind), allocatable, dimension(:) :: xlonCu !< The longitude of the Cu grid points on the + !! opposite side of the tripole seam + real(dbl_kind), allocatable, dimension(:) :: xlatCu !< The latitude of the Cu grid points on the + !! opposite side of the tripole seam + real(dbl_kind), allocatable, dimension(:) :: dlatBu !< The latitude spacing between Bu points at the + !! grid bottom + real(dbl_kind), allocatable, dimension(:) :: dlatCv !< The latitude spacing between Cv points at the + !! grid bottom ! MOM6 fix fields - real(real_kind), allocatable, dimension(:,:) :: wet4 !< The ocean mask from a MOM6 mask file, stored as - !! real*4 (nd) - real(dbl_kind), allocatable, dimension(:,:) :: wet8 !< The ocean mask from a MOM6 mask file, stored as - !! real*8 (nd) + real(real_kind), allocatable, dimension(:,:) :: wet4 !< The ocean mask from a MOM6 mask file, stored as + !! real*4 (nd) + real(dbl_kind), allocatable, dimension(:,:) :: wet8 !< The ocean mask from a MOM6 mask file, stored as + !! real*8 (nd) - real(real_kind), allocatable, dimension(:,:) :: dp4 !< The ocean depth from a MOM6 topog file, stored - !! as real*4 (m) - real(dbl_kind), allocatable, dimension(:,:) :: dp8 !< The ocean depth from a MOM6 topog file, stored - !! as real*8 (m) + real(real_kind), allocatable, dimension(:,:) :: dp4 !< The ocean depth from a MOM6 topog file, stored + !! as real*4 (m) + real(dbl_kind), allocatable, dimension(:,:) :: dp8 !< The ocean depth from a MOM6 topog file, stored + !! as real*8 (m) ! CICE6 fields - real(dbl_kind), allocatable, dimension(:,:) :: ulon !< The longitude points (on the Bu grid) for CICE6 - !! (radians) - real(dbl_kind), allocatable, dimension(:,:) :: ulat !< The latitude points (on the Bu grid) for CICE6 - !! (radians) - real(dbl_kind), allocatable, dimension(:,:) :: htn !< The grid cell width in centimeters of the CICE6 - !! grid in the x-direction (i-dimension) - real(dbl_kind), allocatable, dimension(:,:) :: hte !< The grid cell width in centimeters of the CICE6 - !! grid in the y-direction (j-dimension) - - real(kind=real_kind), parameter :: minimum_depth = 9.5 !< The minimum depth for MOM6 - real(kind=real_kind), parameter :: maximum_depth = 6500.0 !< The maximum depth for MOM6 - real(kind=real_kind), parameter :: masking_depth = 0.0 !< The masking depth for MOM6. Depths shallower than - !! minimum_depth but deeper than masking_depth are - !! rounded to minimum_depth - real(kind=real_kind), parameter :: maximum_lat = 88.0 !< The maximum latitude for water points for WW3 - - contains -!> Allocate grid variables -!! -!! @author Denise Worthen - + real(dbl_kind), allocatable, dimension(:,:) :: ulon !< The longitude points (on the Bu grid) for CICE6 + !! (radians) + real(dbl_kind), allocatable, dimension(:,:) :: ulat !< The latitude points (on the Bu grid) for CICE6 + !! (radians) + real(dbl_kind), allocatable, dimension(:,:) :: htn !< The grid cell width in centimeters of the CICE6 + !! grid in the x-direction (i-dimension) + real(dbl_kind), allocatable, dimension(:,:) :: hte !< The grid cell width in centimeters of the CICE6 + !! grid in the y-direction (j-dimension) + + real(kind=real_kind), parameter :: minimum_depth = 9.5 !< The minimum depth for MOM6 + real(kind=real_kind), parameter :: maximum_depth = 6500.0 !< The maximum depth for MOM6 + real(kind=real_kind), parameter :: masking_depth = 0.0 !< The masking depth for MOM6. Depths shallower than + !! minimum_depth but deeper than masking_depth are + !! rounded to minimum_depth + real(kind=real_kind), parameter :: maximum_lat = 88.0 !< The maximum latitude for water points for WW3 + +contains + !> Allocate grid variables + !! + !! @author Denise Worthen + subroutine allocate_all - allocate( x(0:nx,0:ny), y(0:nx,0:ny), angq(0:nx,0:ny) ) - allocate( dx(nx,0:ny), dy(0:nx,ny) ) + allocate( x(0:nx,0:ny), y(0:nx,0:ny), angq(0:nx,0:ny) ) + allocate( dx(nx,0:ny), dy(0:nx,ny) ) - allocate( xsgp1(0:nx,0:ny+1), ysgp1(0:nx,0:ny+1) ) + allocate( xsgp1(0:nx,0:ny+1), ysgp1(0:nx,0:ny+1) ) - allocate( latCt(ni,nj), lonCt(ni,nj) ) - allocate( latCv(ni,nj), lonCv(ni,nj) ) - allocate( latCu(ni,nj), lonCu(ni,nj) ) - allocate( latBu(ni,nj), lonBu(ni,nj) ) + allocate( latCt(ni,nj), lonCt(ni,nj) ) + allocate( latCv(ni,nj), lonCv(ni,nj) ) + allocate( latCu(ni,nj), lonCu(ni,nj) ) + allocate( latBu(ni,nj), lonBu(ni,nj) ) - allocate( areaCt(ni,nj), anglet(ni,nj), angle(ni,nj) ) + allocate( areaCt(ni,nj), anglet(ni,nj), angle(ni,nj) ) - allocate( latCt_vert(ni,nj,nv), lonCt_vert(ni,nj,nv) ) - allocate( latCv_vert(ni,nj,nv), lonCv_vert(ni,nj,nv) ) - allocate( latCu_vert(ni,nj,nv), lonCu_vert(ni,nj,nv) ) - allocate( latBu_vert(ni,nj,nv), lonBu_vert(ni,nj,nv) ) + allocate( latCt_vert(ni,nj,nv), lonCt_vert(ni,nj,nv) ) + allocate( latCv_vert(ni,nj,nv), lonCv_vert(ni,nj,nv) ) + allocate( latCu_vert(ni,nj,nv), lonCu_vert(ni,nj,nv) ) + allocate( latBu_vert(ni,nj,nv), lonBu_vert(ni,nj,nv) ) - allocate( xlonCt(ni), xlatCt(ni) ) - allocate( xlonCu(ni), xlatCu(ni) ) - allocate( dlatBu(ni), dlatCv(ni) ) + allocate( xlonCt(ni), xlatCt(ni) ) + allocate( xlonCu(ni), xlatCu(ni) ) + allocate( dlatBu(ni), dlatCv(ni) ) - allocate( wet4(ni,nj) ) - allocate( wet8(ni,nj) ) + allocate( wet4(ni,nj) ) + allocate( wet8(ni,nj) ) - allocate( dp4(ni,nj) ) - allocate( dp8(ni,nj) ) + allocate( dp4(ni,nj) ) + allocate( dp8(ni,nj) ) - allocate( ulon(ni,nj), ulat(ni,nj) ) - allocate( htn(ni,nj), hte(ni,nj) ) + allocate( ulon(ni,nj), ulat(ni,nj) ) + allocate( htn(ni,nj), hte(ni,nj) ) end subroutine allocate_all - + end module grdvars diff --git a/sorc/cpld_gridgen.fd/inputnml.F90 b/sorc/cpld_gridgen.fd/inputnml.F90 index 60bc6c2e4..6e363657b 100644 --- a/sorc/cpld_gridgen.fd/inputnml.F90 +++ b/sorc/cpld_gridgen.fd/inputnml.F90 @@ -7,51 +7,51 @@ module inputnml - use grdvars, only : nx,ny,ni,nj,npx - use grdvars, only : editmask, debug, do_postwgts - use charstrings, only : dirsrc, dirout, fv3dir, res, atmres, topofile, editsfile + use grdvars, only : nx,ny,ni,nj,npx + use grdvars, only : editmask, debug, do_postwgts + use charstrings, only : dirsrc, dirout, fv3dir, res, atmres, topofile, editsfile - implicit none + implicit none - contains +contains -!> Read input namelist file -!! -!! @param[in] fname the file name to read -!! -!! @author Denise.Worthen@noaa.gov + !> Read input namelist file + !! + !! @param[in] fname the file name to read + !! + !! @author Denise.Worthen@noaa.gov - subroutine read_inputnml(fname) + subroutine read_inputnml(fname) - character(len=*), intent(in) :: fname + character(len=*), intent(in) :: fname - ! local variables - integer :: stderr, iounit, rc + ! local variables + integer :: stderr, iounit, rc - namelist /grid_nml/ ni, nj, dirsrc, dirout, fv3dir, topofile, editsfile, & - res, atmres, npx, editmask, debug, & - do_postwgts + namelist /grid_nml/ ni, nj, dirsrc, dirout, fv3dir, topofile, editsfile, & + res, atmres, npx, editmask, debug, & + do_postwgts - ! Check whether file exists. - inquire (file=trim(fname), iostat=rc) + ! Check whether file exists. + inquire (file=trim(fname), iostat=rc) - if (rc /= 0) then - write (stderr, '(3a)') 'Error: input file "', trim(fname), '" does not exist.' - return - end if + if (rc /= 0) then + write (stderr, '(3a)') 'Error: input file "', trim(fname), '" does not exist.' + return + end if - ! Open and read Namelist file. - open (action='read', file=trim(fname), iostat=rc, newunit=iounit) - read (nml=grid_nml, iostat=rc, unit=iounit) + ! Open and read Namelist file. + open (action='read', file=trim(fname), iostat=rc, newunit=iounit) + read (nml=grid_nml, iostat=rc, unit=iounit) - ! set supergrid dimensions - nx = ni*2 - ny = nj*2 + ! set supergrid dimensions + nx = ni*2 + ny = nj*2 - if (rc /= 0) then - write (stderr, '(a)') 'Error: invalid Namelist format.' - end if + if (rc /= 0) then + write (stderr, '(a)') 'Error: invalid Namelist format.' + end if - close (iounit) + close (iounit) end subroutine read_inputnml end module inputnml diff --git a/sorc/cpld_gridgen.fd/mapped_mask.F90 b/sorc/cpld_gridgen.fd/mapped_mask.F90 index 514c45ca3..02e3b85d2 100644 --- a/sorc/cpld_gridgen.fd/mapped_mask.F90 +++ b/sorc/cpld_gridgen.fd/mapped_mask.F90 @@ -8,49 +8,49 @@ module mapped_mask use gengrid_kinds, only : dbl_kind,int_kind,CL,CM,CS - use grdvars, only : ni,nj,npx,mastertask + use grdvars, only : ni,nj,npx use charstrings, only : dirout,res,atmres,logmsg use netcdf implicit none - contains +contains -!> Use ESMF weights to map the ocean land mask to the FV3 tiles and write the mapped mask to 6 tile files -!! -!! @param[in] src a SCRIP file containing the land mask for the ocean domain -!! @param[in] wgt a file containing the ESMF weights to regrid from the ocean domain to the FV3 tile domain -!! -!! @author Denise.Worthen@noaa.gov + !> Use ESMF weights to map the ocean land mask to the FV3 tiles and write the mapped mask to 6 tile files + !! + !! @param[in] src a SCRIP file containing the land mask for the ocean domain + !! @param[in] wgt a file containing the ESMF weights to regrid from the ocean domain to the FV3 tile domain + !! + !! @author Denise.Worthen@noaa.gov subroutine make_frac_land(src, wgt) - character(len=*), intent(in) :: src, wgt + character(len=*), intent(in) :: src, wgt - ! local variables - integer, parameter :: ntile = 6 - integer(int_kind) :: n_a, n_b, n_s + ! local variables + integer, parameter :: ntile = 6 + integer(int_kind) :: n_a, n_b, n_s - integer(int_kind), allocatable, dimension(:) :: col, row - real(dbl_kind), allocatable, dimension(:) :: S - real(dbl_kind), allocatable, dimension(:) :: lat1d, lon1d + integer(int_kind), allocatable, dimension(:) :: col, row + real(dbl_kind), allocatable, dimension(:) :: S + real(dbl_kind), allocatable, dimension(:) :: lat1d, lon1d - integer(int_kind), allocatable, dimension(:) :: src_field - real(dbl_kind), allocatable, dimension(:) :: dst_field + integer(int_kind), allocatable, dimension(:) :: src_field + real(dbl_kind), allocatable, dimension(:) :: dst_field - real(dbl_kind), allocatable, dimension(:,:) :: dst2d - real(dbl_kind), allocatable, dimension(:,:) :: lat2d,lon2d + real(dbl_kind), allocatable, dimension(:,:) :: dst2d + real(dbl_kind), allocatable, dimension(:,:) :: lat2d,lon2d - character(len=CS) :: ctile - character(len=CL) :: fdst - integer :: i,ii,jj,id,rc,ncid, dim2(2) - integer :: istr,iend - integer :: idimid,jdimid + character(len=CS) :: ctile + character(len=CL) :: fdst + integer :: i,ii,jj,id,rc,ncid, dim2(2) + integer :: istr,iend + integer :: idimid,jdimid - character(len=CM) :: vname -!--------------------------------------------------------------------- -! retrieve the weights -!--------------------------------------------------------------------- + character(len=CM) :: vname + !--------------------------------------------------------------------- + ! retrieve the weights + !--------------------------------------------------------------------- rc = nf90_open(trim(wgt), nf90_nowrite, ncid) rc = nf90_inq_dimid(ncid, 'n_s', id) @@ -59,7 +59,7 @@ subroutine make_frac_land(src, wgt) rc = nf90_inquire_dimension(ncid, id, len=n_a) rc = nf90_inq_dimid(ncid, 'n_b', id) rc = nf90_inquire_dimension(ncid, id, len=n_b) - + allocate(col(1:n_s)) allocate(row(1:n_s)) allocate( S(1:n_s)) @@ -81,9 +81,9 @@ subroutine make_frac_land(src, wgt) rc = nf90_get_var(ncid, id, lon1d) rc = nf90_close(ncid) -!--------------------------------------------------------------------- -! retrieve 1-d land mask from the SCRIP file and map it -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! retrieve 1-d land mask from the SCRIP file and map it + !--------------------------------------------------------------------- allocate(src_field(1:n_a)) allocate(dst_field(1:n_b)) @@ -97,61 +97,59 @@ subroutine make_frac_land(src, wgt) dst_field = 0.0 do i = 1,n_s - ii = row(i); jj = col(i) - dst_field(ii) = dst_field(ii) + S(i)*real(src_field(jj),dbl_kind) + ii = row(i); jj = col(i) + dst_field(ii) = dst_field(ii) + S(i)*real(src_field(jj),dbl_kind) enddo -!--------------------------------------------------------------------- -! -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! + !--------------------------------------------------------------------- allocate(dst2d(npx,npx)) allocate(lon2d(npx,npx)); allocate(lat2d(npx,npx)) do i = 0,ntile-1 - istr = i*npx*npx+1 - iend = istr+npx*npx-1 - !print *,i,istr,iend + istr = i*npx*npx+1 + iend = istr+npx*npx-1 + !print *,i,istr,iend - write(ctile,'(a5,i1)')'.tile',i+1 - fdst = trim(dirout)//'/'//trim(atmres)//'.mx'//trim(res)//trim(ctile)//'.nc' - if(mastertask) then + write(ctile,'(a5,i1)')'.tile',i+1 + fdst = trim(dirout)//'/'//trim(atmres)//'.mx'//trim(res)//trim(ctile)//'.nc' logmsg = 'creating mapped ocean mask file '//trim(fdst) print '(a)',trim(logmsg) - end if - - dst2d(:,:) = reshape(dst_field(istr:iend), (/npx,npx/)) - lat2d(:,:) = reshape( lat1d(istr:iend), (/npx,npx/)) - lon2d(:,:) = reshape( lon1d(istr:iend), (/npx,npx/)) - - rc = nf90_create(trim(fdst), nf90_64bit_offset, ncid) - rc = nf90_def_dim(ncid, 'grid_xt', npx, idimid) - rc = nf90_def_dim(ncid, 'grid_yt', npx, jdimid) - - dim2(:) = (/idimid, jdimid/) - vname = 'grid_xt' - rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) - vname = 'grid_yt' - rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) - vname = 'land_frac' - rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) - rc = nf90_enddef(ncid) - - rc = nf90_inq_varid(ncid, 'grid_xt', id) - rc = nf90_put_var(ncid, id, lon2d) - rc = nf90_inq_varid(ncid, 'grid_yt', id) - rc = nf90_put_var(ncid, id, lat2d) - rc = nf90_inq_varid(ncid, 'land_frac', id) - rc = nf90_put_var(ncid, id, dst2d) - rc = nf90_close(ncid) + + dst2d(:,:) = reshape(dst_field(istr:iend), (/npx,npx/)) + lat2d(:,:) = reshape( lat1d(istr:iend), (/npx,npx/)) + lon2d(:,:) = reshape( lon1d(istr:iend), (/npx,npx/)) + + rc = nf90_create(trim(fdst), nf90_64bit_offset, ncid) + rc = nf90_def_dim(ncid, 'grid_xt', npx, idimid) + rc = nf90_def_dim(ncid, 'grid_yt', npx, jdimid) + + dim2(:) = (/idimid, jdimid/) + vname = 'grid_xt' + rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) + vname = 'grid_yt' + rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) + vname = 'land_frac' + rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) + rc = nf90_enddef(ncid) + + rc = nf90_inq_varid(ncid, 'grid_xt', id) + rc = nf90_put_var(ncid, id, lon2d) + rc = nf90_inq_varid(ncid, 'grid_yt', id) + rc = nf90_put_var(ncid, id, lat2d) + rc = nf90_inq_varid(ncid, 'land_frac', id) + rc = nf90_put_var(ncid, id, dst2d) + rc = nf90_close(ncid) end do -!--------------------------------------------------------------------- -! clean up -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! clean up + !--------------------------------------------------------------------- - deallocate(col, row, S, lat1d, lon1d, src_field, dst_field) - deallocate(dst2d,lon2d,lat2d) + deallocate(col, row, S, lat1d, lon1d, src_field, dst_field) + deallocate(dst2d,lon2d,lat2d) end subroutine make_frac_land end module mapped_mask diff --git a/sorc/cpld_gridgen.fd/postwgts.F90 b/sorc/cpld_gridgen.fd/postwgts.F90 index 76d17b779..4ff0bc0fa 100644 --- a/sorc/cpld_gridgen.fd/postwgts.F90 +++ b/sorc/cpld_gridgen.fd/postwgts.F90 @@ -9,108 +9,104 @@ module postwgts use ESMF use gengrid_kinds, only : CL,CM,CS - use grdvars, only : nv, mastertask + use grdvars, only : nv use charstrings, only : dirout, res, staggerlocs, logmsg use netcdf implicit none - contains -!> Create the ESMF weights files to remap velocity points from their native stagger location to the center -!! (Ct) location. Create the ESMF weights file to remap from the Ct location to a rectilinear grid -!! -!! @author Denise.Worthen@noaa.gov - +contains + !> Create the ESMF weights files to remap velocity points from their native stagger location to the center + !! (Ct) location. Create the ESMF weights file to remap from the Ct location to a rectilinear grid + !! + !! @author Denise.Worthen@noaa.gov + subroutine make_postwgts - ! local variables - character(len=CL) :: fsrc, fdst, fwgt - character(len= 2) :: cstagger - - character(len=CM), dimension(2) :: methodname = (/'conserve', 'bilinear'/) - - type(ESMF_RegridMethod_Flag) :: method - ! the number of possible destination grids depends on the source grid resolution - integer :: k,rc,nd,ndest - character(len=CS), allocatable, dimension(:) :: destgrds - -!--------------------------------------------------------------------- -! set the destination grids -!--------------------------------------------------------------------- - - if(trim(res) .eq. '400')return - - if(trim(res) .eq. '100')then - ndest = 1 - allocate(destgrds(ndest)) - destgrds = (/'1p0 '/) - end if - if(trim(res) .eq. '050')then - ndest = 2 - allocate(destgrds(ndest)) - destgrds = (/'1p0 ', '0p5 '/) - end if - if(trim(res) .eq. '025')then - ndest = 3 - allocate(destgrds(ndest)) - destgrds = (/'1p0 ', '0p5 ', '0p25'/) - end if - -!--------------------------------------------------------------------- -! use ESMF to create the weights for unstaggering the points onto -! the Ct staggers for post; the destination is always Ct -!--------------------------------------------------------------------- - - method=ESMF_REGRIDMETHOD_BILINEAR - fdst = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' - do k = 2,nv - cstagger = trim(staggerlocs(k)) - fsrc = trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP.nc' - fwgt = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.'//trim(cstagger)//'.to.Ct.bilinear.nc' - if(mastertask) then - logmsg = 'creating weight file '//trim(fwgt) - print '(a)',trim(logmsg) - end if - - call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & - weightFile=trim(fwgt), regridmethod=method, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) - end do - -!--------------------------------------------------------------------- -! use ESMF to create the weights from the Ct tripole to the rectilinear -! grids with conservative and bilinear methods for post; the source -! file is always Ct -!--------------------------------------------------------------------- - - do nd = 1,ndest - fsrc = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' - fdst = trim(dirout)//'/rect.'//trim(destgrds(nd))//'_SCRIP.nc' - - do k = 1,size(methodname) - if(trim(methodname(k)) .eq. 'bilinear')method=ESMF_REGRIDMETHOD_BILINEAR - if(trim(methodname(k)) .eq. 'conserve')method=ESMF_REGRIDMETHOD_CONSERVE - - fwgt = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.Ct.to.rect.'//trim(destgrds(nd)) & - //'.'//trim(methodname(k))//'.nc' - if(mastertask) then - logmsg = 'creating weight file '//trim(fwgt) - print '(a)',trim(logmsg) - end if - - call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & - weightFile=trim(fwgt), regridmethod=method, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) - end do - end do - - deallocate(destgrds) + ! local variables + character(len=CL) :: fsrc, fdst, fwgt + character(len= 2) :: cstagger + + character(len=CM), dimension(2) :: methodname = (/'conserve', 'bilinear'/) + + type(ESMF_RegridMethod_Flag) :: method + ! the number of possible destination grids depends on the source grid resolution + integer :: k,rc,nd,ndest + character(len=CS), allocatable, dimension(:) :: destgrds + + !--------------------------------------------------------------------- + ! set the destination grids + !--------------------------------------------------------------------- + + if(trim(res) .eq. '400')return + + if(trim(res) .eq. '100')then + ndest = 1 + allocate(destgrds(ndest)) + destgrds = (/'1p0 '/) + end if + if(trim(res) .eq. '050')then + ndest = 2 + allocate(destgrds(ndest)) + destgrds = (/'1p0 ', '0p5 '/) + end if + if(trim(res) .eq. '025')then + ndest = 3 + allocate(destgrds(ndest)) + destgrds = (/'1p0 ', '0p5 ', '0p25'/) + end if + + !--------------------------------------------------------------------- + ! use ESMF to create the weights for unstaggering the points onto + ! the Ct staggers for post; the destination is always Ct + !--------------------------------------------------------------------- + + method=ESMF_REGRIDMETHOD_BILINEAR + fdst = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' + do k = 2,nv + cstagger = trim(staggerlocs(k)) + fsrc = trim(dirout)//'/'//trim(cstagger)//'.mx'//trim(res)//'_SCRIP.nc' + fwgt = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.'//trim(cstagger)//'.to.Ct.bilinear.nc' + logmsg = 'creating weight file '//trim(fwgt) + print '(a)',trim(logmsg) + + call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & + weightFile=trim(fwgt), regridmethod=method, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) + end do + + !--------------------------------------------------------------------- + ! use ESMF to create the weights from the Ct tripole to the rectilinear + ! grids with conservative and bilinear methods for post; the source + ! file is always Ct + !--------------------------------------------------------------------- + + do nd = 1,ndest + fsrc = trim(dirout)//'/'//'Ct.mx'//trim(res)//'_SCRIP.nc' + fdst = trim(dirout)//'/rect.'//trim(destgrds(nd))//'_SCRIP.nc' + + do k = 1,size(methodname) + if(trim(methodname(k)) .eq. 'bilinear')method=ESMF_REGRIDMETHOD_BILINEAR + if(trim(methodname(k)) .eq. 'conserve')method=ESMF_REGRIDMETHOD_CONSERVE + + fwgt = trim(dirout)//'/'//'tripole.mx'//trim(res)//'.Ct.to.rect.'//trim(destgrds(nd)) & + //'.'//trim(methodname(k))//'.nc' + logmsg = 'creating weight file '//trim(fwgt) + print '(a)',trim(logmsg) + + call ESMF_RegridWeightGen(srcFile=trim(fsrc),dstFile=trim(fdst), & + weightFile=trim(fwgt), regridmethod=method, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) + end do + end do + + deallocate(destgrds) end subroutine make_postwgts end module postwgts diff --git a/sorc/cpld_gridgen.fd/scripgrid.F90 b/sorc/cpld_gridgen.fd/scripgrid.F90 index e08b77e44..d501939a5 100644 --- a/sorc/cpld_gridgen.fd/scripgrid.F90 +++ b/sorc/cpld_gridgen.fd/scripgrid.F90 @@ -8,7 +8,7 @@ module scripgrid use gengrid_kinds, only: dbl_kind,int_kind,CM - use grdvars, only: ni,nj,nv,mastertask + use grdvars, only: ni,nj,nv use grdvars, only: lonCt,latCt,lonCt_vert,latCt_vert use grdvars, only: lonCu,latCu,lonCu_vert,latCu_vert use grdvars, only: lonCv,latCv,lonCv_vert,latCv_vert @@ -22,162 +22,160 @@ module scripgrid public write_scripgrid - contains -!> Write a SCRIP grid file -!! -!! @param[in] fname the file name to write -!! @param[in] cstagger the name of the stagger location -!! @param[in] imask (optional) the land mask values -!! -!! @author Denise.Worthen@noaa.gov - +contains + !> Write a SCRIP grid file + !! + !! @param[in] fname the file name to write + !! @param[in] cstagger the name of the stagger location + !! @param[in] imask (optional) the land mask values + !! + !! @author Denise.Worthen@noaa.gov + subroutine write_scripgrid(fname,cstagger, imask) - character(len=*) , intent(in) :: fname - character(len=*) , intent(in) :: cstagger - integer(int_kind), optional, intent(in) :: imask(:,:) - - ! local variables - integer, parameter :: grid_rank = 2 - - integer :: ii,n,id,rc, ncid, dim2(2),dim1(1) - integer :: idimid,jdimid,kdimid - - integer, dimension(grid_rank) :: gdims - integer(int_kind), dimension(ni*nj) :: cnmask !1-d mask - real(dbl_kind), dimension(ni*nj) :: cnlons, cnlats !1-d center lats,lons - real(dbl_kind), dimension(nv,ni*nj) :: crlons, crlats !2-d corner lats,lons - - real(dbl_kind), dimension(ni,nj) :: tmp - - character(len=2) :: vtype - character(len=CM) :: vname - character(len=CM) :: vunit - -!--------------------------------------------------------------------- -! -!--------------------------------------------------------------------- - - gdims(:) = (/ni,nj/) - if(trim(cstagger) .eq. 'Ct')then - cnlons = reshape(lonCt, (/ni*nj/)) - cnlats = reshape(latCt, (/ni*nj/)) - do n = 1,nv - tmp(:,:) = lonCt_vert(:,:,n) - crlons(n,:) = reshape(tmp, (/ni*nj/)) - tmp(:,:) = latCt_vert(:,:,n) - crlats(n,:) = reshape(tmp, (/ni*nj/)) - end do - end if - - if(trim(cstagger) .eq. 'Cu')then - cnlons = reshape(lonCu, (/ni*nj/)) - cnlats = reshape(latCu, (/ni*nj/)) - do n = 1,nv - tmp(:,:) = lonCu_vert(:,:,n) - crlons(n,:) = reshape(tmp, (/ni*nj/)) - tmp(:,:) = latCu_vert(:,:,n) - crlats(n,:) = reshape(tmp, (/ni*nj/)) - end do - end if - - if(trim(cstagger) .eq. 'Cv')then - cnlons = reshape(lonCv, (/ni*nj/)) - cnlats = reshape(latCv, (/ni*nj/)) - do n = 1,nv - tmp(:,:) = lonCv_vert(:,:,n) - crlons(n,:) = reshape(tmp, (/ni*nj/)) - tmp(:,:) = latCv_vert(:,:,n) - crlats(n,:) = reshape(tmp, (/ni*nj/)) - end do - end if - - if(trim(cstagger) .eq. 'Bu')then - cnlons = reshape(lonBu, (/ni*nj/)) - cnlats = reshape(latBu, (/ni*nj/)) - do n = 1,nv - tmp(:,:) = lonBu_vert(:,:,n) - crlons(n,:) = reshape(tmp, (/ni*nj/)) - tmp(:,:) = latBu_vert(:,:,n) - crlats(n,:) = reshape(tmp, (/ni*nj/)) - end do - end if - - if(present(imask))then - cnmask = reshape(imask, (/ni*nj/)) - else - cnmask = 1 - end if - -!--------------------------------------------------------------------- -! create the netcdf file -!--------------------------------------------------------------------- - - ! define the output variables and file name - call scripvars_typedefine - ! create the file - ! 64_bit offset reqd for 008 grid - ! produces b4b results for smaller grids - rc = nf90_create(trim(fname), nf90_64bit_offset, ncid) - if(mastertask) then + character(len=*) , intent(in) :: fname + character(len=*) , intent(in) :: cstagger + integer(int_kind), optional, intent(in) :: imask(:,:) + + ! local variables + integer, parameter :: grid_rank = 2 + + integer :: ii,n,id,rc, ncid, dim2(2),dim1(1) + integer :: idimid,jdimid,kdimid + + integer, dimension(grid_rank) :: gdims + integer(int_kind), dimension(ni*nj) :: cnmask !1-d mask + real(dbl_kind), dimension(ni*nj) :: cnlons, cnlats !1-d center lats,lons + real(dbl_kind), dimension(nv,ni*nj) :: crlons, crlats !2-d corner lats,lons + + real(dbl_kind), dimension(ni,nj) :: tmp + + character(len=2) :: vtype + character(len=CM) :: vname + character(len=CM) :: vunit + + !--------------------------------------------------------------------- + ! + !--------------------------------------------------------------------- + + gdims(:) = (/ni,nj/) + if(trim(cstagger) .eq. 'Ct')then + cnlons = reshape(lonCt, (/ni*nj/)) + cnlats = reshape(latCt, (/ni*nj/)) + do n = 1,nv + tmp(:,:) = lonCt_vert(:,:,n) + crlons(n,:) = reshape(tmp, (/ni*nj/)) + tmp(:,:) = latCt_vert(:,:,n) + crlats(n,:) = reshape(tmp, (/ni*nj/)) + end do + end if + + if(trim(cstagger) .eq. 'Cu')then + cnlons = reshape(lonCu, (/ni*nj/)) + cnlats = reshape(latCu, (/ni*nj/)) + do n = 1,nv + tmp(:,:) = lonCu_vert(:,:,n) + crlons(n,:) = reshape(tmp, (/ni*nj/)) + tmp(:,:) = latCu_vert(:,:,n) + crlats(n,:) = reshape(tmp, (/ni*nj/)) + end do + end if + + if(trim(cstagger) .eq. 'Cv')then + cnlons = reshape(lonCv, (/ni*nj/)) + cnlats = reshape(latCv, (/ni*nj/)) + do n = 1,nv + tmp(:,:) = lonCv_vert(:,:,n) + crlons(n,:) = reshape(tmp, (/ni*nj/)) + tmp(:,:) = latCv_vert(:,:,n) + crlats(n,:) = reshape(tmp, (/ni*nj/)) + end do + end if + + if(trim(cstagger) .eq. 'Bu')then + cnlons = reshape(lonBu, (/ni*nj/)) + cnlats = reshape(latBu, (/ni*nj/)) + do n = 1,nv + tmp(:,:) = lonBu_vert(:,:,n) + crlons(n,:) = reshape(tmp, (/ni*nj/)) + tmp(:,:) = latBu_vert(:,:,n) + crlats(n,:) = reshape(tmp, (/ni*nj/)) + end do + end if + + if(present(imask))then + cnmask = reshape(imask, (/ni*nj/)) + else + cnmask = 1 + end if + + !--------------------------------------------------------------------- + ! create the netcdf file + !--------------------------------------------------------------------- + + ! define the output variables and file name + call scripvars_typedefine + ! create the file + ! 64_bit offset reqd for 008 grid + ! produces b4b results for smaller grids + rc = nf90_create(trim(fname), nf90_64bit_offset, ncid) logmsg = '==> writing SCRIP grid to '//trim(fname) print '(a)',trim(logmsg) if(rc .ne. 0)print '(a)', 'nf90_create = '//trim(nf90_strerror(rc)) - end if - - rc = nf90_def_dim(ncid, 'grid_size', ni*nj, idimid) - rc = nf90_def_dim(ncid, 'grid_corners', nv, jdimid) - rc = nf90_def_dim(ncid, 'grid_rank', grid_rank, kdimid) - - !grid_dims - dim1(:) = (/kdimid/) - rc = nf90_def_var(ncid, 'grid_dims', nf90_int, dim1, id) - ! mask - dim1(:) = (/idimid/) - rc = nf90_def_var(ncid, 'grid_imask', nf90_int, dim1, id) - rc = nf90_put_att(ncid, id, 'units', 'unitless') - - ! centers - do ii = 1,2 - vname = trim(scripvars(ii)%var_name) - vunit = trim(scripvars(ii)%unit_name) - vtype = trim(scripvars(ii)%var_type) - dim1(:) = (/idimid/) - if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim1, id) - if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim1, id) - if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim1, id) - rc = nf90_put_att(ncid, id, 'units', vunit) - enddo - - ! corners - do ii = 3,4 - vname = trim(scripvars(ii)%var_name) - vunit = trim(scripvars(ii)%unit_name) - vtype = trim(scripvars(ii)%var_type) - dim2(:) = (/jdimid,idimid/) - if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) - if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim2, id) - if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim2, id) - rc = nf90_put_att(ncid, id, 'units', vunit) - enddo - rc = nf90_enddef(ncid) - - rc = nf90_inq_varid(ncid, 'grid_dims', id) - rc = nf90_put_var(ncid, id, gdims) - rc = nf90_inq_varid(ncid, 'grid_imask', id) - rc = nf90_put_var(ncid, id, cnmask) - - rc = nf90_inq_varid(ncid, 'grid_center_lon', id) - rc = nf90_put_var(ncid, id, cnlons) - rc = nf90_inq_varid(ncid, 'grid_center_lat', id) - rc = nf90_put_var(ncid, id, cnlats) - - rc = nf90_inq_varid(ncid, 'grid_corner_lon', id) - rc = nf90_put_var(ncid, id, crlons) - rc = nf90_inq_varid(ncid, 'grid_corner_lat', id) - rc = nf90_put_var(ncid, id, crlats) - - rc = nf90_close(ncid) + + rc = nf90_def_dim(ncid, 'grid_size', ni*nj, idimid) + rc = nf90_def_dim(ncid, 'grid_corners', nv, jdimid) + rc = nf90_def_dim(ncid, 'grid_rank', grid_rank, kdimid) + + !grid_dims + dim1(:) = (/kdimid/) + rc = nf90_def_var(ncid, 'grid_dims', nf90_int, dim1, id) + ! mask + dim1(:) = (/idimid/) + rc = nf90_def_var(ncid, 'grid_imask', nf90_int, dim1, id) + rc = nf90_put_att(ncid, id, 'units', 'unitless') + + ! centers + do ii = 1,2 + vname = trim(scripvars(ii)%var_name) + vunit = trim(scripvars(ii)%unit_name) + vtype = trim(scripvars(ii)%var_type) + dim1(:) = (/idimid/) + if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim1, id) + if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim1, id) + if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim1, id) + rc = nf90_put_att(ncid, id, 'units', vunit) + enddo + + ! corners + do ii = 3,4 + vname = trim(scripvars(ii)%var_name) + vunit = trim(scripvars(ii)%unit_name) + vtype = trim(scripvars(ii)%var_type) + dim2(:) = (/jdimid,idimid/) + if(vtype .eq. 'r8')rc = nf90_def_var(ncid, vname, nf90_double, dim2, id) + if(vtype .eq. 'r4')rc = nf90_def_var(ncid, vname, nf90_float, dim2, id) + if(vtype .eq. 'i4')rc = nf90_def_var(ncid, vname, nf90_int, dim2, id) + rc = nf90_put_att(ncid, id, 'units', vunit) + enddo + rc = nf90_enddef(ncid) + + rc = nf90_inq_varid(ncid, 'grid_dims', id) + rc = nf90_put_var(ncid, id, gdims) + rc = nf90_inq_varid(ncid, 'grid_imask', id) + rc = nf90_put_var(ncid, id, cnmask) + + rc = nf90_inq_varid(ncid, 'grid_center_lon', id) + rc = nf90_put_var(ncid, id, cnlons) + rc = nf90_inq_varid(ncid, 'grid_center_lat', id) + rc = nf90_put_var(ncid, id, cnlats) + + rc = nf90_inq_varid(ncid, 'grid_corner_lon', id) + rc = nf90_put_var(ncid, id, crlons) + rc = nf90_inq_varid(ncid, 'grid_corner_lat', id) + rc = nf90_put_var(ncid, id, crlats) + + rc = nf90_close(ncid) end subroutine write_scripgrid end module scripgrid diff --git a/sorc/cpld_gridgen.fd/topoedits.F90 b/sorc/cpld_gridgen.fd/topoedits.F90 index 927c3fba2..6e1889474 100644 --- a/sorc/cpld_gridgen.fd/topoedits.F90 +++ b/sorc/cpld_gridgen.fd/topoedits.F90 @@ -9,7 +9,7 @@ module topoedits use gengrid_kinds, only: real_kind,int_kind - use grdvars, only: ni,nj,mastertask + use grdvars, only: ni,nj use grdvars, only: wet4,dp4,minimum_depth,maximum_depth,masking_depth use charstrings, only: logmsg,history use netcdf @@ -20,208 +20,208 @@ module topoedits public add_topoedits public apply_topoedits - contains -!> Read the existing topoedits file, append required topoedits and write a new topoedits file. Use the new topoedits -!! to adjust the land mask used in subsequent steps to match the land mask which will be created at run time -!! -!! @param[in] fsrc the existing topoedits file name -!! @param[out] fdst the modified topoedits file name -!! -!! @author Denise.Worthen@noaa.gov - +contains + !> Read the existing topoedits file, append required topoedits and write a new topoedits file. Use the new topoedits + !! to adjust the land mask used in subsequent steps to match the land mask which will be created at run time + !! + !! @param[in] fsrc the existing topoedits file name + !! @param[out] fdst the modified topoedits file name + !! + !! @author Denise.Worthen@noaa.gov + subroutine add_topoedits(fsrc,fdst) - character(len=*), intent(in) :: fsrc, fdst - - ! local variables - integer :: rc,id,i,j,ii,jj,ncid,dimid,idimid,dim1(1) - integer :: cnt1=0, cnt2=0, icnt - integer(int_kind), allocatable, dimension(:) :: ieds1, jeds1, ieds2, jeds2 - real(real_kind), allocatable, dimension(:) :: zeds1, zeds2 - -!--------------------------------------------------------------------- -! read existing topo edits -!--------------------------------------------------------------------- - - rc = nf90_open(trim(fsrc), nf90_nowrite, ncid) - print '(a)','using topo edits file '//trim(fsrc)//' to edit land mask ' - - rc = nf90_inq_dimid(ncid, 'nEdits', dimid) - rc = nf90_inquire_dimension(ncid, dimid, len=cnt1) - rc = nf90_close(ncid) - - ! return the existing values - allocate(ieds1(cnt1)); ieds1 = 0 - allocate(jeds1(cnt1)); jeds2 = 0 - allocate(zeds1(cnt1)); zeds2 = 0.0 - - rc = nf90_open(fsrc, nf90_nowrite, ncid) - rc = nf90_inq_varid(ncid, 'iEdit', id) - rc = nf90_get_var(ncid, id, ieds1) - rc = nf90_inq_varid(ncid, 'jEdit', id) - rc = nf90_get_var(ncid, id, jeds1) - rc = nf90_inq_varid(ncid, 'zEdit', id) - rc = nf90_get_var(ncid, id, zeds1) - rc = nf90_close(ncid) - -!--------------------------------------------------------------------- -! determine the number of points to be added to topo-edits file -! check only j=1 now -!--------------------------------------------------------------------- - - icnt = 0 - j = 1 - do i = 1,ni - if(wet4(i,j) .eq. 1.0)icnt = icnt+1 - end do - cnt2 = cnt2+icnt - print '(a,i4,a,i4)', 'found ',icnt,' open water points at j=1 , cnt2 = ',cnt2 - - cnt2 = cnt1 + cnt2 - ! allocate space for existing+new values and copy in original values - allocate(ieds2(cnt2)); ieds2 = 0 - allocate(jeds2(cnt2)); jeds2 = 0 - allocate(zeds2(cnt2)); zeds2 = 0.0 - - ieds2(1:cnt1) = ieds1(1:cnt1) - jeds2(1:cnt1) = jeds1(1:cnt1) - zeds2(1:cnt1) = zeds1(1:cnt1) - -!--------------------------------------------------------------------- -! fill in new values and write new topoedits file -!--------------------------------------------------------------------- - - icnt = cnt1 - j = 1 - do i = 1,ni - if(wet4(i,j) .eq. 1.0)then - icnt = icnt+1 - ii = i-1; jj = j-1 - ieds2(icnt) = ii - jeds2(icnt) = jj - zeds2(icnt) = 0.0 - end if - end do - - !do i = 1,cnt2 - ! print '(3i5,f12.4)',i,ieds2(i),jeds2(i),zeds2(i) - !end do - - rc = nf90_create(fdst, nf90_write, ncid) - print '(a)', 'writing new topo edits to '//trim(fdst) - - rc = nf90_def_dim(ncid, 'nEdits', cnt2, idimid) - - rc = nf90_def_var(ncid, 'ni', nf90_int, id) - rc = nf90_def_var(ncid, 'nj', nf90_int, id) - - dim1(:) = (/idimid/) - rc = nf90_def_var(ncid, 'iEdit', nf90_int, dim1, id) - rc = nf90_def_var(ncid, 'jEdit', nf90_int, dim1, id) - rc = nf90_def_var(ncid, 'zEdit', nf90_float, dim1, id) - rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) - rc = nf90_enddef(ncid) - - rc = nf90_inq_varid(ncid, 'ni', id) - rc = nf90_put_var(ncid, id, ni) - rc = nf90_inq_varid(ncid, 'nj', id) - rc = nf90_put_var(ncid, id, nj) - - rc = nf90_inq_varid(ncid, 'iEdit', id) - rc = nf90_put_var(ncid, id, ieds2) - rc = nf90_inq_varid(ncid, 'jEdit', id) - rc = nf90_put_var(ncid, id, jeds2) - rc = nf90_inq_varid(ncid, 'zEdit', id) - rc = nf90_put_var(ncid, id, zeds2) - - rc = nf90_close(ncid) - -!--------------------------------------------------------------------- -! adjust land mask by same edits used at run time -!--------------------------------------------------------------------- - - do i = 1,cnt2 - ii = ieds2(i); jj = jeds2(i) - if(wet4(ii+1,jj+1) .eq. 0.0 .and. zeds2(i) .gt. 0.0) then - wet4(ii+1,jj+1) = 1.0 - print '(a,2i4,a)', 'switch point ',ii+1,jj+1,' from land->ocean at runtime' - end if - if(wet4(ii+1,jj+1) .eq. 1.0 .and. zeds2(i) .eq. 0.0) then - wet4(ii+1,jj+1) = 0.0 - print '(a,2i4,a)', 'switch point ',ii+1,jj+1,' from ocean->land at runtime' - end if - end do - deallocate(ieds1, jeds1, zeds1) - deallocate(ieds2, jeds2, zeds2) + character(len=*), intent(in) :: fsrc, fdst + + ! local variables + integer :: rc,id,i,j,ii,jj,ncid,dimid,idimid,dim1(1) + integer :: cnt1=0, cnt2=0, icnt + integer(int_kind), allocatable, dimension(:) :: ieds1, jeds1, ieds2, jeds2 + real(real_kind), allocatable, dimension(:) :: zeds1, zeds2 + + !--------------------------------------------------------------------- + ! read existing topo edits + !--------------------------------------------------------------------- + + rc = nf90_open(trim(fsrc), nf90_nowrite, ncid) + print '(a)','using topo edits file '//trim(fsrc)//' to edit land mask ' + + rc = nf90_inq_dimid(ncid, 'nEdits', dimid) + rc = nf90_inquire_dimension(ncid, dimid, len=cnt1) + rc = nf90_close(ncid) + + ! return the existing values + allocate(ieds1(cnt1)); ieds1 = 0 + allocate(jeds1(cnt1)); jeds2 = 0 + allocate(zeds1(cnt1)); zeds2 = 0.0 + + rc = nf90_open(fsrc, nf90_nowrite, ncid) + rc = nf90_inq_varid(ncid, 'iEdit', id) + rc = nf90_get_var(ncid, id, ieds1) + rc = nf90_inq_varid(ncid, 'jEdit', id) + rc = nf90_get_var(ncid, id, jeds1) + rc = nf90_inq_varid(ncid, 'zEdit', id) + rc = nf90_get_var(ncid, id, zeds1) + rc = nf90_close(ncid) + + !--------------------------------------------------------------------- + ! determine the number of points to be added to topo-edits file + ! check only j=1 now + !--------------------------------------------------------------------- + + icnt = 0 + j = 1 + do i = 1,ni + if(wet4(i,j) .eq. 1.0)icnt = icnt+1 + end do + cnt2 = cnt2+icnt + print '(a,i4,a,i4)', 'found ',icnt,' open water points at j=1 , cnt2 = ',cnt2 + + cnt2 = cnt1 + cnt2 + ! allocate space for existing+new values and copy in original values + allocate(ieds2(cnt2)); ieds2 = 0 + allocate(jeds2(cnt2)); jeds2 = 0 + allocate(zeds2(cnt2)); zeds2 = 0.0 + + ieds2(1:cnt1) = ieds1(1:cnt1) + jeds2(1:cnt1) = jeds1(1:cnt1) + zeds2(1:cnt1) = zeds1(1:cnt1) + + !--------------------------------------------------------------------- + ! fill in new values and write new topoedits file + !--------------------------------------------------------------------- + + icnt = cnt1 + j = 1 + do i = 1,ni + if(wet4(i,j) .eq. 1.0)then + icnt = icnt+1 + ii = i-1; jj = j-1 + ieds2(icnt) = ii + jeds2(icnt) = jj + zeds2(icnt) = 0.0 + end if + end do + + !do i = 1,cnt2 + ! print '(3i5,f12.4)',i,ieds2(i),jeds2(i),zeds2(i) + !end do + + rc = nf90_create(fdst, nf90_write, ncid) + print '(a)', 'writing new topo edits to '//trim(fdst) + + rc = nf90_def_dim(ncid, 'nEdits', cnt2, idimid) + + rc = nf90_def_var(ncid, 'ni', nf90_int, id) + rc = nf90_def_var(ncid, 'nj', nf90_int, id) + + dim1(:) = (/idimid/) + rc = nf90_def_var(ncid, 'iEdit', nf90_int, dim1, id) + rc = nf90_def_var(ncid, 'jEdit', nf90_int, dim1, id) + rc = nf90_def_var(ncid, 'zEdit', nf90_float, dim1, id) + rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) + rc = nf90_enddef(ncid) + + rc = nf90_inq_varid(ncid, 'ni', id) + rc = nf90_put_var(ncid, id, ni) + rc = nf90_inq_varid(ncid, 'nj', id) + rc = nf90_put_var(ncid, id, nj) + + rc = nf90_inq_varid(ncid, 'iEdit', id) + rc = nf90_put_var(ncid, id, ieds2) + rc = nf90_inq_varid(ncid, 'jEdit', id) + rc = nf90_put_var(ncid, id, jeds2) + rc = nf90_inq_varid(ncid, 'zEdit', id) + rc = nf90_put_var(ncid, id, zeds2) + + rc = nf90_close(ncid) + + !--------------------------------------------------------------------- + ! adjust land mask by same edits used at run time + !--------------------------------------------------------------------- + + do i = 1,cnt2 + ii = ieds2(i); jj = jeds2(i) + if(wet4(ii+1,jj+1) .eq. 0.0 .and. zeds2(i) .gt. 0.0) then + wet4(ii+1,jj+1) = 1.0 + print '(a,2i4,a)', 'switch point ',ii+1,jj+1,' from land->ocean at runtime' + end if + if(wet4(ii+1,jj+1) .eq. 1.0 .and. zeds2(i) .eq. 0.0) then + wet4(ii+1,jj+1) = 0.0 + print '(a,2i4,a)', 'switch point ',ii+1,jj+1,' from ocean->land at runtime' + end if + end do + deallocate(ieds1, jeds1, zeds1) + deallocate(ieds2, jeds2, zeds2) end subroutine add_topoedits -!> Read the topoedits file and adjust the bathymetry. Apply limits to bathymetry. -!! -!! @param[in] fsrc the topoedits file name -!! -!! @author Denise.Worthen@noaa.gov + !> Read the topoedits file and adjust the bathymetry. Apply limits to bathymetry. + !! + !! @param[in] fsrc the topoedits file name + !! + !! @author Denise.Worthen@noaa.gov subroutine apply_topoedits(fsrc) - character(len=*), intent(in) :: fsrc - - ! local variables - integer :: rc,ncid,id,dimid,i,j,ii,jj,cnt1 - integer(int_kind), allocatable, dimension(:) :: ieds1, jeds1 - real(real_kind), allocatable, dimension(:) :: zeds1 - - logical :: file_exists -!--------------------------------------------------------------------- -! read and apply topo edits file, if any -!--------------------------------------------------------------------- - - inquire(file=trim(fsrc),exist=file_exists) - if (file_exists) then - rc = nf90_open(trim(fsrc), nf90_nowrite, ncid) - print '(a)','using topo edits file '//trim(fsrc)//' to adjust bathymetry ' - - rc = nf90_inq_dimid(ncid, 'nEdits', dimid) - rc = nf90_inquire_dimension(ncid, dimid, len=cnt1) - rc = nf90_close(ncid) - - ! return the existing values - allocate(ieds1(cnt1)) - allocate(jeds1(cnt1)) - allocate(zeds1(cnt1)) - - rc = nf90_open(fsrc, nf90_nowrite, ncid) - rc = nf90_inq_varid(ncid, 'iEdit', id) - rc = nf90_get_var(ncid, id, ieds1) - rc = nf90_inq_varid(ncid, 'jEdit', id) - rc = nf90_get_var(ncid, id, jeds1) - rc = nf90_inq_varid(ncid, 'zEdit', id) - rc = nf90_get_var(ncid, id, zeds1) - rc = nf90_close(ncid) - - ! apply topo edits from file - do i = 1,cnt1 - ii = ieds1(i); jj = jeds1(i) - print '(a,3i5,f8.2,a,f8.2)', 'Ocean topography edit: ', i, ii+1, jj+1 , dp4(ii+1,jj+1), '->', abs(zeds1(i)) - dp4(ii+1,jj+1) = abs(zeds1(i)) - end do - deallocate(ieds1, jeds1, zeds1) - end if - -!--------------------------------------------------------------------- -! limit topography -!--------------------------------------------------------------------- - - print '(a)', 'Applying topo limits to ensure that min_depth < D(x,y) < max_depth ' - print '(a, f8.2)', 'Using min_depth = ',minimum_depth - print '(a, f8.2)', 'Using max_depth = ',maximum_depth - do j = 1,nj - do i = 1,ni - if(dp4(i,j) > min(minimum_depth,masking_depth))then - dp4(i,j) = min( max(dp4(i,j), minimum_depth), maximum_depth) - end if - end do - end do + character(len=*), intent(in) :: fsrc + + ! local variables + integer :: rc,ncid,id,dimid,i,j,ii,jj,cnt1 + integer(int_kind), allocatable, dimension(:) :: ieds1, jeds1 + real(real_kind), allocatable, dimension(:) :: zeds1 + + logical :: file_exists + !--------------------------------------------------------------------- + ! read and apply topo edits file, if any + !--------------------------------------------------------------------- + + inquire(file=trim(fsrc),exist=file_exists) + if (file_exists) then + rc = nf90_open(trim(fsrc), nf90_nowrite, ncid) + print '(a)','using topo edits file '//trim(fsrc)//' to adjust bathymetry ' + + rc = nf90_inq_dimid(ncid, 'nEdits', dimid) + rc = nf90_inquire_dimension(ncid, dimid, len=cnt1) + rc = nf90_close(ncid) + + ! return the existing values + allocate(ieds1(cnt1)) + allocate(jeds1(cnt1)) + allocate(zeds1(cnt1)) + + rc = nf90_open(fsrc, nf90_nowrite, ncid) + rc = nf90_inq_varid(ncid, 'iEdit', id) + rc = nf90_get_var(ncid, id, ieds1) + rc = nf90_inq_varid(ncid, 'jEdit', id) + rc = nf90_get_var(ncid, id, jeds1) + rc = nf90_inq_varid(ncid, 'zEdit', id) + rc = nf90_get_var(ncid, id, zeds1) + rc = nf90_close(ncid) + + ! apply topo edits from file + do i = 1,cnt1 + ii = ieds1(i); jj = jeds1(i) + print '(a,3i5,f8.2,a,f8.2)', 'Ocean topography edit: ', i, ii+1, jj+1 , dp4(ii+1,jj+1), '->', abs(zeds1(i)) + dp4(ii+1,jj+1) = abs(zeds1(i)) + end do + deallocate(ieds1, jeds1, zeds1) + end if + + !--------------------------------------------------------------------- + ! limit topography + !--------------------------------------------------------------------- + + print '(a)', 'Applying topo limits to ensure that min_depth < D(x,y) < max_depth ' + print '(a, f8.2)', 'Using min_depth = ',minimum_depth + print '(a, f8.2)', 'Using max_depth = ',maximum_depth + do j = 1,nj + do i = 1,ni + if(dp4(i,j) > min(minimum_depth,masking_depth))then + dp4(i,j) = min( max(dp4(i,j), minimum_depth), maximum_depth) + end if + end do + end do end subroutine apply_topoedits end module topoedits diff --git a/sorc/cpld_gridgen.fd/tripolegrid.F90 b/sorc/cpld_gridgen.fd/tripolegrid.F90 index 7161ee0d5..feb287101 100644 --- a/sorc/cpld_gridgen.fd/tripolegrid.F90 +++ b/sorc/cpld_gridgen.fd/tripolegrid.F90 @@ -2,13 +2,13 @@ !! @brief Write the tripole grid file !! @author Denise.Worthen@noaa.gov !! -!> This module writes the master tripole grid file +!> This module writes the main tripole grid file !! @author Denise.Worthen@noaa.gov module tripolegrid use gengrid_kinds, only: dbl_kind,int_kind,CM - use grdvars, only: ni,nj,nv,mastertask,nverts,ncoord + use grdvars, only: ni,nj,nv,nverts,ncoord use grdvars, only: lonCt,latCt,lonCt_vert,latCt_vert use grdvars, only: lonCu,latCu,lonCu_vert,latCu_vert use grdvars, only: lonCv,latCv,lonCv_vert,latCv_vert @@ -23,140 +23,138 @@ module tripolegrid public write_tripolegrid - contains -!> Write the tripole grid file -!! -!! @param[in] fname the name of the tripole grid file to write -!! -!! @author Denise.Worthen@noaa.gov - +contains + !> Write the tripole grid file + !! + !! @param[in] fname the name of the tripole grid file to write + !! + !! @author Denise.Worthen@noaa.gov + subroutine write_tripolegrid(fname) - character(len=*), intent(in) :: fname + character(len=*), intent(in) :: fname - ! local variables - integer :: ii,id,rc, ncid, dim2(2),dim3(3) - integer :: idimid,jdimid,kdimid + ! local variables + integer :: ii,id,rc, ncid, dim2(2),dim3(3) + integer :: idimid,jdimid,kdimid -!--------------------------------------------------------------------- -! create the netcdf file -!--------------------------------------------------------------------- + !--------------------------------------------------------------------- + ! create the netcdf file + !--------------------------------------------------------------------- - ! define the output variables and file name - call fixvars_typedefine + ! define the output variables and file name + call fixvars_typedefine - ! create the file - ! 64_bit offset reqd for 008 grid - ! produces b4b results for smaller grids - rc = nf90_create(trim(fname), nf90_64bit_offset, ncid) - if(mastertask) then + ! create the file + ! 64_bit offset reqd for 008 grid + ! produces b4b results for smaller grids + rc = nf90_create(trim(fname), nf90_64bit_offset, ncid) logmsg = '==> writing tripole grid to '//trim(fname) print '(a)', trim(logmsg) if(rc .ne. 0)print '(a)', 'nf90_create = '//trim(nf90_strerror(rc)) - end if - - rc = nf90_def_dim(ncid, 'ni', ni, idimid) - rc = nf90_def_dim(ncid, 'nj', nj, jdimid) - rc = nf90_def_dim(ncid, 'nv', nv, kdimid) - - !mask - dim2(:) = (/idimid, jdimid/) - rc = nf90_def_var(ncid, 'wet', nf90_int, dim2, id) - rc = nf90_put_att(ncid, id, 'units', 'nd') - !area - rc = nf90_def_var(ncid, 'area', nf90_double, dim2, id) - rc = nf90_put_att(ncid, id, 'units', 'm2') - !angleT - rc = nf90_def_var(ncid, 'anglet', nf90_double, dim2, id) - rc = nf90_put_att(ncid, id, 'units', 'radians') - !bathymetry - rc = nf90_def_var(ncid, 'depth', nf90_float, dim2, id) - rc = nf90_put_att(ncid, id, 'units', 'm') - - dim2(:) = (/idimid, jdimid/) - do ii = 1,ncoord - rc = nf90_def_var(ncid, trim(fixvars(ii)%var_name), nf90_double, dim2, id) - rc = nf90_put_att(ncid, id, 'units', trim(fixvars(ii)%unit_name)) - rc = nf90_put_att(ncid, id, 'long_name', trim(fixvars(ii)%long_name)) - if(trim(fixvars(ii)%var_name(1:3)) .eq. "lon")then - rc = nf90_put_att(ncid, id, 'lon_bounds', trim(fixvars(ii)%vertices)) - else - rc = nf90_put_att(ncid, id, 'lat_bounds', trim(fixvars(ii)%vertices)) - endif - enddo - - dim3(:) = (/idimid, jdimid, kdimid/) - do ii = ncoord+1,ncoord+nverts - rc = nf90_def_var(ncid, trim(fixvars(ii)%var_name), nf90_double, dim3, id) - rc = nf90_put_att(ncid, id, 'units', trim(fixvars(ii)%unit_name)) - rc = nf90_put_att(ncid, id, 'long_name', trim(fixvars(ii)%long_name)) - enddo - - rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) - rc = nf90_enddef(ncid) - - rc = nf90_inq_varid(ncid, 'wet', id) - rc = nf90_put_var(ncid, id, int(wet4)) - - rc = nf90_inq_varid(ncid, 'area', id) - rc = nf90_put_var(ncid, id, areaCt) - - rc = nf90_inq_varid(ncid,'anglet', id) - rc = nf90_put_var(ncid, id, anglet) - - rc = nf90_inq_varid(ncid, 'depth', id) - rc = nf90_put_var(ncid, id, dp4) - - rc = nf90_inq_varid(ncid, 'lonCt', id) - rc = nf90_put_var(ncid, id, lonCt) - - rc = nf90_inq_varid(ncid, 'latCt', id) - rc = nf90_put_var(ncid, id, latCt) - - rc = nf90_inq_varid(ncid, 'lonCv', id) - rc = nf90_put_var(ncid, id, lonCv) - - rc = nf90_inq_varid(ncid, 'latCv', id) - rc = nf90_put_var(ncid, id, latCv) - - rc = nf90_inq_varid(ncid, 'lonCu', id) - rc = nf90_put_var(ncid, id, lonCu) - - rc = nf90_inq_varid(ncid, 'latCu', id) - rc = nf90_put_var(ncid, id, latCu) - - rc = nf90_inq_varid(ncid, 'lonBu', id) - rc = nf90_put_var(ncid, id, lonBu) - - rc = nf90_inq_varid(ncid, 'latBu', id) - rc = nf90_put_var(ncid, id, latBu) - - ! vertices - rc = nf90_inq_varid(ncid, 'lonCt_vert', id) - rc = nf90_put_var(ncid, id, lonCt_vert) - - rc = nf90_inq_varid(ncid, 'latCt_vert', id) - rc = nf90_put_var(ncid, id, latCt_vert) - - rc = nf90_inq_varid(ncid, 'lonCv_vert', id) - rc = nf90_put_var(ncid, id, lonCv_vert) - - rc = nf90_inq_varid(ncid, 'latCv_vert', id) - rc = nf90_put_var(ncid, id, latCv_vert) - - rc = nf90_inq_varid(ncid, 'lonCu_vert', id) - rc = nf90_put_var(ncid, id, lonCu_vert) - - rc = nf90_inq_varid(ncid, 'latCu_vert', id) - rc = nf90_put_var(ncid, id, latCu_vert) - - rc = nf90_inq_varid(ncid, 'lonBu_vert', id) - rc = nf90_put_var(ncid, id, lonBu_vert) - - rc = nf90_inq_varid(ncid, 'latBu_vert', id) - rc = nf90_put_var(ncid, id, latBu_vert) - - rc = nf90_close(ncid) + + rc = nf90_def_dim(ncid, 'ni', ni, idimid) + rc = nf90_def_dim(ncid, 'nj', nj, jdimid) + rc = nf90_def_dim(ncid, 'nv', nv, kdimid) + + !mask + dim2(:) = (/idimid, jdimid/) + rc = nf90_def_var(ncid, 'wet', nf90_int, dim2, id) + rc = nf90_put_att(ncid, id, 'units', 'nd') + !area + rc = nf90_def_var(ncid, 'area', nf90_double, dim2, id) + rc = nf90_put_att(ncid, id, 'units', 'm2') + !angleT + rc = nf90_def_var(ncid, 'anglet', nf90_double, dim2, id) + rc = nf90_put_att(ncid, id, 'units', 'radians') + !bathymetry + rc = nf90_def_var(ncid, 'depth', nf90_float, dim2, id) + rc = nf90_put_att(ncid, id, 'units', 'm') + + dim2(:) = (/idimid, jdimid/) + do ii = 1,ncoord + rc = nf90_def_var(ncid, trim(fixvars(ii)%var_name), nf90_double, dim2, id) + rc = nf90_put_att(ncid, id, 'units', trim(fixvars(ii)%unit_name)) + rc = nf90_put_att(ncid, id, 'long_name', trim(fixvars(ii)%long_name)) + if(trim(fixvars(ii)%var_name(1:3)) .eq. "lon")then + rc = nf90_put_att(ncid, id, 'lon_bounds', trim(fixvars(ii)%vertices)) + else + rc = nf90_put_att(ncid, id, 'lat_bounds', trim(fixvars(ii)%vertices)) + endif + enddo + + dim3(:) = (/idimid, jdimid, kdimid/) + do ii = ncoord+1,ncoord+nverts + rc = nf90_def_var(ncid, trim(fixvars(ii)%var_name), nf90_double, dim3, id) + rc = nf90_put_att(ncid, id, 'units', trim(fixvars(ii)%unit_name)) + rc = nf90_put_att(ncid, id, 'long_name', trim(fixvars(ii)%long_name)) + enddo + + rc = nf90_put_att(ncid, nf90_global, 'history', trim(history)) + rc = nf90_enddef(ncid) + + rc = nf90_inq_varid(ncid, 'wet', id) + rc = nf90_put_var(ncid, id, int(wet4)) + + rc = nf90_inq_varid(ncid, 'area', id) + rc = nf90_put_var(ncid, id, areaCt) + + rc = nf90_inq_varid(ncid,'anglet', id) + rc = nf90_put_var(ncid, id, anglet) + + rc = nf90_inq_varid(ncid, 'depth', id) + rc = nf90_put_var(ncid, id, dp4) + + rc = nf90_inq_varid(ncid, 'lonCt', id) + rc = nf90_put_var(ncid, id, lonCt) + + rc = nf90_inq_varid(ncid, 'latCt', id) + rc = nf90_put_var(ncid, id, latCt) + + rc = nf90_inq_varid(ncid, 'lonCv', id) + rc = nf90_put_var(ncid, id, lonCv) + + rc = nf90_inq_varid(ncid, 'latCv', id) + rc = nf90_put_var(ncid, id, latCv) + + rc = nf90_inq_varid(ncid, 'lonCu', id) + rc = nf90_put_var(ncid, id, lonCu) + + rc = nf90_inq_varid(ncid, 'latCu', id) + rc = nf90_put_var(ncid, id, latCu) + + rc = nf90_inq_varid(ncid, 'lonBu', id) + rc = nf90_put_var(ncid, id, lonBu) + + rc = nf90_inq_varid(ncid, 'latBu', id) + rc = nf90_put_var(ncid, id, latBu) + + ! vertices + rc = nf90_inq_varid(ncid, 'lonCt_vert', id) + rc = nf90_put_var(ncid, id, lonCt_vert) + + rc = nf90_inq_varid(ncid, 'latCt_vert', id) + rc = nf90_put_var(ncid, id, latCt_vert) + + rc = nf90_inq_varid(ncid, 'lonCv_vert', id) + rc = nf90_put_var(ncid, id, lonCv_vert) + + rc = nf90_inq_varid(ncid, 'latCv_vert', id) + rc = nf90_put_var(ncid, id, latCv_vert) + + rc = nf90_inq_varid(ncid, 'lonCu_vert', id) + rc = nf90_put_var(ncid, id, lonCu_vert) + + rc = nf90_inq_varid(ncid, 'latCu_vert', id) + rc = nf90_put_var(ncid, id, latCu_vert) + + rc = nf90_inq_varid(ncid, 'lonBu_vert', id) + rc = nf90_put_var(ncid, id, lonBu_vert) + + rc = nf90_inq_varid(ncid, 'latBu_vert', id) + rc = nf90_put_var(ncid, id, latBu_vert) + + rc = nf90_close(ncid) end subroutine write_tripolegrid end module tripolegrid diff --git a/sorc/cpld_gridgen.fd/vartypedefs.F90 b/sorc/cpld_gridgen.fd/vartypedefs.F90 index 8e4b09985..388b6aef2 100644 --- a/sorc/cpld_gridgen.fd/vartypedefs.F90 +++ b/sorc/cpld_gridgen.fd/vartypedefs.F90 @@ -14,195 +14,195 @@ module vartypedefs integer, parameter :: maxvars = 20 !< The maximum number of variables written to a file type :: vardefs - character(len=CM) :: var_name !< A variable name - character(len=CM) :: long_name !< A variable's long name - character(len=CM) :: unit_name !< A variable's unit - character(len= 2) :: var_type !< A variable's type - character(len=CM) :: vertices !< A variable's vertices + character(len=CM) :: var_name !< A variable name + character(len=CM) :: long_name !< A variable's long name + character(len=CM) :: unit_name !< A variable's unit + character(len= 2) :: var_type !< A variable's type + character(len=CM) :: vertices !< A variable's vertices end type vardefs - type(vardefs) :: fixvars(maxvars) !< Attribute definitions for the variables written to the master tripole file + type(vardefs) :: fixvars(maxvars) !< Attribute definitions for the variables written to the main tripole file type(vardefs) :: cicevars(maxvars) !< Attribute definitions for the variables written to the CICE grid file type(vardefs) :: scripvars(maxvars) !< Attribute definitions for the variables written to any SCRIP file - contains +contains -!> Define the variables written to the tripole grid file -!! -!! @author Denise.Worthen@noaa.gov + !> Define the variables written to the tripole grid file + !! + !! @author Denise.Worthen@noaa.gov subroutine fixvars_typedefine - ! local variables - integer :: ii = 0 - - !default - fixvars(:)%var_type = 'r8' - fixvars(:)%vertices = '' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCt' - fixvars(ii)%long_name = 'Longitude of center (Ct) points' - fixvars(ii)%unit_name = 'degrees_east' - fixvars(ii)%vertices = 'lonCt_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCt' - fixvars(ii)%long_name = 'Latitude of center (Ct) points' - fixvars(ii)%unit_name = 'degrees_north' - fixvars(ii)%vertices = 'latCt_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCv' - fixvars(ii)%long_name = 'Longitude of meridional velocity (Cv) points' - fixvars(ii)%unit_name = 'degrees_east' - fixvars(ii)%vertices = 'lonCv_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCv' - fixvars(ii)%long_name = 'Latitude of meridional velocity (Cv) points' - fixvars(ii)%unit_name = 'degrees_north' - fixvars(ii)%vertices = 'latCv_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCu' - fixvars(ii)%long_name = 'Longitude of zonal velocity (Cu) points' - fixvars(ii)%unit_name = 'degrees_east' - fixvars(ii)%vertices = 'lonCu_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCu' - fixvars(ii)%long_name = 'Latitude of zonal velocity (Cu) points' - fixvars(ii)%unit_name = 'degrees_north' - fixvars(ii)%vertices = 'latCu_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonBu' - fixvars(ii)%long_name = 'Longitude of corner (Bu) points' - fixvars(ii)%unit_name = 'degrees_east' - fixvars(ii)%vertices = 'lonBu_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'latBu' - fixvars(ii)%long_name = 'Latitude of corner (Bu) points' - fixvars(ii)%unit_name = 'degrees_north' - fixvars(ii)%vertices = 'latBu_vert' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCt_vert' - fixvars(ii)%long_name = 'Longitude Vertices of Ct points' - fixvars(ii)%unit_name = 'degrees_east' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCt_vert' - fixvars(ii)%long_name = 'Latitude Vertices of Ct points' - fixvars(ii)%unit_name = 'degrees_north' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCu_vert' - fixvars(ii)%long_name = 'Longitude Vertices of Cu points' - fixvars(ii)%unit_name = 'degrees_east' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCu_vert' - fixvars(ii)%long_name = 'Latitude Vertices of Cu points' - fixvars(ii)%unit_name = 'degrees_north' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonCv_vert' - fixvars(ii)%long_name = 'Longitude Vertices of Cv points' - fixvars(ii)%unit_name = 'degrees_east' - - ii = ii + 1 - fixvars(ii)%var_name = 'latCv_vert' - fixvars(ii)%long_name = 'Latitude Vertices of Cv points' - fixvars(ii)%unit_name = 'degrees_north' - - ii = ii + 1 - fixvars(ii)%var_name = 'lonBu_vert' - fixvars(ii)%long_name = 'Longitude Vertices of Bu points' - fixvars(ii)%unit_name = 'degrees_east' - - ii = ii + 1 - fixvars(ii)%var_name = 'latBu_vert' - fixvars(ii)%long_name = 'Latitude Vertices of Bu points' - fixvars(ii)%unit_name = 'degrees_north' - - end subroutine fixvars_typedefine -!> Define the variables written to the CICE grid file -!! -!! @author Denise.Worthen@noaa.gov - - subroutine cicevars_typedefine - - ! local variables - integer :: ii = 0 - - !default - cicevars(:)%var_type = 'r8' - cicevars(:)%vertices = '' - - ii = ii + 1 - cicevars(ii)%var_name = 'ulon' - cicevars(ii)%long_name = 'Longitude of corner (Bu) points' - cicevars(ii)%unit_name = 'radians' - - ii = ii + 1 - cicevars(ii)%var_name = 'ulat' - cicevars(ii)%long_name = 'Latitude of corner (Bu) points' - cicevars(ii)%unit_name = 'radians' - - ii = ii + 1 - cicevars(ii)%var_name = 'hte' - cicevars(ii)%long_name = 'Distance between corner (Bu) points, east face' - cicevars(ii)%unit_name = 'cm' - - ii = ii + 1 - cicevars(ii)%var_name = 'htn' - cicevars(ii)%long_name = 'Distance between corner (Bu) points, north face' - cicevars(ii)%unit_name = 'cm' - - ii = ii + 1 - cicevars(ii)%var_name = 'angle' - cicevars(ii)%long_name = 'Angle at corner (Bu) points' - cicevars(ii)%unit_name = 'radians' - - ii = ii + 1 - cicevars(ii)%var_name = 'kmt' - cicevars(ii)%long_name = 'ocean fraction at T-cell centers' - cicevars(ii)%unit_name = 'none' - cicevars(ii)%var_type = 'i4' - - end subroutine cicevars_typedefine -!> Define the variables written to any SCRIP grid file -!! -!! @author Denise.Worthen@noaa.gov - - subroutine scripvars_typedefine - - ! local variables - integer :: ii = 0 - - !default - scripvars(:)%long_name = '' - scripvars(:)%var_type = 'r8' - scripvars(:)%vertices = '' - - ii = ii + 1 - scripvars(ii)%var_name = 'grid_center_lat' - scripvars(ii)%unit_name = 'degrees' - - ii = ii + 1 - scripvars(ii)%var_name = 'grid_center_lon' - scripvars(ii)%unit_name = 'degrees' - - ii = ii + 1 - scripvars(ii)%var_name = 'grid_corner_lat' - scripvars(ii)%unit_name = 'degrees' - - ii = ii + 1 - scripvars(ii)%var_name = 'grid_corner_lon' - scripvars(ii)%unit_name = 'degrees' - - end subroutine scripvars_typedefine + ! local variables + integer :: ii = 0 + + !default + fixvars(:)%var_type = 'r8' + fixvars(:)%vertices = '' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCt' + fixvars(ii)%long_name = 'Longitude of center (Ct) points' + fixvars(ii)%unit_name = 'degrees_east' + fixvars(ii)%vertices = 'lonCt_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCt' + fixvars(ii)%long_name = 'Latitude of center (Ct) points' + fixvars(ii)%unit_name = 'degrees_north' + fixvars(ii)%vertices = 'latCt_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCv' + fixvars(ii)%long_name = 'Longitude of meridional velocity (Cv) points' + fixvars(ii)%unit_name = 'degrees_east' + fixvars(ii)%vertices = 'lonCv_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCv' + fixvars(ii)%long_name = 'Latitude of meridional velocity (Cv) points' + fixvars(ii)%unit_name = 'degrees_north' + fixvars(ii)%vertices = 'latCv_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCu' + fixvars(ii)%long_name = 'Longitude of zonal velocity (Cu) points' + fixvars(ii)%unit_name = 'degrees_east' + fixvars(ii)%vertices = 'lonCu_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCu' + fixvars(ii)%long_name = 'Latitude of zonal velocity (Cu) points' + fixvars(ii)%unit_name = 'degrees_north' + fixvars(ii)%vertices = 'latCu_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonBu' + fixvars(ii)%long_name = 'Longitude of corner (Bu) points' + fixvars(ii)%unit_name = 'degrees_east' + fixvars(ii)%vertices = 'lonBu_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'latBu' + fixvars(ii)%long_name = 'Latitude of corner (Bu) points' + fixvars(ii)%unit_name = 'degrees_north' + fixvars(ii)%vertices = 'latBu_vert' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCt_vert' + fixvars(ii)%long_name = 'Longitude Vertices of Ct points' + fixvars(ii)%unit_name = 'degrees_east' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCt_vert' + fixvars(ii)%long_name = 'Latitude Vertices of Ct points' + fixvars(ii)%unit_name = 'degrees_north' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCu_vert' + fixvars(ii)%long_name = 'Longitude Vertices of Cu points' + fixvars(ii)%unit_name = 'degrees_east' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCu_vert' + fixvars(ii)%long_name = 'Latitude Vertices of Cu points' + fixvars(ii)%unit_name = 'degrees_north' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonCv_vert' + fixvars(ii)%long_name = 'Longitude Vertices of Cv points' + fixvars(ii)%unit_name = 'degrees_east' + + ii = ii + 1 + fixvars(ii)%var_name = 'latCv_vert' + fixvars(ii)%long_name = 'Latitude Vertices of Cv points' + fixvars(ii)%unit_name = 'degrees_north' + + ii = ii + 1 + fixvars(ii)%var_name = 'lonBu_vert' + fixvars(ii)%long_name = 'Longitude Vertices of Bu points' + fixvars(ii)%unit_name = 'degrees_east' + + ii = ii + 1 + fixvars(ii)%var_name = 'latBu_vert' + fixvars(ii)%long_name = 'Latitude Vertices of Bu points' + fixvars(ii)%unit_name = 'degrees_north' + + end subroutine fixvars_typedefine + !> Define the variables written to the CICE grid file + !! + !! @author Denise.Worthen@noaa.gov + + subroutine cicevars_typedefine + + ! local variables + integer :: ii = 0 + + !default + cicevars(:)%var_type = 'r8' + cicevars(:)%vertices = '' + + ii = ii + 1 + cicevars(ii)%var_name = 'ulon' + cicevars(ii)%long_name = 'Longitude of corner (Bu) points' + cicevars(ii)%unit_name = 'radians' + + ii = ii + 1 + cicevars(ii)%var_name = 'ulat' + cicevars(ii)%long_name = 'Latitude of corner (Bu) points' + cicevars(ii)%unit_name = 'radians' + + ii = ii + 1 + cicevars(ii)%var_name = 'hte' + cicevars(ii)%long_name = 'Distance between corner (Bu) points, east face' + cicevars(ii)%unit_name = 'cm' + + ii = ii + 1 + cicevars(ii)%var_name = 'htn' + cicevars(ii)%long_name = 'Distance between corner (Bu) points, north face' + cicevars(ii)%unit_name = 'cm' + + ii = ii + 1 + cicevars(ii)%var_name = 'angle' + cicevars(ii)%long_name = 'Angle at corner (Bu) points' + cicevars(ii)%unit_name = 'radians' + + ii = ii + 1 + cicevars(ii)%var_name = 'kmt' + cicevars(ii)%long_name = 'ocean fraction at T-cell centers' + cicevars(ii)%unit_name = 'none' + cicevars(ii)%var_type = 'i4' + + end subroutine cicevars_typedefine + !> Define the variables written to any SCRIP grid file + !! + !! @author Denise.Worthen@noaa.gov + + subroutine scripvars_typedefine + + ! local variables + integer :: ii = 0 + + !default + scripvars(:)%long_name = '' + scripvars(:)%var_type = 'r8' + scripvars(:)%vertices = '' + + ii = ii + 1 + scripvars(ii)%var_name = 'grid_center_lat' + scripvars(ii)%unit_name = 'degrees' + + ii = ii + 1 + scripvars(ii)%var_name = 'grid_center_lon' + scripvars(ii)%unit_name = 'degrees' + + ii = ii + 1 + scripvars(ii)%var_name = 'grid_corner_lat' + scripvars(ii)%unit_name = 'degrees' + + ii = ii + 1 + scripvars(ii)%var_name = 'grid_corner_lon' + scripvars(ii)%unit_name = 'degrees' + + end subroutine scripvars_typedefine end module vartypedefs diff --git a/sorc/cpld_gridgen.fd/vertices.F90 b/sorc/cpld_gridgen.fd/vertices.F90 index e45df6568..17158abaf 100644 --- a/sorc/cpld_gridgen.fd/vertices.F90 +++ b/sorc/cpld_gridgen.fd/vertices.F90 @@ -17,134 +17,134 @@ module vertices implicit none - contains -!> Fill the vertices for any stagger location between bounding j-rows -!! -!! @param[in] jbeg the beginning row -!! @param[in] jend the ending row -!! @param[in] iVert the i-offset applied to the i-index of a stagger grid -!! @param[in] jVert the j-offset applied to the j-index of a stagger grid -!! @param[in] lat the latitudes of the stagger grid which define each vertex -!! @param[in] lon the longitudes of the stagger grid which define each vertex -!! @param[out] latvert the latitudes of each vertex -!! @param[out] lonvert the longitudes of each vertex -!! @author Denise.Worthen@noaa.gov - - subroutine fill_vertices(jbeg,jend,iVert,jVert,lat,lon,latvert,lonvert) - - integer, intent( in) :: jbeg,jend - integer, intent( in) :: iVert(nv), jVert(nv) - real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon +contains + !> Fill the vertices for any stagger location between bounding j-rows + !! + !! @param[in] jbeg the beginning row + !! @param[in] jend the ending row + !! @param[in] iVert the i-offset applied to the i-index of a stagger grid + !! @param[in] jVert the j-offset applied to the j-index of a stagger grid + !! @param[in] lat the latitudes of the stagger grid which define each vertex + !! @param[in] lon the longitudes of the stagger grid which define each vertex + !! @param[out] latvert the latitudes of each vertex + !! @param[out] lonvert the longitudes of each vertex + !! @author Denise.Worthen@noaa.gov - real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert - - ! local variables - integer :: i,j,n,ii,jj + subroutine fill_vertices(jbeg,jend,iVert,jVert,lat,lon,latvert,lonvert) - do j = jbeg,jend - do i = 1,ni - do n = 1,nv - ii = i + iVert(n); jj = j + jVert(n) - if(ii .eq. 0)ii = ni - if(ii .eq. ni+1)ii = 1 - latvert(i,j,n) = lat(ii,jj) - lonvert(i,j,n) = lon(ii,jj) + integer, intent( in) :: jbeg,jend + integer, intent( in) :: iVert(nv), jVert(nv) + real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon + + real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert + + ! local variables + integer :: i,j,n,ii,jj + + do j = jbeg,jend + do i = 1,ni + do n = 1,nv + ii = i + iVert(n); jj = j + jVert(n) + if(ii .eq. 0)ii = ni + if(ii .eq. ni+1)ii = 1 + latvert(i,j,n) = lat(ii,jj) + lonvert(i,j,n) = lon(ii,jj) + enddo + enddo enddo - enddo - enddo end subroutine fill_vertices -!> Fill the vertices for a stagger location along the bottom j-row -!! -!! @param[in] iVert the i-offset applied to the i-index of a stagger grid -!! @param[in] jVert the j-offset applied to the j-index of a stagger grid -!! @param[in] lat the latitudes of the stagger grid which define each vertex -!! @param[in] lon the longitudes of the stagger grid which define each vertex -!! @param[in] dlat the approximate latitude along the bottom-most row -!! @param[out] latvert the latitudes of each vertex -!! @param[out] lonvert the longitudes of each vertex -!! @author Denise.Worthen@noaa.gov + !> Fill the vertices for a stagger location along the bottom j-row + !! + !! @param[in] iVert the i-offset applied to the i-index of a stagger grid + !! @param[in] jVert the j-offset applied to the j-index of a stagger grid + !! @param[in] lat the latitudes of the stagger grid which define each vertex + !! @param[in] lon the longitudes of the stagger grid which define each vertex + !! @param[in] dlat the approximate latitude along the bottom-most row + !! @param[out] latvert the latitudes of each vertex + !! @param[out] lonvert the longitudes of each vertex + !! @author Denise.Worthen@noaa.gov subroutine fill_bottom(iVert,jVert,lat,lon,latvert,lonvert,dlat) - integer, intent( in) :: iVert(nv), jVert(nv) - real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon - real(dbl_kind), dimension(ni), intent( in) :: dlat - - real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert - - ! local variables - integer :: i,j,n,ii,jj - - ! fill in grid bottom (j=1) - ! vertices 1,2 are available - ! vertices 3,4 must be set manually - j = 1 - do i = 1,ni - do n = 1,2 - ii = i + iVert(n); jj = j + jVert(n) - if(ii .eq. 0)ii = ni - if(ii .eq. ni+1)ii = 1 - latvert(i,j,n) = lat(ii,jj) - lonvert(i,j,n) = lon(ii,jj) - enddo - do n = 3,4 - ii = i + iVert(n) - if(ii .eq. 0)ii = ni - if(ii .eq. ni+1)ii = 1 - latvert(i,j, n) = dlat(ii) + integer, intent( in) :: iVert(nv), jVert(nv) + real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon + real(dbl_kind), dimension(ni), intent( in) :: dlat + + real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert + + ! local variables + integer :: i,j,n,ii,jj + + ! fill in grid bottom (j=1) + ! vertices 1,2 are available + ! vertices 3,4 must be set manually + j = 1 + do i = 1,ni + do n = 1,2 + ii = i + iVert(n); jj = j + jVert(n) + if(ii .eq. 0)ii = ni + if(ii .eq. ni+1)ii = 1 + latvert(i,j,n) = lat(ii,jj) + lonvert(i,j,n) = lon(ii,jj) + enddo + do n = 3,4 + ii = i + iVert(n) + if(ii .eq. 0)ii = ni + if(ii .eq. ni+1)ii = 1 + latvert(i,j, n) = dlat(ii) + enddo + lonvert(i,j, 3) = lonvert(i,j,2) + lonvert(i,j, 4) = lonvert(i,j,1) enddo - lonvert(i,j, 3) = lonvert(i,j,2) - lonvert(i,j, 4) = lonvert(i,j,1) - enddo - end subroutine fill_bottom - -!> Fill the vertices for a stagger location along the top j-row -!! -!! @param[in] iVert the i-offset applied to the i-index of a stagger grid -!! @param[in] jVert the j-offset applied to the j-index of a stagger grid -!! @param[in] lat the latitudes of the stagger grid which define each vertex -!! @param[in] lon the longitudes of the stagger grid which define each vertex -!! @param[in] xlat the latitude across the tripole seam -!! @param[in] xlon the longitude across the tripole seam -!! @param[out] latvert the latitudes of each vertex -!! @param[out] lonvert the longitudes of each vertex -!! @author Denise.Worthen@noaa.gov - - subroutine fill_top(iVert,jVert,lat,lon,latvert,lonvert,xlat,xlon) - - integer, intent( in) :: iVert(nv), jVert(nv) - real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon - real(dbl_kind), dimension(ni), intent( in) :: xlat, xlon - - real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert - - ! local variables - integer :: i,j,n,ii,jj - - ! fill in grid top (j=nj) - ! vertices 3,4 are available - ! vertices 1,2 must be set manually using 'across seam' values - j = nj - do i = 1,ni - do n = 3,4 - ii = i + iVert(n); jj = j + jVert(n) - if(ii .eq. 0)ii = ni - if(ii .eq. ni+1)ii = 1 - latvert(i,j,n) = lat(ii,jj) - lonvert(i,j,n) = lon(ii,jj) + end subroutine fill_bottom + + !> Fill the vertices for a stagger location along the top j-row + !! + !! @param[in] iVert the i-offset applied to the i-index of a stagger grid + !! @param[in] jVert the j-offset applied to the j-index of a stagger grid + !! @param[in] lat the latitudes of the stagger grid which define each vertex + !! @param[in] lon the longitudes of the stagger grid which define each vertex + !! @param[in] xlat the latitude across the tripole seam + !! @param[in] xlon the longitude across the tripole seam + !! @param[out] latvert the latitudes of each vertex + !! @param[out] lonvert the longitudes of each vertex + !! @author Denise.Worthen@noaa.gov + + subroutine fill_top(iVert,jVert,lat,lon,latvert,lonvert,xlat,xlon) + + integer, intent( in) :: iVert(nv), jVert(nv) + real(dbl_kind), dimension(ni,nj), intent( in) :: lat, lon + real(dbl_kind), dimension(ni), intent( in) :: xlat, xlon + + real(dbl_kind), dimension(ni,nj,nv), intent(out) :: latvert,lonvert + + ! local variables + integer :: i,j,n,ii,jj + + ! fill in grid top (j=nj) + ! vertices 3,4 are available + ! vertices 1,2 must be set manually using 'across seam' values + j = nj + do i = 1,ni + do n = 3,4 + ii = i + iVert(n); jj = j + jVert(n) + if(ii .eq. 0)ii = ni + if(ii .eq. ni+1)ii = 1 + latvert(i,j,n) = lat(ii,jj) + lonvert(i,j,n) = lon(ii,jj) + enddo + do n = 1,2 + ii = i + iVert(n) + if(ii .eq. 0)ii = ni + if(ii .eq. ni+1)ii = 1 + latvert(i,j,n) = xlat(ii) + lonvert(i,j,n) = xlon(ii) + enddo enddo - do n = 1,2 - ii = i + iVert(n) - if(ii .eq. 0)ii = ni - if(ii .eq. ni+1)ii = 1 - latvert(i,j,n) = xlat(ii) - lonvert(i,j,n) = xlon(ii) - enddo - enddo - !latCv_vert(i,j, 1) = latCv_vert(i,j,4) - !latCv_vert(i,j, 2) = latCv_vert(i,j,3) - !lonCv_vert(i,j, 1) = lonCv_vert(i,j,4)+240.d0 - !lonCv_vert(i,j, 2) = lonCv_vert(i,j,3)+240.d0 + !latCv_vert(i,j, 1) = latCv_vert(i,j,4) + !latCv_vert(i,j, 2) = latCv_vert(i,j,3) + !lonCv_vert(i,j, 1) = lonCv_vert(i,j,4)+240.d0 + !lonCv_vert(i,j, 2) = lonCv_vert(i,j,3)+240.d0 end subroutine fill_top end module vertices diff --git a/ush/cpld_gridgen.sh b/ush/cpld_gridgen.sh index f9c61ccea..2573baf6e 100755 --- a/ush/cpld_gridgen.sh +++ b/ush/cpld_gridgen.sh @@ -3,96 +3,104 @@ set -eux function edit_namelist { - sed -e "s/NI_GLB/$NI/g" \ - -e "s/NJ_GLB/$NJ/g" \ - -e "s|FIXDIR|$FIXDIR_PATH|g" \ - -e "s|OUTDIR|$OUTDIR_PATH|g" \ - -e "s|MOSAICDIR|$MOSAICDIR_PATH|g" \ - -e "s/TOPOGFILE/$TOPOGFILE/g" \ - -e "s/EDITSFILE/$EDITSFILE/g" \ - -e "s/RESNAME/$RESNAME/g" \ - -e "s/MOSAICRES/$MOSAICRES/g" \ - -e "s/NPX/$NPX/g" \ - -e "s/DO_MASKEDIT/$MASKEDIT/g" \ - -e "s/DO_DEBUG/$DEBUG/g" \ - -e "s/DO_POSTWGTS/$DO_POSTWGTS/g" + sed -e "s/NI_GLB/$NI/g" \ + -e "s/NJ_GLB/$NJ/g" \ + -e "s|FIXDIR|$FIXDIR_PATH|g" \ + -e "s|OUTDIR|$OUTDIR_PATH|g" \ + -e "s|MOSAICDIR|$MOSAICDIR_PATH|g" \ + -e "s/TOPOGFILE/$TOPOGFILE/g" \ + -e "s/EDITSFILE/$EDITSFILE/g" \ + -e "s/RESNAME/$RESNAME/g" \ + -e "s/MOSAICRES/$MOSAICRES/g" \ + -e "s/NPX/$NPX/g" \ + -e "s/DO_MASKEDIT/$MASKEDIT/g" \ + -e "s/DO_DEBUG/$DEBUG/g" \ + -e "s/DO_POSTWGTS/$DO_POSTWGTS/g" } export RESNAME=${RESNAME:-$1} export DEBUG=.false. export MASKEDIT=.false. export DO_POSTWGTS=.false. -export OUTDIR_PATH=${OUTDIR_PATH:-/scratch2/NCEPDEV/climate/Denise.Worthen/grids-20220116} +export OUTDIR_PATH=${OUTDIR_PATH:-/scratch1/NCEPDEV/climate/Denise.Worthen/grids-20220116} export MOSAICDIR_PATH=${MOSAICDIR_PATH:-$PATHTR/fix/orog} -APRUN=${APRUN:-"srun"} - -if [ $RESNAME = 400 ]; then - echo "The 4 degree resolution is not implemented yet" - exit 1 +if [[ $MOSAICRES == C3072 ]]; then + export NPX=3072 +elif [[ $MOSAICRES == C1152 ]]; then + export NPX=1152 +elif [[ $MOSAICRES == C768 ]]; then + export NPX=768 +elif [[ $MOSAICRES == C384 ]]; then + export NPX=384 +elif [[ $MOSAICRES == C192 ]]; then + export NPX=192 +elif [[ $MOSAICRES == C096 ]]; then + export MOSAICRES=C96 + export NPX=96 +elif [[ $MOSAICRES == C048 ]]; then + export MOSAICRES=C48 + export NPX=48 +fi +if [ $RESNAME = 500 ]; then + export FIXDIR_PATH=/scratch1/NCEPDEV/global/glopara/fix/mom6/20220805/500/ else export FIXDIR_PATH=${MOM6_FIXDIR}/${RESNAME} fi -if [ $RESNAME = 400 ]; then - export NI=72 - export NJ=35 - export MOSAICRES=C48 - export NPX=48 - export TOPOGFILE=ocean_topog.nc - export EDITSFILE='none' +APRUN=${APRUN:-"srun"} + +if [ $RESNAME = 500 ]; then + export NI=72 + export NJ=35 + export TOPOGFILE=ocean_topog.nc + export EDITSFILE='none' fi if [ $RESNAME = 100 ]; then - export NI=360 - export NJ=320 - export MASKEDIT=.T. - export MOSAICRES=C96 - export NPX=96 - export TOPOGFILE=topog.nc - export EDITSFILE=topo_edits_011818.nc - if [ $DO_POSTWGTS == .true. ]; then - #pre-generate SCRIP files for dst rectilinear grids using NCO - # TODO: is the stagger really correct? The first pt is at 0.0E? - # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap - ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr - fi + export NI=360 + export NJ=320 + export MASKEDIT=.T. + export TOPOGFILE=topog.nc + export EDITSFILE=topo_edits_011818.nc + if [ $DO_POSTWGTS == .true. ]; then + #pre-generate SCRIP files for dst rectilinear grids using NCO + # TODO: is the stagger really correct? The first pt is at 0.0E? + # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap + ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr + fi fi if [ $RESNAME = 050 ]; then - export NI=720 - export NJ=576 - export MOSAICRES=C192 - export NPX=192 - export TOPOGFILE=ocean_topog.nc - export EDITSFILE='none' - if [ $DO_POSTWGTS == .true. ]; then - #pre-generate SCRIP files for dst rectilinear grids using NCO - # TODO: is the stagger really correct? The first pt is at 0.0E? - # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap - ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr - ncremap -g ${OUTDIR_PATH}/rect.0p5_SCRIP.nc -G latlon=361,720#lon_typ=grn_ctr - fi + export NI=720 + export NJ=576 + export TOPOGFILE=ocean_topog.nc + export EDITSFILE='none' + if [ $DO_POSTWGTS == .true. ]; then + #pre-generate SCRIP files for dst rectilinear grids using NCO + # TODO: is the stagger really correct? The first pt is at 0.0E? + # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap + ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr + ncremap -g ${OUTDIR_PATH}/rect.0p5_SCRIP.nc -G latlon=361,720#lon_typ=grn_ctr + fi fi if [ $RESNAME = 025 ]; then - export NI=1440 - export NJ=1080 - export MOSAICRES=C384 - export NPX=384 - export TOPOGFILE=ocean_topog.nc - export EDITSFILE=All_edits.nc - if [ $DO_POSTWGTS == .true. ]; then - #pre-generate SCRIP files for dst rectilinear grids using NCO - # TODO: is the stagger really correct? The first pt is at 0.0E? - # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap - ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr - ncremap -g ${OUTDIR_PATH}/rect.0p5_SCRIP.nc -G latlon=361,720#lon_typ=grn_ctr - ncremap -g ${OUTDIR_PATH}/rect.0p25_SCRIP.nc -G latlon=721,1440#lon_typ=grn_ctr - fi + export NI=1440 + export NJ=1080 + export TOPOGFILE=ocean_topog.nc + export EDITSFILE=All_edits.nc + if [ $DO_POSTWGTS == .true. ]; then + #pre-generate SCRIP files for dst rectilinear grids using NCO + # TODO: is the stagger really correct? The first pt is at 0.0E? + # should lat_type be cap? #lon_typ=grn_ctr#lat_typ=cap + ncremap -g ${OUTDIR_PATH}/rect.1p0_SCRIP.nc -G latlon=181,360#lon_typ=grn_ctr + ncremap -g ${OUTDIR_PATH}/rect.0p5_SCRIP.nc -G latlon=361,720#lon_typ=grn_ctr + ncremap -g ${OUTDIR_PATH}/rect.0p25_SCRIP.nc -G latlon=721,1440#lon_typ=grn_ctr + fi fi if [ ! -d ${OUTDIR_PATH} ]; then - mkdir -p ${OUTDIR_PATH} + mkdir -p ${OUTDIR_PATH} fi cd ${OUTDIR_PATH} @@ -103,7 +111,7 @@ $APRUN ./cpld_gridgen # generate ice mesh export FSRC=${OUTDIR_PATH}/Ct.mx${RESNAME}_SCRIP_land.nc export FDST=${OUTDIR_PATH}/mesh.mx${RESNAME}.nc -$APRUN ESMF_Scrip2Unstruct ${FSRC} ${FDST} 0 +$APRUN -n 1 ESMF_Scrip2Unstruct ${FSRC} ${FDST} 0 # generate kmt file for CICE export FSRC=${OUTDIR_PATH}/grid_cice_NEMS_mx${RESNAME}.nc