[Ncep.list.nems.announce] nems r100116: A batch of coupling and technical updates.
Samuel.Trahan at noaa.gov
Samuel.Trahan at noaa.gov
Wed Apr 25 21:13:07 UTC 2018
New
basel...
Message-ID: <5ae0ef63.+FE+hrjNw3uVosVK%Samuel.Trahan at noaa.gov>
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="=_5ae0ef63.oomzj71SPlVTIonTUnBZLTfFZl0l/En67elrZg420g1Y82e8"
This is a multi-part message in MIME format.
--=_5ae0ef63.oomzj71SPlVTIonTUnBZLTfFZl0l/En67elrZg420g1Y82e8
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Friendly NEMS developers,
This is an automated email about a NEMS commit.
Project: nems
URL: https://svnemc.ncep.noaa.gov/projects/nems/trunk
Revision: 100116
Author: samuel.trahan at noaa.gov
Date: 2018-04-25T20:59:18.484913Z
Message:
A batch of coupling and technical updates.
New baselines were generated for the following supported apps:
HYCOM-GSM-CICE
GSM-MOM5-CICE5
No other apps' answers changed.
See tickets:
https://vlab.ncep.noaa.gov/redmine/issues/47301
https://vlab.ncep.noaa.gov/redmine/issues/48832
https://vlab.ncep.noaa.gov/redmine/issues/47414
============================== Coupling updates:
Please note that if your coupled application uses the mediator and:
GSM: the mediator updates require the use of the GSM gridmask branch
(in VLab: d47e8b9b), which has the required grid mask information.
FV3: the appropriate conf file needs to have CPPFLAGS += -DFV3_CPLD in
the ifdef InNemsMakefile section of your configure file. Using
FV3_CPLD requires the use of esmf/8.0.0bs01
1. Simplification of realizeConnectedGrid() inside
InitializeIPDv03p4(). Instead of explicitly constructing the
regDecompPTile, let ESMF construct a 1DE/PET default.
2. Adding a subroutine for multi-tile FV3 grid output. (FieldBundle_RWFields_tiles)
3. Tested vtk file output for FV3 grid (currently commented out search
for ESMF_GridWriteVTK)
4. Adding nearest neighbor interpolation method for regridding flux fields.
5. The land-sea mask from the atmosphere model on the atmosphere model
grid is used for regridding flux fields in the mediator.
============================== NEMSAppBuilder updates:
6. Add NEMSAppBuilder support for MOM6
7. A bug fix was added to NEMSAppBuilder to prevent it from picking a
different *.appBuilder file than was requested. There was a logic
error in the scripts, where a regular expression comparison (=~) was
used instead of an equality comparison (==). This occasionally broke
the NEMSGSM build because standaloneGSM%gocart.appBuilder was used
when standaloneGSM was requested because the former string contains
the latter.
============================= Platform support setup fixes:
8. Changes to module-setup.sh.inc and module-setup.csh.inc for
supporting GAEA and WCOSS Phase 3 (Dell)
9. The NEMSfv3gfs tests now have a 45 minute wallclock limit on WCOSS
Phase 1 and Phase 2.
============================== Upstream fixes:
10. A bugfix to produtil needed to support removing "blocking" status
from streams. This is a fix needed by MET+
============================== Commit process:
11. A multi-app test script NEMS/tests/multi-app-test.sh which will be
used to automate commit tests and nightly tests
See attached file for full differences.
First 4000 bytes of differences:
Index: checkout/tests/testfile
===================================================================
--- checkout/tests/testfile (revision 99852)
+++ checkout/tests/testfile (nonexistent)
@@ -1 +0,0 @@
-this is a test
Index: checkout/tests/rtgen
===================================================================
--- checkout/tests/rtgen (revision 99852)
+++ checkout/tests/rtgen (revision 100116)
@@ -1000,7 +1000,7 @@
optval,arglist=getopt.getopt(sys.argv[1:],"c:fst:n:hr:p:b",[
'project=', 'mode=', 'baseline-dir=', 'baseline',
'dry-run', 'verbose', 'unique-id=', 'temp-dir=',
- 'resume=','compset='])
+ 'resume=','compset=', 'multi-app-test-mode'])
except getopt.GetoptError as ge:
rtsh_usage(str(ge))
@@ -1026,6 +1026,9 @@
'Run with -h for more information')
if opt=='--verbose':
verbose+=1
+ elif opt == '--multi-app-test-mode':
+ # Enable extra log messages for multi-app-test to parse.
+ script_mode=True
elif opt in [ '-h', '--help' ]:
rtsh_full_usage()
elif opt=='-f':
@@ -1140,7 +1143,7 @@
optval,arglist=getopt.getopt(sys.argv[1:],'vdu:t:bn:i:p:hS',
'project=', 'mode=', 'baseline-dir=', 'baseline',
'dry-run', 'verbose', 'unique-id=', 'temp-dir=',
- 'resume=', 'help', 'input-file')
+ 'resume=', 'help', 'input-file', 'multi-app-test-mode')
except getopt.GetoptError as ge:
rtgen_usage(str(ge))
@@ -1156,6 +1159,9 @@
for opt,val in optval:
if opt in ['-v', '--verbose']:
verbose+=1
+ elif opt == '--multi-app-test-mode':
+ # Enable extra log messages for multi-app-test to parse.
+ script_mode=True
elif opt in ['-h', '--help']:
rtgen_full_usage() # does not return
elif opt in ['-p', '--project']:
Index: checkout/tests/README.multi-app-test.md
===================================================================
--- checkout/tests/README.multi-app-test.md (nonexistent)
+++ checkout/tests/README.multi-app-test.md (revision 100116)
@@ -0,0 +1,60 @@
+Multi-App Test Instructions
+===========================
+
+Running the Commit Process
+--------------------------
+
+Edit the `commit.def` file, commit, and push it to your NEMS branch.
+
+On each machine `$machine`:
+
+ git clone gerrit:NEMS multi-app-test
+ cd multi-app-test
+ git checkout (your-nems-branch-goes-here)
+ cd tests
+
+On one machine:
+
+ cat apps.def control.def | ./multi-app-test.sh jet web_init
+ cat apps.def control.def | ./multi-app-test.sh jet make_branches
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine checkout
+
+On each machine `$machine`, run under nemspara:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine test
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine push
+ cat apps.def control.def | ./multi-app-test.sh $machine deliver
+
+Then check the results, and make sure you are satisfied. Next, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine master
+
+Running the Nightly Tests
+--------------------------
+
+On each machine `$machine`:
+
+ git clone gerrit:NEMS nightly-tests
+ cd nightly-tests/tests
+
+On one machine:
+
+ cat apps.def nightly.def | ./multi-app-test.sh jet web_init
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine checkout
+
+On each machine `$machine`, run under nemspara:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine test
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine deliver
Index: checkout/tests/apps.def
=================================================
... see attachment for the rest ...
--=_5ae0ef63.oomzj71SPlVTIonTUnBZLTfFZl0l/En67elrZg420g1Y82e8
Content-Type: text/plain;
charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="100116.diff"
Index: checkout/tests/testfile
===================================================================
--- checkout/tests/testfile (revision 99852)
+++ checkout/tests/testfile (nonexistent)
@@ -1 +0,0 @@
-this is a test
Index: checkout/tests/rtgen
===================================================================
--- checkout/tests/rtgen (revision 99852)
+++ checkout/tests/rtgen (revision 100116)
@@ -1000,7 +1000,7 @@
optval,arglist=getopt.getopt(sys.argv[1:],"c:fst:n:hr:p:b",[
'project=', 'mode=', 'baseline-dir=', 'baseline',
'dry-run', 'verbose', 'unique-id=', 'temp-dir=',
- 'resume=','compset='])
+ 'resume=','compset=', 'multi-app-test-mode'])
except getopt.GetoptError as ge:
rtsh_usage(str(ge))
@@ -1026,6 +1026,9 @@
'Run with -h for more information')
if opt=='--verbose':
verbose+=1
+ elif opt == '--multi-app-test-mode':
+ # Enable extra log messages for multi-app-test to parse.
+ script_mode=True
elif opt in [ '-h', '--help' ]:
rtsh_full_usage()
elif opt=='-f':
@@ -1140,7 +1143,7 @@
optval,arglist=getopt.getopt(sys.argv[1:],'vdu:t:bn:i:p:hS',
'project=', 'mode=', 'baseline-dir=', 'baseline',
'dry-run', 'verbose', 'unique-id=', 'temp-dir=',
- 'resume=', 'help', 'input-file')
+ 'resume=', 'help', 'input-file', 'multi-app-test-mode')
except getopt.GetoptError as ge:
rtgen_usage(str(ge))
@@ -1156,6 +1159,9 @@
for opt,val in optval:
if opt in ['-v', '--verbose']:
verbose+=1
+ elif opt == '--multi-app-test-mode':
+ # Enable extra log messages for multi-app-test to parse.
+ script_mode=True
elif opt in ['-h', '--help']:
rtgen_full_usage() # does not return
elif opt in ['-p', '--project']:
Index: checkout/tests/README.multi-app-test.md
===================================================================
--- checkout/tests/README.multi-app-test.md (nonexistent)
+++ checkout/tests/README.multi-app-test.md (revision 100116)
@@ -0,0 +1,60 @@
+Multi-App Test Instructions
+===========================
+
+Running the Commit Process
+--------------------------
+
+Edit the `commit.def` file, commit, and push it to your NEMS branch.
+
+On each machine `$machine`:
+
+ git clone gerrit:NEMS multi-app-test
+ cd multi-app-test
+ git checkout (your-nems-branch-goes-here)
+ cd tests
+
+On one machine:
+
+ cat apps.def control.def | ./multi-app-test.sh jet web_init
+ cat apps.def control.def | ./multi-app-test.sh jet make_branches
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine checkout
+
+On each machine `$machine`, run under nemspara:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine test
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine push
+ cat apps.def control.def | ./multi-app-test.sh $machine deliver
+
+Then check the results, and make sure you are satisfied. Next, run as yourself:
+
+ cat apps.def control.def | ./multi-app-test.sh $machine master
+
+Running the Nightly Tests
+--------------------------
+
+On each machine `$machine`:
+
+ git clone gerrit:NEMS nightly-tests
+ cd nightly-tests/tests
+
+On one machine:
+
+ cat apps.def nightly.def | ./multi-app-test.sh jet web_init
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine checkout
+
+On each machine `$machine`, run under nemspara:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine test
+
+On each machine `$machine`, run as yourself:
+
+ cat apps.def nightly.def | ./multi-app-test.sh $machine deliver
Index: checkout/tests/apps.def
===================================================================
--- checkout/tests/apps.def (nonexistent)
+++ checkout/tests/apps.def (revision 100116)
@@ -0,0 +1,46 @@
+# List of valid platforms and the human-readable names of each:
+PLATFORM jet NAME Jet
+PLATFORM theia NAME Theia
+PLATFORM wcoss1 NAME WCOSS Phase 1
+PLATFORM wcoss2 NAME WCOSS Phase 2
+PLATFORM wcoss_cray NAME WCOSS Cray
+#PLATFORM wcoss_dell_p3 NAME WCOSS Phase 3
+#PLATFORM gaea NAME GAEA
+
+# List of known apps and the compsets to run for each app.
+APP NEMSfv3gfs COMPSETS -f
+APP GSM-MOM5-CICE5 COMPSETS -s
+APP NEMSGSM COMPSETS -f
+APP WW3-FV3 COMPSETS -f
+APP WW3-ATM COMPSETS -f
+APP HYCOM-GSM-CICE COMPSETS -f
+
+# URLs of each application's repository. Default is gerrit:APPNAME
+APP NEMSfv3gfs URL gerrit:NEMSfv3gfs
+APP GSM-MOM5-CICE5 URL gerrit:EMC_GSM-MOM5-CICE5
+APP NEMSGSM URL gerrit:EMC_NEMSGSM
+APP WW3-FV3 URL gerrit:EMC_FV3-WW3
+APP WW3-ATM URL gerrit:EMC_ATM-WW3
+APP HYCOM-GSM-CICE URL gerrit:EMC_HYCOM-GSM-CICE
+
+# Shell expressions that generate scrub space for a given $username
+# on each platform.
+ON jet SCRUB /lfs3/projects/hfv3gfs/$username/scrub
+ON theia SCRUB /scratch4/NCEPDEV/nems/scrub/$username
+ON wcoss1 SCRUB /ptmpp1/$username
+ON wcoss2 SCRUB /ptmpd3/$username
+ON wcoss_cray SCRUB /gpfs/hps2/ptmp/$username
+#ON wcoss_dell_p3 SCRUB /fixme/$username
+#ON gaea SCRUB $( ls -1 /lustre/f1/*/$username | head -1 )
+
+# List of apps to run on each platform.
+ON jet APPS NEMSfv3gfs
+ON theia APPS NEMSfv3gfs NEMSGSM HYCOM-GSM-CICE WW3-FV3 WW3-ATM GSM-MOM5-CICE5
+ON wcoss1 APPS NEMSfv3gfs NEMSGSM
+ON wcoss2 APPS NEMSfv3gfs WW3-FV3 WW3-ATM GSM-MOM5-CICE5
+ON wcoss_cray APPS NEMSfv3gfs WW3-FV3
+#ON wcoss_dell_p3 APPS FIXME
+#ON gaea APPS NEMSfv3gfs
+
+# Extra arguments to rt.sh for each platform
+ON jet EXTRA_ARGS --temp-dir /lfs3/projects/hfv3gfs/$USER/scrub
Index: checkout/tests/commit.def
===================================================================
--- checkout/tests/commit.def (nonexistent)
+++ checkout/tests/commit.def (revision 100116)
@@ -0,0 +1,28 @@
+# Directory to receive the webpage with regression test results
+ON jet WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON theia WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON wcoss1 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON wcoss2 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON wcoss_cray WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON wcoss_dell_p3 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+ON gaea WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/nems-commit/coupling-test-1/
+
+USER ACCOUNT IS Samuel.Trahan
+ROLE ACCOUNT IS emc.nemspara
+
+# nems branch - branch of NEMS that is being tested. Set to "default"
+# to test the app's own NEMS
+NEMS BRANCH IS multi-app-test
+#NEMS BRANCH IS default
+
+# app branch - branch to use for committing logs to each
+APP BRANCH IS coupling-test-1
+
+# If relevant, the starting branch that we copy to make the app
+# branch. Default is the master branch.
+APP GSM-MOM5-CICE5 CHECKOUT newnems_0417
+APP NEMSGSM CHECKOUT coupling-update
+APP NEMSfv3gfs CHECKOUT coupling-update
+
+# master branch - name of the git "master" branch. Do not change.
+MASTER BRANCH IS master
Index: checkout/tests/run-if-dev.sh
===================================================================
--- checkout/tests/run-if-dev.sh (nonexistent)
+++ checkout/tests/run-if-dev.sh (revision 100116)
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+if [[ ! -s /etc/prod ]] ; then
+ # Not on WCOSS. No dev vs. prod, so we're always "on dev"
+ "$@"
+else
+ hostchar=$( hostname | head -1 | cut -c1-1 )
+ prodchar=$( head -1 /etc/prod | cut -c1-1 )
+
+ if [[ "$hostchar" != "$prodchar" ]] ; then
+ # This is the dev side.
+ "$@"
+ else
+ echo "On production machine." 1>&2
+ fi
+fi
\ No newline at end of file
Property changes on: checkout/tests/run-if-dev.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: checkout/tests/git_info.sh
===================================================================
--- checkout/tests/git_info.sh (nonexistent)
+++ checkout/tests/git_info.sh (revision 100116)
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+echo REPO TOP:
+git branch -vv | head -1 | cut -c3-
+git remote show -n origin | grep 'Fetch URL:' | sed "s,^ *,,g"
+git status -suno
+echo
+git submodule foreach sh -c 'git branch -vv | head -1 | cut -c3- ; git remote show -n origin | grep "Fetch URL:" | sed "s,^ *,,g" ; git status -suno ; echo'
Property changes on: checkout/tests/git_info.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: checkout/tests/nightly.def
===================================================================
--- checkout/tests/nightly.def (nonexistent)
+++ checkout/tests/nightly.def (revision 100116)
@@ -0,0 +1,18 @@
+# Directory to receive the webpage with regression test results
+ON jet WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON theia WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON wcoss1 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON wcoss2 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON wcoss_cray WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON wcoss_dell_p3 WEBPAGE strahan at emcrzdm.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+ON gaea WEBPAGE samuel.trahan at dmzgw.ncep.noaa.gov:/home/www/emc/htdocs/projects/rt
+
+USER ACCOUNT IS Samuel.Trahan
+ROLE ACCOUNT IS emc.nemspara
+
+# nems branch - branch of NEMS that is being tested. Set to "default"
+# to test the app's own NEMS, and omit the commit process
+NEMS BRANCH IS default
+
+# app branch - branch to use for committing logs to each
+#APP BRANCH IS commit-test-1
Index: checkout/tests/web-top/regtestview.css
===================================================================
--- checkout/tests/web-top/regtestview.css (nonexistent)
+++ checkout/tests/web-top/regtestview.css (revision 100116)
@@ -0,0 +1,207 @@
+body {
+ background-color: white;
+}
+
+.passrow {
+ background-color: Moccasin ;
+}
+
+.repo {
+ background-color: PowderBlue ;
+}
+
+p {
+ line-height: 70%;
+}
+
+h1 {
+ text-align: center;
+}
+
+table.rt_list {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.rtresult {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+p.loading {
+ line-height: 110%;
+}
+
+caption.note {
+ margin-top: 1m;
+ line-height: 110%;
+ text-align: justify;
+ text-justify: auto;
+ caption-side: bottom;
+}
+
+caption.note p {
+ margin-top: 1m;
+ line-height: 110%;
+ text-align: justify;
+ text-justify: auto;
+ caption-side: bottom;
+ font-size: 80%;
+}
+
+caption.note span {
+ margin-top: 1m;
+ line-height: 110%;
+ text-align: justify;
+ text-justify: auto;
+ caption-side: bottom;
+ font-size: 80%;
+}
+
+a {
+ color: MidnightBlue ;
+}
+
+.failrow {
+ background-color: LightPink ;
+ color: Maroon ;
+ font-weight: bold;
+}
+
+.passold {
+ background-color: PowderBlue ;
+ color: DarkSlateBlue ;
+}
+
+.passancient {
+ background-color: Thistle ;
+ color: Indigo ;
+ font-style: italic;
+}
+
+.errorrow {
+ background-color: White ;
+ color: Maroon ;
+ font-weight: bold;
+}
+
+.head {
+ color: white ;
+ background-color: black;
+}
+.badline {
+ background-color: DodgerBlue ;
+}
+
+.compile {
+ background-color: LightGray ;
+}
+
+.compilefail {
+ background-color: LightPink ;
+}
+
+.testinfo {
+ display: none;
+}
+
+.testinfoshow {
+ display: block;
+}
+
+td {
+ text-align: right;
+}
+
+table.rtresult tr td:first-child {
+ width: auto;
+ max-width: 20em;
+ word-wrap: normal;
+ min-width: 8em;
+}
+
+table.rtresult tr th:first-child {
+ width: auto;
+ max-width: 20em;
+ word-wrap: normal;
+ min-width: 8em;
+}
+
+table tr td:nth-child(2) {
+ text-align: center;
+ width: 11em ;
+}
+
+table tr th:nth-child(2) {
+ text-align: center;
+ width: 11em ;
+}
+
+table tr td:first-child + td + td {
+ text-align: left;
+ width: auto ;
+}
+
+table {
+ border-collapse: collapse;
+}
+th, td {
+ vertical-align: text-top;
+ border-bottom: 3px solid white;
+}
+
+th {
+ font-size: large;
+}
+
+/**********************************************************************/
+
+.compileinfo {
+ display: none;
+}
+
+.compileinfoshow {
+ display: block;
+ position: fixed;
+ background-color: black;
+ top: 5%;
+ left: 5%;
+ width: 90%;
+ height: 90%;
+ border: 3px solid black;
+ margin: 0;
+}
+
+.compileinfoshow tr {
+ position: absolute;
+ background-color: black;
+ color: white;
+ width: 100%;
+}
+
+.compilecontent {
+ font-family: monospace;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ word-wrap: break-word;
+ background-color: white;
+ color: black;
+ text-align: left;
+ width: 100%;
+}
+
+.compilehead {
+ font-size: large;
+ color: white ;
+ background-color: black;
+ text-align: center;
+ width: 90%;
+}
+
+.close {
+ background-color: black;
+ color: white;
+ width: 10%;
+ font-size: large;
+ text-align: left;
+}
Index: checkout/tests/web-top/regtestview.js
===================================================================
--- checkout/tests/web-top/regtestview.js (nonexistent)
+++ checkout/tests/web-top/regtestview.js (revision 100116)
@@ -0,0 +1,452 @@
+debugMode=false;
+rtPlatform=null;
+rtStartTime=-1;
+rtEndTime=-1;
+rtResult=null;
+popUps=new Array();
+
+function cachebuster() {
+ return '?cachebuster='
+ +'A'+Math.random().toString()
+ +'B'+Math.random().toString()
+ +'C'+Math.random().toString()
+ +'D'+Math.random().toString();
+}
+
+function zeroPad2(number) {
+ if(number<10) {
+ return '0'+number.toString();
+ } else {
+ return number.toString();
+ }
+}
+
+function niceTime(when) {
+ var date;
+ date=new Date(0);
+ date.setUTCSeconds(when);
+ return date.toUTCString();
+}
+
+function niceDuration(duration) {
+ var hours, minutes, seconds;
+ var hoursPad, minutesPad, secondsPad;
+ hours=Math.floor(duration/3600);
+ minutes=Math.floor((duration-hours*3600)/60);
+ seconds=Math.floor(duration-hours*3600-minutes*60);
+ return zeroPad2(hours)+':'+zeroPad2(minutes)+':'+zeroPad2(seconds);
+}
+
+function niceAge(whence) {
+ var nowdate;
+ var nowtime;
+ var duration;
+ nowdate=new Date();
+ nowtime=nowdate.valueOf()/1000.0;
+ duration=nowtime-whence;
+ return niceDuration(duration);
+
+}
+
+function closeAll() {
+ for(var i=0;i<popUps.length;i++) {
+ element=document.getElementById(popUps[i]);
+ element.className='compileinfo';
+ }
+}
+
+function openCompile(id) {
+ var oldurl=location.href;
+ location.href='#'+id;
+ history.replaceState(null,null,oldurl);
+ // location.href = "#"+h; //Go to the target element.
+ // history.replaceState(null,null,url); //Don't like hashes. Changing it back. window.location=
+ //element=document.getElementById(id);
+ //element.className='compileinfoshow';
+ // window.scrollTo(0,element.offsetTop);
+}
+
+function asId(text) {
+ // Generate a reasonable css id based on some text.
+
+ // Strings of anything other than alphanumeric and _ become a single _
+ // Remove trailing underscores.
+ // Prepend "id_"
+ part='id_'+text.replace(/[^A-Za-z0-9_]+/g,'_');
+ return part.replace(/_+$/g,'').replace(/__+/g,'_');
+}
+
+function cleanText(text) {
+ return text.replace(/&/g,"&").replace(/</g,"<").
+ replace(/\s+/g," ");
+}
+
+function cleanTest(text) {
+ return text.replace(/&/g,"&").replace(/</g,"<").
+ replace(/\s+/g," ").replace(/%/g,"<wbr>%<wbr>").
+ replace(/@/g,"<wbr>@<wbr>").replace(/_/g,"<wbr>_<wbr>");
+}
+
+function toggleInfo(id) {
+ element=document.getElementById(id);
+ className=element.className;
+ if(className=='testinfo') {
+ element.className='testinfoshow';
+ } else {
+ element.className='testinfo';
+ }
+}
+
+function topNotes() {
+ return '<p>Source: <a href="regtest.txt">regtest.txt</a>. Click on a test or repo for details.</p>'+
+ '<p>Legend: <span class="repo">CHECKOUT</span> - '+
+ 'TEST <span class="passrow">PASSED</span> - '+
+ 'TEST <span class="failrow">FAILED</span> - '+
+ 'NEMS <span class="compileinfo">RECOMPILED</span></p>';
+}
+
+function itoggle(irow) {
+ toggleInfo("detail"+irow);
+}
+
+function toggle1() {
+ toggleInfo("detail1");
+}
+
+function tableHeading() {
+ return '<table class="rtresult">'
+ +'<tr class="head"><th>Action</th><th>Result</th>'
+ +'<th class="thdetail">Details (click for more info)</th></tr>\n';
+}
+
+function makeRepoRow(rownum,repoPath,repoURL,repoRevision,repoInfo) {
+ if(repoPath=='.') {
+ repoPath='. (top of checkout)';
+ }
+ return '<tr class="repo" onclick="itoggle('+rownum+')">\n'+
+ ' <td>'+repoPath+'</td>\n'+
+ ' <td>rev '+repoRevision+'</td>\n'+
+ ' <td>\n'+
+ ' '+repoURL+'\n'+
+ ' <ul class="testinfo" id="detail'+rownum+'">\n'+
+ repoInfo+
+ ' </ul>\n'+
+ ' </td>\n'+
+ '</tr>\n';
+}
+
+function makeTestRow(rownum,testName,testTime,testStatus,testDescr,testInfo) {
+ if(testStatus=='PASS') {
+ row='<tr class="passrow" onclick="itoggle('+rownum+')">\n';
+ } else {
+ row='<tr class="failrow" onclick="itoggle('+rownum+')">\n';
+ }
+ return row+
+ '\n <td class="testname">'+cleanTest(testName)+
+ '</td>\n <td class="teststatus">'+
+ cleanText(testStatus)+'</td>\n <td class="testmore"'+
+ '>\n <div class="testdescr">\n '+
+ cleanText(testDescr)+'\n </div>\n'+
+ ' <ul class="testinfo" id="detail'+rownum.toString()+
+ '">\n'+testInfo+'\n </ul>\n </td>\n</tr>\n';
+}
+
+function receiveText(text,debugMode) {
+ var lines=text.split(/[\n\r]+/);
+ var mode='PRE';
+ var line;
+ var unknown='**unknown**';
+ var compileMode=unknown;
+ var testName=unknown;
+ var testDescr=unknown;
+ var testTime=unknown;
+ var testStatus=unknown;
+ var testInfo='';
+ var row='';
+ var startedTable=false;
+ var numBad=0;
+ var text='';
+ var endtext='';
+ var rownum=0;
+ var sawDot=false; // Did I see repo path "." yet?
+ var inCompileDiv=false;
+ var compileTime=null;
+ var compileClass=null;
+ var compileStatus=null;
+ var testEarlyStatus=null;
+ var lineReports=0;
+
+ for(var i=0;i<lines.length;i++) {
+ line=lines[i];
+ if(lineReports<300) {
+ console.log('mode '+mode+' line: '+line);
+ lineReports++;
+ }
+ if(-1!==line.search(/^\s*$/)) {
+ // Ignore blank lines.
+ continue;
+ }
+ if(mode=='PRE') {
+ m=line.match(/^===.REGTEST BEGIN\s+\+(-?\d+)$/);
+ if(m) {
+ mode='REGTEST';
+ rtStartTime=m[1];
+ continue;
+ }
+ } else if(mode=='REGTEST') {
+ m=line.match(/^===!REGTEST (\S+) (\S+) ?(.*)/);
+ if(m!=null) {
+ if(m[1]=='PLATFORM') {
+ rtPlatform=m[2];
+ if(m[3]) {
+ rtPlatform+=' '+m[3]
+ }
+ continue;
+ } else if(m[1]=='RESULT') {
+ rtResult=m[2];
+ continue;
+ } else if(m[1]=='LOG' && m[2]=='BEGIN') {
+ mode='LOG';
+ if(!startedTable) {
+ text+=tableHeading();
+ startedTable=true;
+ }
+ continue;
+ } else if(m[1]=='REPO' && m[2]=='BEGIN') {
+ mode='REPO';
+ repoInfo=null; // for detection of empty repo info in REPO mode
+ if(!startedTable) {
+ text+=tableHeading();
+ startedTable=true;
+ }
+ continue;
+ } else if(m[1]=='COMPILE') {
+ mode='COMPILE';
+ compileId=asId(m[2]);
+ inCompileDiv=true;
+ endtext+='<a name="'+compileId+'"></a>'
+ +'<h1 id='+compileId+'> Compile NEMS Executable for '+m[2]+'</h1>';
+ continue;
+ } else if(m[1]=='END') {
+ rtEndTime=m[2];
+ continue;
+ }
+ }
+ } else if(mode=='COMPILE') {
+ if(line.match(/^===!REGTEST COMPILE END/)) {
+ mode='REGTEST';
+ if(inCompileDiv) {
+ inCompileDiv=false;
+ }
+ continue;
+ } else {
+ endtext+=cleanText(line)+'<br>';
+ continue;
+ }
+ } else if(mode=='REPO' || mode=='GIT_BRANCH') {
+ // Check for repo name line
+ if(-1!=line.search(/^===!REGTEST REPO END/)) {
+ console.log('saw REGTEST REPO END in mode '+mode);
+ if(( repoInfo!==null && (repoPath!='.' || !sawDot) ) || mode=='GIT_BRANCH') {
+ rownum++;
+ console.log('makeRepoRow after REGTEST REPO END');
+ text+=makeRepoRow(rownum,repoPath,repoURL,repoRevision,repoInfo);
+ sawDot=( sawDot || repoPath=='.')
+ }
+ mode='REGTEST';
+ continue;
+ }
+ if(-1!=line.search(/^REPO TOP:/)) {
+ mode='GIT_BRANCH';
+ repoPath='.';
+ repoURL='';
+ repoRevision='';
+ repoInfo='';
+ continue;
+ }
+ m=line.match(/^Entering '([^\']+)'/);
+ if(m!==null) {
+ console.log('makeRepoRow after Entering');
+ rownum++;
+ text+=makeRepoRow(rownum,repoPath,repoURL,repoRevision,repoInfo);
+ mode='GIT_BRANCH';
+ repoPath=m[1];
+ repoURL='';
+ repoRevision='';
+ repoInfo='';
+ continue;
+ }
+ if(mode=='GIT_BRANCH') {
+ repoInfo+=cleanText(line)+'<br>\n';
+ m=line.match(/^Fetch URL: (\S+)/);
+ if(m!==null) {
+ repoURL=m[1];
+ continue;
+ }
+ m=line.match(/^([^\(]\S+)\s+([a-zA-Z0-9]+)\s+/);
+ if(m!==null) {
+ repoPath='branch '+m[1];
+ repoRevision=m[2];
+ continue;
+ }
+ m=line.match(/^\([^\)]*\)\s+([a-zA-Z0-9]+)\s+/);
+ if(m!==null) {
+ repoPath='no branch';
+ repoRevision=m[1];
+ continue;
+ }
+ if(line.match(/^\s*$/)) {
+ mode='REPO';
+ continue;
+ }
+ }
+ m=line.match(/^Path: (\S+)/);
+ if(m!==null) {
+ if(repoInfo!==null && (repoPath!='.' || !sawDot) ) {
+ rownum++;
+ text+=makeRepoRow(rownum,repoPath,repoURL,repoRevision,repoInfo);
+ sawDot=( sawDot || repoPath=='.')
+ }
+ repoPath=m[1];
+ repoURL='';
+ repoRevision='';
+ repoInfo='<li>'+cleanText(line)+'</li>\n';
+ continue;
+ }
+ m=line.match(/^([^:]+): (.*)/);
+ if(m!==null) {
+ repoInfo+='<li>'+cleanText(line)+'</li>\n';
+ if(m[1]=='URL') {
+ repoURL=m[2];
+ }
+ if(m[1]=='Revision') {
+ repoRevision=m[2];
+ }
+ continue;
+ }
+ // Other lines can be ignored
+ continue;
+ } else if(mode=='LOG' || mode=='TEST' || mode=='BETWEEN_TESTS') {
+ //Test gfs_gocart_nemsio starting at Tue Dec 13 01:36:17 UTC 2016 (GFS_GOCART with NEMSIO)
+ // Check for test start line.
+ if(mode=='LOG') {
+ m=line.match(/BUILD ([^:]+): ([A-Z]+)/);
+ if(m!==null) {
+ rownum++;
+ compileId=m[1];
+ compileClass='compile';
+ compileStatus=m[2];
+ if(compileStatus!='SUCCEEDED') {
+ compileClass='compilefail';
+ }
+ text+='<tr class="'+compileClass+'" onclick="openCompile('
+ +"'"+asId(compileId)+"'"+')">\n'
+ +' <td>COMPILE</td>\n<td>'
+ +cleanText(compileStatus)+'</td>\n <td>'
+ +cleanText(compileId)+'</td>\n</tr>\n';
+ continue;
+ }
+ if(-1!=line.search(/TEST #|WORKFLOW START|WORKFLOW REPORT/)) {
+ // Can ignore these in LOG mode
+ continue;
+ }
+ }
+ // TEST #7: PASS
+ m=line.match(/TEST #[0-9]+: ([A-Z]+)/);
+ if(m!==null) {
+ testEarlyStatus=m[1];
+ continue;
+ }
+ // Test fv3_appbuilder starting at Thu Apr 5 02:11:36 GMT 2018
+ // (Compare FV3 with the NEMSAppBuilder against the previous
+ // trunk version)
+ m=line.match(/Test ([^\)]+) starting at ([^\(]+) \(([^\)]+)\)/);
+ if(m!==null) {
+ mode='TEST';
+ if(testName!=unknown) {
+ rownum++;
+ text+=makeTestRow(rownum,testName,testTime,testStatus,testDescr,testInfo);
+ }
+ testName=m[1];
+ testTime=m[2];
+ testDescr=m[3];
+ testInfo='';
+ testStatus='FAIL';
+ if(testEarlyStatus!==null) {
+ testStatus=testEarlyStatus;
+ testEarlyStatus=null;
+ }
+ continue;
+ }
+ if(-1!=line.search(/TEST PASSED AT/)) {
+ testInfo=testInfo.concat('\n <li>\n ');
+ testInfo=testInfo.concat(cleanText(line));
+ testInfo=testInfo.concat('\n </li>\n');
+ testStatus='PASS';
+ mode='BETWEEN_TESTS';
+ continue;
+ }
+ if (-1!=line.search(/^===!REGTEST LOG END/)) {
+ mode='REGTEST';
+ if(testName!=unknown) {
+ rownum++;
+ text+=makeTestRow(rownum,testName,testTime,testStatus,testDescr,testInfo);
+ testName=unknown;
+ testTime=unknown;
+ testDescr=unknown;
+ testInfo='';
+ testStatus='FAIL';
+ }
+ continue;
+ }
+ if(mode=='TEST') {
+ testInfo=testInfo.concat('\n <li>\n ');
+ testInfo=testInfo.concat(cleanText(line));
+ testInfo=testInfo.concat('\n </li>\n');
+ continue;
+ }
+ }
+
+ if(debugMode && numBad<100) {
+ numBad++;
+ if(!startedTable) {
+ text+=tableHeading();
+ startedTable=true;
+ }
+ text+='<tr class="badline"><td>mode='+cleanText(mode)+'</td><td>BAD LINE</td><td>'+cleanText(line)+'</td></tr>\n';
+ }
+ }
+ if(startedTable) {
+ text+='</table>\n';
+ }
+
+ toptext='<h1>'+cleanText(rtPlatform)+' Regression Tests: '+
+ cleanText(rtResult)+'</h1>\n'
+ + '<p>Start time: '+niceTime(rtStartTime)+' (age '+niceAge(rtStartTime)+')</p>'
+ +'<p>End time: '+niceTime(rtEndTime)+' (age '+niceAge(rtEndTime)+')</p>'
+ +'<p>Duration: '+niceDuration(rtEndTime-rtStartTime)+'</p>'
+ +topNotes();
+
+ document.body.innerHTML=toptext+text+endtext;
+}
+
+function readTextFile(filename) {
+ var reader=new XMLHttpRequest();
+ reader.open("GET",filename+cachebuster(),true);
+ reader.onreadystatechange=function () {
+ if(reader.readyState==4 && reader.status==200) {
+ receiveText(reader.responseText,debugMode);
+ }
+ }
+ reader.send(null);
+}
+
+function splashScreen() {
+ document.body.innerHTML="<h1>Loading...</h1>"+
+ "<p>Please wait. Loading regtest.txt...</p>";
+}
+
+window.onload=function() {
+ splashScreen();
+ readTextFile("regtest.txt");
+}
\ No newline at end of file
Index: checkout/tests/web-top/regtestlist.js.in
===================================================================
--- checkout/tests/web-top/regtestlist.js.in (nonexistent)
+++ checkout/tests/web-top/regtestlist.js.in (revision 100116)
@@ -0,0 +1,213 @@
+
+current_dir_index=0;
+old_wcoss_tests=0;
+testInfo=new Array();
+
+function cachebuster() {
+ return '?cachebuster='
+ +'A'+Math.random().toString()
+ +'B'+Math.random().toString()
+ +'C'+Math.random().toString()
+ +'D'+Math.random().toString();
+}
+
+function zeroPad2(number) {
+ if(number<10) {
+ return '0'+number.toString();
+ } else {
+ return number.toString();
+ }
+}
+
+function cleanText(text) {
+ return text.replace(/&/g,"&").replace(/</g,"<").
+ replace(/\s+/g," ");
+}
+
+function niceTime(when) {
+ var date;
+ date=new Date(0);
+ date.setUTCSeconds(when);
+ return date.toUTCString();
+}
+
+function niceDuration(duration) {
+ var hours, minutes, seconds;
+ var hoursPad, minutesPad, secondsPad;
+ hours=Math.floor(duration/3600);
+ minutes=Math.floor((duration-hours*3600)/60);
+ seconds=Math.floor(duration-hours*3600-minutes*60);
+ return zeroPad2(hours)+':'+zeroPad2(minutes)+':'+zeroPad2(seconds);
+}
+
+function hourAge(whence) {
+ var nowdate=new Date();
+ var nowtime=nowdate.valueOf()/1000.0;
+ return (nowtime-whence)/3600;
+}
+
+function niceAge(whence) {
+ var nowdate;
+ var nowtime;
+ var duration;
+ nowdate=new Date();
+ nowtime=nowdate.valueOf()/1000.0;
+ duration=nowtime-whence;
+ return niceDuration(duration);
+
+}
+
+
+function parseText(dirpath,txtpath,txt) {
+ var lines=txt.split(/[\n\r]+/);
+ var mode='PRE';
+ var line;
+ var rtStartTime=-1;
+ var rtEndTime=-1;
+ var rtPlatform='(**UNKNOWN**)';
+ var rtResult='(**UNKNOWN**)';
+ var rowclass;
+ var txtdir=txtpath.replace(/\/[^\/]*$/,'');
+ var duration;
+
+ console.log('parseText: dir='+dirpath.toString()
+ +' txtpath='+txtpath.toString())
+
+ for(var i=0;i<lines.length;i++) {
+ line=lines[i];
+ if(-1!==line.search(/^\s*$/)) {
+ // Ignore blank lines.
+ continue;
+ }
+
+ m=line.match(/^===.REGTEST BEGIN\s+\+(\d+)$/);
+ if(m) {
+ mode='REGTEST';
+ rtStartTime=m[1];
+ console.log(line);
+ continue;
+ }
+
+ m=line.match(/^===!REGTEST (\S+) (\S+) ?(.*)/);
+ if(m!=null) {
+ if(m[1]=='END') {
+ rtEndTime=m[2];
+ console.log(line);
+ continue;
+ } else if(m[1]=='PLATFORM') {
+ rtPlatform=m[2];
+ if(m[3]) {
+ rtPlatform+=' '+m[3];
+ }
+ console.log(line);
+ continue;
+ } else if(m[1]=='RESULT') {
+ rtResult=m[2];
+ console.log(line);
+ continue;
+ }
+ }
+ }
+
+ rowclass='failrow';
+ if(hourAge(rtEndTime)>30) {
+ if(hourAge(rtEndTime)<128) {
+ if(rtResult=="PASS") {
+ rowclass='passold';
+ }
+ rtResult=rtResult+' [OLD]';
+ } else {
+ if(rtResult=="PASS") {
+ rowclass='passancient';
+ }
+ rtResult=rtResult+' [ANCIENT]';
+ }
+ if(txtdir.match(/wcoss/i) || rtPlatform.match(/wcoss/i)) {
+ rtResult=rtResult + '*';
+ old_wcoss_tests++;
+ }
+ } else if(rtResult=='PASS') {
+ rowclass='passrow';
+ }
+
+ console.log('Result: '
+ +' txtpath='+txtpath
+ +' txtdir='+txtdir
+ +' rtResult='+rtResult.toString()
+ +' rtPlatform='+rtPlatform.toString()
+ +' rtStartTime='+rtStartTime.toString()
+ +' rtEndTime='+rtEndTime.toString());
+
+ return '<tr class="'+rowclass+'" onclick="window.location='
+ +"'"+txtdir+"'"+'"><td class="rep_name">'
+ +cleanText(rtPlatform)
+ +'</td><td class="rep_result">'+cleanText(rtResult)
+ +'</td><td class="rep_age">'+niceAge(rtEndTime)
+ +'</td><td class="rep_dur">'
+ +niceDuration(rtEndTime-rtStartTime)
+ +'</td></tr>\n';
+}
+
+function errorText(dir,txtpath,status) {
+ var txtdir=txtpath.replace(/\/[^\/]*$/,'');
+ console.log('errorText: dir='+dir.toString()
+ +' txtpath='+txtpath.toString()
+ +' status='+status.toString())
+ return '<tr class="errorrow"><td class="rep_path">'
+ +'<a href="'+txtpath+'">'+cleanText(txtdir)+'</a>'
+ +'</td><td class="rep_result">ERROR '+cleanText(status.toString())
+ +'</td><td class="rep_age">(unknown)'
+ +'</td><td class="rep_dur">(unknown)'
+ +'</td></tr>\n';
+}
+
+function loadPage() {
+ var dir;
+ var txt;
+ var reader;
+ console.log('current_dir_index='+current_dir_index.toString())
+ if(current_dir_index>=TEST_DIRS.length) {
+ text='<h1>'+TEST_NAME+'</h1>'+
+ '<table class="rt_list">'+
+ '<tr class="head"><th>Test</th><th>Result</th><th>Age</th><th>Duration</th></tr>'+
+ testInfo.join(' ')+
+ '<caption class="note"><p>This table summarizes the results of the regression tests, which consist of all compsets for several apps on several platforms. Each row above represents one app on one platform; select the row for details. Legend:</p><p>'
+ +'<span class="passrow">PASS</span> - all compsets ran to completion and matched baseline<br>'
+ +'<span class="failrow">FAIL</span> - a compset failed or did not match the baseline<br>'
+ +'<span class="failrow">ABORT</span> - regression test system failed; results are unknown<br>'
+ +'<span class="passold">PASS [OLD]</span> - compsets matched baseline, but test has not run in >30 hours<br>'
+ +'<span class="passancient">PASS [ANCIENT]</span> - compsets matched baseline, but test has not run in >5 days</p>';
+ if(old_wcoss_tests>1) {
+ text=text+'<p>*<b>WCOSS NOTE</b>: WCOSS is divided into a production side and a development side which swap frequently. Often, there is no development side; it is down for maintenance. When that happens, the "Result" column will display "PASS [OLD]" if the test passed before the downtime. You may occasionally see comically large ages with "PASS [ANCIENT]". Those are the tests before the last production switch replacing the latest ones. A day or two after WCOSS is available for development again, the regression tests run normally, and you will see the normal PASS or FAIL messages for each app on WCOSS.</p>';
+ }
+ text=text+'</caption></table>';
+ document.body.innerHTML=text;
+ return;
+ }
+ dir=TEST_DIRS[current_dir_index];
+ current_dir_index++;
+ txt=dir+"/regtest.txt"+cachebuster();
+ document.body.innerHTML="<h1>Loading "+dir+"</h1>"+
+ '<p class="loading">Please wait. Loading '+txt+"...</p>";
+ reader=new XMLHttpRequest();
+ reader.open("GET",txt,true);
+ reader.onreadystatechange=function () {
+ if(reader.readyState==4) {
+ if(reader.status==200) {
+ testInfo.push(parseText(dir,txt,reader.responseText));
+ } else {
+ testInfo.push(errorText(dir,txt,reader.status));
+ }
+ loadPage();
+ }
+ }
+ reader.send(null);
+}
+
+window.onload=function() {
+ var reader;
+ var dir;
+ var txt;
+ current_dir_index=0;
+ loadPage();
+}
Index: checkout/tests/web-top/index.html
===================================================================
--- checkout/tests/web-top/index.html (nonexistent)
+++ checkout/tests/web-top/index.html (revision 100116)
@@ -0,0 +1,18 @@
+<html><head>
+ <title>NEMS Regression Tests</title>
+ <link rel="stylesheet" href="regtestview.css" type="text/css"/>
+ <script src="regtestlist.js"></script>
+</head>
+<body>
+<div id="content">
+
+</div>
+<noscript>
+<h1>Turn on Javascript Support (2).</h1>
+
+<p>It appears you have Javascript blocked for this website or turned
+off entirely. In order to use the automatic regression test viewer,
+you must enable javascript.</p>
+</noscript>
+</body>
+</html>
Index: checkout/tests/multi-app-test.sh
===================================================================
--- checkout/tests/multi-app-test.sh (nonexistent)
+++ checkout/tests/multi-app-test.sh (revision 100116)
@@ -0,0 +1,1353 @@
+#! /bin/sh
+
+set -m # enable job control
+
+if [[ "$#" != 4 && "$2" == resume_test ]] ; then
+ echo "SYNTAX: cat apps.def commit.def | multi-app-test.sh platform resume_test AppName /path/to/app" 1>&2
+ echo "When resuming a test, you must specify which test to resume." 1>&2
+elif [[ "$#" != 3 && "$2" == master ]] ; then
+ echo "SYNTAX: cat apps.def commit.def | multi-app-test.sh platform master /path/to/file/with/commit/message" 1>&2
+ echo "When resuming a test, you must specify which test to resume." 1>&2
+elif [[ "$#" != 2 && "$2" != master && "$2" != resume_test ]] ; then
+ echo "SYNTAX: cat apps.def commit.def | multi-app-test.sh platform stage" 1>&2
+ echo " OR: cat apps.def commit.def | multi-app-test.sh platform resume_test /path/to/NEMS/tests" 1>&2
+ echo " OR: cat apps.def commit.def | multi-app-test.sh platform master /path/to/file/with/commit/message" 1>&2
+ exit 2
+fi
+
+if ( test -t 0 ) ; then
+ echo "ERROR: stdin must not be a terminal." 1>&2
+ echo "SYNTAX: cat apps.def commit.def | multi-app-test.sh platform stage" 1>&2
+ exit 2
+fi
+
+# Kill child processes on abnormal exit:
+prolicide() {
+ set +uex
+ jobs=$( jobs -p )
+ if [[ ! -z "$jobs" ]] ; then
+ kill $jobs
+ fi
+ return 0
+}
+trap 'result="$?" ; if [[ "$result" != 0 ]] ; then prolicide ; fi ; exit $result' EXIT
+trap 'prolicide ; exit 1' SIGINT SIGTERM SIGHUP SIGQUIT
+
+platform="$1"
+stage="$2"
+
+########################################################################
+
+nonsense() {
+ local which=$(( RANDOM % 12 ))
+ case "$which" in
+ 0) echo "blunder: Script is aborting due to metaphysical dilemma." ;;
+ 1) echo "blunder: Rumination failure. Check for false dichotomies." ;;
+ 2) echo "blunder: Aborting due to loss of ipseity." ;;
+ 3) echo "blunder: This process has been eaten by a grue." ;;
+ 4) echo "blunder: Check for gremlins." ;;
+ 5) echo "blunder: Brain-dump into sewer. Please retrieve." ;;
+ 6) echo "blunder: Kernel panic: no popcorn remains." ;;
+ 7) echo "blunder: Existential error: null pointer dereference." ;;
+ 8) echo "blunder: No clam found in shell. Try again?" ;;
+ 9) echo "blunder: Sanity lost. Please find." ;;
+ 10) echo "blunder: Operator failed. Please replace." ;;
+ *) echo "blunder: CPU elves are on a lunch break. Check back later?" ;;
+ esac
+}
+
+########################################################################
+
+forbid_terminals() {
+ local stage="$1"
+ if ( test -t 1 -o -t 2 ) ; then
+ nonsense 1>&2
+ echo 1>&2
+ echo "FATAL ERROR: this process is connected to a terminal." 1>&2
+ echo "In stage \"$stage\" this script must not be connected to a terminal." 1>&2
+ echo "Run in nohup, CRON, or a batch job." 1>&2
+ echo 1>&2
+ # Both git and svn can do odd things if they are connected to
+ # a terminal when their process is backgrounded.
+ exit 2
+ fi
+}
+
+########################################################################
+
+set_global() {
+ # Allows setting a calculated variable name to a value.
+ # set_global variable_name value
+ local var=$( echo "$1" | sed 's,[. -],_,g' )
+ local value="$2"
+ eval "$var=\"\$value\""
+ #new_value=$( get_global "$var" )
+ #echo "$var=$value=$new_value" 1>&2
+}
+
+have_global() {
+ # Given a string, see if a variable by that name exists.
+ # have_global variable_name
+ local var=$( echo "$1" | sed 's,[. -],_,g' )
+ eval "[[ ! -z \"\$$var\" ]]"
+}
+
+get_global() {
+ # Given a string, get the value of the variable with that name
+ # get_global variable_name
+ local var=$( echo "$1" | sed 's,[. -],_,g' )
+ local result=$( eval "echo \"\$$var\"" )
+ #echo "GET $var=$result" 1>&2
+ echo "$result"
+}
+
+get_global_or_default() {
+ # Given a string, get the value of the variable with that name
+ # get_global variable_name
+ local var=$( echo "$1" | sed 's,[. -],_,g' )
+ local default="$2"
+ #echo "GET $var OR $default" 1>&2
+ eval "echo \"\${$var:-$default}\""
+}
+
+########################################################################
+
+parse_control_file() {
+ local context key command value
+ local check_platform check_apps
+ local result=0
+ local lineno=0
+ local eof=0
+ platforms=""
+ all_apps=""
+ set +eux
+ #set -x
+
+ # Default values:
+ user=MISSING
+ role=MISSING
+ nems_branch=default
+ app_branch=MISSING
+ master_branch=master
+ more_rt_sh_args=
+
+ while [[ $eof == 0 ]] ; do
+ lineno=$(( lineno+1 ))
+ read context key command value
+ eof=$?
+ check_platform_in_key=NO
+ check_apps_in_value=NO
+ check_app_in_key=NO
+ if [[ -z "$context" ]] ; then
+ continue # blank line
+ elif [[ "${context:0:1}" == '#' ]] ; then
+ #echo "line $lineno: comment: $context $key $command $value" 1>&2
+ continue
+ elif [[ -z "$value" ]] ; then
+ result=1
+ echo "line $lineno: invalid line; no value: $context $key $command $value" 1>&2
+ elif [[ "$context" == PLATFORM && "$command" == NAME ]] ; then
+ #echo "Platform $key has name $value"
+ platforms="$platforms $key"
+ set_global "platform_${key}_name" "$value"
+ elif [[ "$context" == APP && "$command" == COMPSETS ]] ; then
+ #echo "App $key shall run compsets specified by: $value"
+ set_global "compsets_for_$key" "$value"
+ all_apps="$all_apps $key"
+ check_app_in_key=YES
+ elif [[ "$context" == APP && "$command" == URL ]] ; then
+ #echo "App $key URL is: $value"
+ set_global "app_url_$key" "$value"
+ check_app_in_key=YES
+ elif [[ "$context" == APP && "$command" == CHECKOUT ]] ; then
+ echo "App $key starting branch is: $value"
+ set_global "starting_branch_for_$key" "$value"
+ check_app_in_key=YES
+ elif [[ "$context" == ON && "$command" == EXTRA_ARGS ]] ; then
+ #echo "Platform $key uses extra args to NEMSCompsetRun: $value" 1>&2
+ set_global "rt_sh_args_for_$key" "$value"
+ check_platform_in_key=YES
+ elif [[ "$context" == ON && "$command" == SCRUB ]] ; then
+ #echo "Platform $key uses scrub space $value"
+ set_global "scrub_space_for_$key" "$value"
+ check_platform_in_key=YES
+ elif [[ "$context" == ON && "$command" == APPS ]] ; then
+ #echo "Platform $key will run apps $value"
+ set_global "app_list_for_$key" "$value"
+ check_platform_in_key=YES
+ check_apps_in_value=YES
+ elif [[ "$context $key $command" == "USER ACCOUNT IS" ]] ; then
+ user="$value"
+ elif [[ "$context $key $command" == "ROLE ACCOUNT IS" ]] ; then
+ role="$value"
+ elif [[ "$context $key $command" == "NEMS BRANCH IS" ]] ; then
+ nems_branch="$value"
+ elif [[ "$context $key $command" == "APP BRANCH IS" ]] ; then
+ app_branch="$value"
+ elif [[ "$context $key $command" == "MASTER BRANCH IS" ]] ; then
+ master_branch="$value"
+ elif [[ "$context" == ON && "$command" == WEBPAGE ]] ; then
+ #echo "Platform $key sends to webpage $value"
+ set_global "webpage_for_$key" "$value"
+ check_platform=YES
+ check_apps=YES
+ else
+ echo "line $lineno: invalid line: $context $key $command $value" 1>&2
+ result=1
+ fi
+
+ if [[ "$check_platform_in_key" == YES ]] ; then
+ if ( ! have_global "platform_${key}_name" ) ; then
+ echo "line $lineno: unknown platform $key (no PLATFORM...NAME block for this)" 1>&2
+ result=1
+ fi
+ fi
+ if [[ "$check_app_in_key" == YES ]] ; then
+ if ( ! have_global "compsets_for_$key" ) ; then
+ echo "line $lineno: unknown app $key (no APP...COMPSETS line for this app)" 1>&2
+ result=1
+ fi
+ fi
+ if [[ "$check_apps_in_value" == YES ]] ; then
+ for app in $value ; do
+ if ( ! have_global "compsets_for_$app" ) ; then
+ echo "line $lineno: unknown app $app (no APP...COMPSETS line for this app)" 1>&2
+ result=1
+ fi
+ done
+ fi
+ done
+ if [[ "$user" == MISSING ]] ; then
+ echo "user: missing \"USER ACCOUNT IS\" line in stdin" 1>&2
+ result=1
+ fi
+ if [[ "$role" == MISSING ]] ; then
+ echo "role: missing \"ROLE ACCOUNT IS\" line in stdin" 1>&2
+ result=1
+ fi
+ if [[ "$nems_branch" != default && "$app_branch" == MISSING ]] ; then
+ echo "role: when a nems branch is specified, the app branch must also be specified. Missing \"APP BRANCH IS\" line in stdin." 1>&2
+ result=1
+ fi
+ if [[ "$master_branch" != master ]] ; then
+ cat<<EOF 1>&2
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!
+
+ The master branch is set to "$master_branch" instead of "master"
+ This means the commits will NOT go to the git master of NEMS nor
+ the git master of apps. You probably do not want to do this!
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!
+EOF
+ fi
+ if [[ -z "$platforms" ]] ; then
+ nonsense 1>&2
+ echo "No platforms defined!" 1>&2
+ echo "Send the control file into stdin!" 1>&2
+ exit 1
+ fi
+ if [[ "$result" != 0 ]] ; then
+ nonsense 1>&2
+ echo "ABORT: Errors in control file." 1>&2
+ exit 1
+ fi
+ if ( ! have_global "platform_${platform}_name" ) ; then
+ nonsense 1>&2
+ echo "ERROR: Unknown platform \"$platform\" selected on command line." 1>&2
+ echo "Known platforms: $platforms" 1>&2
+ exit 1
+ fi
+}
+
+########################################################################
+
+# Accessors of data from the control file
+
+get_app_url() {
+ local app="$1"
+ get_global_or_default "app_url_$app" "gerrit:$app"
+}
+
+get_app_test_set() {
+ local app="$1"
+ get_global "compsets_for_$app"
+}
+
+get_human_readable_name_for_platform() {
+ local plat="${1:-$platform}"
+ get_global "platform_${plat}_name"
+}
+
+get_scrub_for_user() {
+ local username="$1"
+ local expr=$( get_global "scrub_space_for_$platform" )
+ eval "echo $expr"
+}
+
+get_app_list_for_platform() {
+ local plat="${1:-$platform}"
+ get_global "app_list_for_$plat"
+}
+
+get_webpage_for_platform() {
+ local plat="${1:-$platform}"
+ get_global_or_default "webpage_for_$plat" "none"
+}
+
+get_rt_sh_args() {
+ local plat="${1:-$platform}"
+ get_global_or_default "rt_sh_args_for_$plat" " "
+}
+
+get_app_starting_branch() {
+ local app="$1"
+ get_global_or_default "starting_branch_for_$app" "$master_branch"
+}
+
+get_platform_specific_variables() {
+ webpage=$( get_webpage_for_platform )
+ workuser=$( get_scrub_for_user "$user" )
+ worknems=$( get_scrub_for_user "$role" )
+ apps=$( get_app_list_for_platform )
+ more_rt_sh_args=$( eval echo $( get_rt_sh_args ) )
+ webuser=$( echo "$webpage" | awk 'BEGIN{FS=":"}{print $1}' )
+ webbase=$( echo "$webpage" | awk 'BEGIN{FS=":"}{print $2}' )
+ email_from=$user at noaa.gov
+ email_to=$user at noaa.gov
+}
+
+########################################################################
+
+dump_control_file() {
+ local url tests starting_branch
+ get_platform_specific_variables
+ local human_platform=$( get_human_readable_name_for_platform )
+ echo "DUMP OF CONTROL FILES FROM STDIN"
+ echo
+ echo "Known platforms: $platforms"
+ echo "Known apps: $all_apps"
+ echo
+ echo "PLATFORM $human_platform"
+ echo " - key = $platform"
+ echo " - user $user work area = $workuser"
+ echo " - role $role work area = $worknems"
+ echo " - back-end website login = $webuser"
+ echo " - back-end website dir = $webbase"
+ if [[ ! -z "$more_rt_sh_args" ]] ; then
+ echo " - extra args to NEMSCompsetRun = $more_rt_sh_args"
+ fi
+ echo
+ echo "BRANCHES:"
+ if [[ "$nems_branch" == default ]] ; then
+ echo " - apps: master"
+ echo " - nems: Use each app's own NEMS."
+ else
+ echo " - apps: $app_branch"
+ echo " - nems: $nems_branch"
+ if [[ "$master_branch" != master ]] ; then
+ echo " - push to master: $master_branch"
+ fi
+ fi
+ echo
+ echo "APPS TO RUN: $apps"
+ for app in $apps ; do
+ url=$( get_app_url $app )
+ tests=$( get_app_test_set $app )
+ echo " - $app ($url) will run $tests"
+ done
+ echo
+ echo "BRANCHING INFO: $all_apps"
+ for app in $all_apps ; do
+ url=$( get_app_url $app )
+ starting_branch=$( get_app_starting_branch $app )
+ if [[ "$starting_branch" != "$master_branch" ]] ; then
+ echo " - $app ($url) checkout $starting_branch push to $app_branch"
+ else
+ echo " - $app ($url) push to $app_branch"
+ fi
+ done
+}
+
+########################################################################
+
+mkdir_p_workaround() {
+ # If multiple threads "mkdir -p" a directory at the same time,
+ # then all but one thread will fail.
+ local dir="$1"
+ local x
+ for x in $( seq 1 10 ) ; do
+ ( set +e ; mkdir -p "$dir" ; exit 0 )
+ if [[ -d "$dir" ]] ; then
+ echo "mkdir -p \"$1\": success after $x tries" 1>&2
+ return 0
+ fi
+ done
+ echo "mkdir -p \"$1\": gave up after $x tries" 1>&2
+ return 1
+}
+
+########################################################################
+
+require_a_nems_branch() {
+ if [[ "$nems_branch" == default ]] ; then
+ nonsense 1>&2
+ echo "NEMS commit process is disabled. Running in Nightly Test mode." 1>&2
+ echo "Will not make any branches." 1>&2
+ exit 1
+ fi
+}
+
+########################################################################
+
+run_in_background_for_each_app() {
+ local workdir="$1"
+ local log_name="$2"
+ local command_template="$3"
+ local app_list_id="$4"
+ local app_list
+ local command
+
+ if [[ "$app_list_id" == all_apps ]] ; then
+ app_list="$all_apps"
+ else
+ app_list=$( get_app_list_for_platform )
+ fi
+
+ set -ue
+
+ # Make a file that will hold exit statuses.
+ local status_file="${TMPDIR:-/tmp}/${log_name}_status.$$.$RANDOM.$RANDOM"
+ echo 0 > "$status_file"
+ chmod 600 "$status_file"
+ echo 0 > "$status_file"
+
+ mkdir_p_workaround "$workdir/log"
+ cd "$workdir/log"
+ for app in $app_list ; do
+ log="${app}_${platform}_${log_name}.log"
+ if [[ "$nems_branch" != default ]] ; then
+ log="$nems_branch-$log"
+ fi
+ command=$( eval "echo $command_template" )
+
+ echo "$app: log $log"
+ echo "$app: running $command"
+
+ ( set +xue ;
+ ( $command > "$log" 2>&1 ) ;
+ result=$? ;
+ echo "$result" >> "$status_file" ;
+ echo "$app: exit $result" 1>&2 ) &
+ done
+ wait
+
+ local status
+ local max_status=0
+ for status in $( cat "$status_file" ) ; do
+ if [[ "$status" -gt 0 && ( "$status" -gt "$max_status" || "$max_status" == 0 ) ]] ; then
+ max_status=status
+ fi
+ done
+
+ rm -f "$status_file"
+
+ if [[ "$max_status" != 0 ]] ; then
+ echo "FAILURE: $log_name: non-zero exit status $max_status!" 1>&2
+ return 1
+ fi
+ echo "Zero exit status for all jobs."
+ return 0
+}
+
+########################################################################
+
+generate_hash_for_test_name() {
+ local purpose="$1"
+ local name="$2"
+ echo "$purpose"-$( echo "$name" | md5sum | cut -c1-8 )
+}
+
+########################################################################
+
+repeatedly_try_to_run() {
+ local tries scale naptime success
+ local max_tries=7
+ success=NO
+ for tries in $( seq 1 $max_tries ) ; do
+ if ( "$@" ) ; then
+ return 0
+ fi
+
+ # We sleep a random time after pulling to reduce the chances
+ # of many simultaneous pushes.
+ if [[ "$tries" -lt 11 ]] ; then
+ scale=$(( 2**tries / tries + tries))
+ else
+ scale=180
+ fi
+ if [[ "$scale" -lt 3 ]] ; then
+ $scale=3
+ fi
+ naptime=$(( 1 + $RANDOM%$scale ))
+ echo "Sleep $naptime..."
+ sleep $naptime
+ done
+
+ echo "$*: failed after $tries tries" 1>&2
+ return 1
+}
+
+########################################################################
+
+repeatedly_try_to_push() {
+ # Pull and push until we succeed in pushing:
+ local tries scale naptime success
+ local max_tries=7
+ success=NO
+ for tries in $( seq 1 $max_tries ) ; do
+ git pull "$@" || true
+
+ # We sleep a random time after pulling to reduce the chances
+ # of many simultaneous pushes.
+ if [[ "$tries" -lt 11 ]] ; then
+ scale=$(( 2**tries / tries + tries))
+ else
+ scale=180
+ fi
+ if [[ "$scale" -lt 3 ]] ; then
+ $scale=3
+ fi
+ naptime=$(( 1 + $RANDOM%$scale ))
+ echo "Sleep $naptime..."
+ sleep $naptime
+
+ if ( git push "$@" ) ; then
+ success=YES
+ echo "Push success at try #$tries"
+ break
+ fi
+ done
+ if [[ "$success" != YES ]] ; then
+ echo "Unable to push to repository after $tries tries." 1>&2
+ return 1
+ fi
+ return 0
+}
+
+########################################################################
+
+make_branch() {
+ require_a_nems_branch
+ echo "MAKE BRANCH $*"
+ set -xe
+ local app="$1"
+ local unique_id="$2"
+ local delete="$3"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$app" )
+ if [[ "$?" != 0 || -z "$app_url" ]] ; then
+ echo "CANNOT CHECKOUT UNKNOWN APP $app" 1>&2
+ return 1
+ fi
+ local app_starting_branch=$( get_app_starting_branch "$app" )
+
+ local workdir="$workuser/branch_${nems_branch}_$unique_id"
+ mkdir_p_workaround "$workdir"
+ cd $workdir
+
+ local test_hash=$( generate_hash_for_test_name branch "$test_name" )
+
+ rm -rf "$test_hash"
+ repeatedly_try_to_run git clone "$app_url" "$test_hash"
+ cd "$test_hash"
+
+ # Make sure the branch does not exist before we create it.
+ if [[ "$delete" == DELETE ]] ; then
+ # We are being instructed to delete the branch if it exists.
+ git push origin --delete "$app_branch" || true
+ elif ( git branch -a | grep "origin/$app_branch" ) ; then
+ echo "$app_branch: already exists" 1>&2
+ exit 9
+ fi
+
+ git checkout "$app_starting_branch"
+ git checkout -b "$app_branch"
+ repeatedly_try_to_run git submodule update --init --recursive
+ cd NEMS
+ git fetch
+ git checkout "$nems_branch"
+ cd ..
+ git add NEMS
+ git commit -m "Check out NEMS $nems_branch"
+ repeatedly_try_to_push origin "$app_branch"
+ git branch --set-upstream-to=origin/"$app_branch" "$app_branch" || \
+ git branch --set-upstream "$app_branch" origin/"$app_branch"
+ cd ..
+ rm -rf "$test_hash"
+}
+
+########################################################################
+
+delete_branch() {
+ require_a_nems_branch
+ echo "DELETE BRANCH $*"
+ set -xe
+ local app="$1"
+ local unique_id="$2"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$app" )
+ if [[ "$?" != 0 || -z "$app_url" ]] ; then
+ echo "CANNOT CHECKOUT UNKNOWN APP $app" 1>&2
+ return 1
+ fi
+ local app_starting_branch=$( get_app_starting_branch "$app" )
+
+ local workdir="$workuser/delete_${nems_branch}_$unique_id"
+ mkdir_p_workaround "$workdir"
+ cd $workdir
+
+ local test_hash=$( generate_hash_for_test_name branch "$test_name" )
+
+ rm -rf "$test_hash"
+ repeatedly_try_to_run git clone "$app_url" "$test_hash"
+ cd "$test_hash"
+
+ git push origin --delete "$app_branch" || true
+ cd ..
+ rm -rf "$test_hash"
+}
+
+########################################################################
+
+checkout_app() {
+ # Checks out an app under the user and makes a flag file so the
+ # nemsuser knows where the checkout resides.
+ set -xe
+ local app="$1"
+ local unique_id="$2"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$1" )
+ if [[ "$?" != 0 || -z "$app_url" ]] ; then
+ echo "CANNOT CHECKOUT UNKNOWN APP $1" 1>&2
+ return 1
+ fi
+
+ local test_hash=$( generate_hash_for_test_name checkout "$test_name" )
+
+ mkdir_p_workaround "$workuser"
+ cd $workuser
+ rm -rf "$test_hash"
+
+ if ( echo "$app_url" | grep -E 'gerrit|git' > /dev/null 2>&1 ) ; then
+ which git
+ rm -rf "$test_hash"
+ repeatedly_try_to_run git clone "$app_url" "$test_hash"
+ else
+ which svn
+ svn co "$app_url" "$test_hash"
+ fi
+
+ cd "$test_hash"
+
+ if [[ "$nems_branch" != default ]] ; then
+ git checkout "$app_branch"
+ git branch --set-upstream-to=origin/"$app_branch" "$app_branch" || \
+ git branch --set-upstream "$app_branch" origin/"$app_branch"
+ fi
+
+ repeatedly_try_to_run git submodule update --init --recursive
+
+ if [[ -x checkout.sh ]] ; then
+ ./checkout.sh "$USER"
+ fi
+
+ chmod -R go=u-w .
+
+ echo $( date +%s ) $unique_id $( pwd ) > $workuser/$test_name.for.nemspara
+}
+
+########################################################################
+
+test_app() {
+ # Obtains the repo checked out by the user, and runs it. Creates
+ # a flag file so the next stages know how to find the results.
+ set -x
+ local app="$1"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$1" )
+ local set=$( get_app_test_set "$1" )
+ if [[ "$?" != 0 ]] ; then
+ echo "CANNOT TEST UNKNOWN APP $1" 1>&2
+ return 1
+ fi
+ set="${set:--f}"
+
+ local maxwait=1800
+ local flagfile="$workuser/$test_name".for.nemspara
+ local startdate=$( date )
+ if [[ -f "$HOME/nems-test-email-lists/$test_name" ]] ; then
+ email_to=$( echo $( cat "$HOME/nems-test-email-lists/$test_name" ) )
+ fi
+
+ mkdir_p_workaround "$worknems"
+
+ local scriptstart=$( date +%s )
+
+ local waitstart=$scriptstart
+ local waittime=0
+
+ while [[ ! -s "$flagfile" && $waittime -lt "$maxwait" ]] ; do
+ echo "$flagfile: empty or does not exist; sleep 30"
+ sleep 30
+ local nowtime=$( date +%s )
+ waittime=$(( nowtime - waitstart ))
+ done
+ if [[ ! -s "$flagfile" ]] ; then
+ nonsense 1>&2
+ echo "$flagfile: gave up waiting after $maxwait seconds."
+ exit 1
+ fi
+
+ sleep 15
+
+ local timestamp=$( head -1 "$flagfile" | awk '{print $1}' )
+ local unique_id=$( head -1 "$flagfile" | awk '{print $2}' )
+ local checkout=$( head -1 "$flagfile" | awk '{print $3}' )
+
+ set +e
+ echo "timestamp=$timestamp"
+ echo "unique_id=$unique_id"
+ echo "checkout=$checkout"
+ set -e
+
+ if (( scriptstart - timestamp > 3600*24 )) ; then
+ nonsense 1>&2
+ echo "$flagfile: timestamp is more than one day old. Check CRON."
+ exit 1
+ fi
+
+ if [[ ! -d "$checkout" ]] ; then
+ nonsense 1>&2
+ echo "$checkout: not a directory or does not exist. Check logs."
+ exit 1
+ fi
+
+ local test_hash=$( generate_hash_for_test_name test "$test_name" )
+
+ local workarea="$worknems/$test_hash"
+ cd /
+ rm -rf "$workarea"
+ mkdir_p_workaround "$workarea"
+ cd "$workarea"
+ set +e
+ rsync -arv "$checkout/." . || true
+ rsync -arv "$checkout/." .
+
+ set +eu
+ if [[ -d .svn ]] ; then
+ svn info . > repo.info
+ echo >> repo.info
+ svn propget svn:externals . | while read dir rest ; do
+ echo "$dir" >> repo.info
+ svn info "$dir" >> repo.info
+ done
+ else
+ (
+ echo REPO TOP:
+ git branch -vv | head -1 | cut -c3- ;
+ git remote show -n origin | grep 'Fetch URL:' | sed "s,^ *,,g" ;
+ git status -suno ;
+ echo ;
+ git submodule foreach 'sh -c '\''git branch -vv | head -1 | cut -c3- ; git remote show -n origin | grep "Fetch URL:" | sed "s,^ *,,g" ; git status -suno ; echo'\' ;
+ ) > repo.info
+ fi
+ set -eu
+ local repo_info_file="$( pwd -P )/repo.info"
+ test -s "$repo_info_file"
+
+ set +ue
+
+ env > env.out
+ module list > module-list.out 2>&1
+
+ rm -f rt-f.log # "$workarea"/log/report*log/*
+ echo "WILL RUN NEMSCompsetRun FOR SET \"$set\""
+ echo " IN DIR $( pwd -P )"
+ echo " LOGGING TO $( pwd )/rt-f.log"
+ echo " REPO INFO AT $repo_info_file"
+ echo "This may take a while..."
+
+ ./NEMS/NEMSCompsetRun --multi-app-test-mode \
+ $set $more_rt_sh_args > rt-f.log 2>&1
+
+ tail -20 rt-f.log
+
+ local status="$?"
+ cd NEMS/tests
+
+ echo "$( date +%s ) $( pwd )" > $worknems/$test_name.for.sam
+}
+
+########################################################################
+
+resume_test() {
+ set -x
+ local workarea="$1"
+ local app="$2"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$1" )
+ local set=$( get_app_test_set "$1" )
+ if [[ "$?" != 0 ]] ; then
+ echo "CANNOT TEST UNKNOWN APP $1" 1>&2
+ return 1
+ fi
+ set="${set:--f}"
+
+ set -e
+ test -d "$workarea"
+ cd "$workarea"
+ cd ../../
+
+ rm -f rt-f.log
+ set +x
+ echo "WILL RUN NEMSCompsetRun FOR SET \"$set\""
+ echo " IN DIR $( pwd -P )"
+ echo " LOGGING TO $( pwd )/rt-f.log"
+ echo " REPO INFO AT $repo_info_file"
+ echo "This may take a while..."
+ set -x
+
+ ./NEMS/NEMSCompsetRun --multi-app-test-mode \
+ $set $more_rt_sh_args > rt-f.log 2>&1
+
+ tail -20 rt-f.log
+
+ local status="$?"
+ cd NEMS/tests
+
+ echo "$( date +%s ) $( pwd )" > $worknems/$test_name.for.sam
+}
+
+########################################################################
+
+generate_regtest_txt_and_send_email() {
+ set -x
+ local test_name="$1"
+
+ local worktest=$( cat "$worknems/$test_name.for.sam" | awk '{print $2}' )
+ local workarea=$( cd "$worktest" ; cd ../.. ; pwd -P )
+ local rt_f_log="$workarea/rt-f.log"
+ local startdate=$( stat -c %z "$rt_f_log" )
+
+ local RUNDIR=''
+ local PLATFORM_NAME=''
+ vars=$( cat "$rt_f_log" | grep -E 'RUNDIR.*PLATFORM' )
+ eval $vars
+
+ if [[ -z "$PLATFORM_NAME" || -z "$RUNDIR" ]] ; then
+ # New scripts
+ local REPORT_DIR=$( cat "$rt_f_log" | perl -ne 'chomp; /copy build logs to (\S+)/ and do { print $1; exit }' )
+ local RTREPORT="$REPORT_DIR/rtreport.txt"
+ echo "New scripts. Report dir = $REPORT_DIR"
+ echo "New scripts. Report txt = $RTREPORT"
+ else
+ # Old scripts
+ local REPORT_DIR="$workarea/log/report-$PLATFORM_NAME-log"
+ local RTREPORT="$REPORT_DIR/rtreport.txt"
+ echo "Old scripts. Report dir = $REPORT_DIR"
+ echo "Old scripts. Report txt = $RTREPORT"
+ echo "Old scripts. Platform = $PLATFORM_NAME"
+ echo "Old scripts. Run dir = $RUNDIR"
+ fi
+
+ local result
+ local build
+ if [[ ! -s "$RTREPORT" ]] ; then
+ echo RTREPORT DOES NOT EXIST: $RTREPORT
+ result=ABORT
+ elif ( grep 'REGRESSION TEST FAILED' < $RTREPORT ) ; then
+ result=FAIL
+ elif ( grep 'REGRESSION TEST WAS SUCCESSFUL' < $RTREPORT ) ; then
+ result=PASS
+ else
+ result=ABORT
+ fi
+
+ REGRESSION_TEST_RESULT=$result
+
+ if [[ "$result" == PASS ]] ; then
+ echo "Success; will not email."
+ return 0
+ fi
+
+ (
+ echo "Automated NEMS regression test run at $startdate."
+ echo "Test result: $result."
+ echo "Completed at: $( date )."
+ echo "Main log: $REPORT_DIR/rtreport.txt"
+ for buildfile in "$REPORT_DIR/build"*log ; do
+ build=$( basename $buildfile | sed 's,build_,,g' | sed 's,\.x\.log,,g' )
+ echo "Compile log for $build: $buildfile"
+ done
+ echo
+ echo "========================================================================"
+ echo "Subversion information:"
+ cat "$repo_info_file"
+ echo
+ echo "========================================================================"
+ echo "Regression test log:"
+ cat $RTREPORT
+ ) | mail \
+ -s "Regression test result: $result" \
+ -r "$email_from" \
+ "$email_to"
+ set +x
+}
+
+########################################################################
+
+push_logs_to_branch() {
+ set -x
+ local app="$1"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$1" )
+ if [[ "$?" != 0 ]] ; then
+ echo "CANNOT PUSH LOGS TO UNKNOWN APP $1" 1>&2
+ return 1
+ fi
+
+ set -eu
+
+ # Find the directory in which nemspara ran the test:
+ local nemsfile="$worknems/$test_name.for.sam"
+ local testdir=$( head -1 "$nemsfile" | awk '{print $2}' )
+ local test_time=$( head -1 "$nemsfile" | awk '{print $1}' )
+ testdir=$testdir/../..
+ test -d "$testdir/NEMS/tests"
+
+ # Find the directory from which nemspara copied the repo:
+ local flagfile="$workuser/$test_name".for.nemspara
+ local checkout=$( head -1 "$flagfile" | awk '{print $3}' )
+ test -d "$checkout/NEMS/tests"
+
+ # Determine if the push has already happened
+ local push_flag_file="$workuser/$test_name".pushed
+ if [[ -s "$push_flag_file" ]] ; then
+ # A push happened. Did it happen after the test?
+ set +ue
+ local push_time=$( head -1 "$push_flag_file" | awk '{print $1}' )
+ if [[ "$push_time" -gt "$test_time" ]] ; then
+ echo "Push already done for this test of this repo."
+ exit 0
+ fi
+ fi
+
+ # Update the checkout directory with nemspara's logs:
+ cd "$checkout"
+ test -d NEMS/tests
+ rsync --exclude '*.o' --exclude '*.a' --exclude '*.mod' --exclude '*.exe' \
+ -arv "$testdir/." .
+
+ git add log
+ git commit -m "Commit logs for $platform testing NEMS $nems_branch"
+ repeatedly_try_to_push
+
+ echo "$( date +%s ) $app $( pwd )" > "$push_flag_file"
+}
+
+########################################################################
+
+deliver_test_to_web_server() {
+ # Finds the nemsuser's test and copies the result to the website.
+ set -x
+ local app="$1"
+ local test_name="${app}_on_${platform}"
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="$nems_branch-${test_name}"
+ fi
+ local app_url=$( get_app_url "$1" )
+ if [[ "$?" != 0 ]] ; then
+ echo "CANNOT DELIVER TEST FOR UNKNOWN APP $1" 1>&2
+ return 1
+ fi
+
+ set -eu
+
+ REGRESSION_TEST_RESULT=ABORT
+ generate_regtest_txt_and_send_email "$test_name"
+
+ local human_platform=$( get_human_readable_name_for_platform "$platform")
+ local human_name="$human_platform $app"
+ local javascript_name="$app/$platform"
+
+ local rtset='full'
+
+ umask 077 # Make sure only I can access my web directory.
+
+ local nemsfile="$worknems/$test_name.for.sam"
+
+ local timestamp=$( head -1 "$nemsfile" | awk '{print $1}' )
+ local result=$REGRESSION_TEST_RESULT
+ local testdir=$( head -1 "$nemsfile" | awk '{print $2}' )
+ test -d "$testdir"
+ local rtflog=$testdir/../../rt-f.log
+
+ ########################################################################
+
+ # Get further info from log files:
+ local RUNDIR=''
+ local PLATFORM_NAME=''
+ set +eu
+ local vars=$( cat "$testdir/../../rt-f.log" | grep -E 'RUNDIR.*PLATFORM' )
+ eval "$vars"
+
+ local LOGDIR
+ local RTREPORT
+
+ # New scripts
+ LOGDIR=$( cat $rtflog | perl -ne 'chomp; /copy build logs to (\S+)/ and do { print $1; exit }' )
+ RTREPORT="$LOGDIR/rtreport.txt"
+ echo "NEW SCRIPTS: $LOGDIR $RTREPORT"
+ local repo_info_file="$LOGDIR/../../repo.info"
+ set -eu
+ test -d "$LOGDIR"
+ test -s "$RTREPORT"
+
+ local REPORT_TIME=-1
+ local START_TIME=-1
+ #WORKFLOW REPORT AT %s (+%d)
+ eval $( cat "$RTREPORT" | perl -ne '
+if(m:WORKFLOW REPORT AT.*\(\+(\d+)\):) {
+ print "REPORT_TIME=$1 ";
+} elsif(m:WORKFLOW STARTED AT.*\(\+(\d+)\):) {
+ print "START_TIME=$1 ";
+};
+END {
+ print "\n";
+}' )
+
+ test -s "$repo_info_file"
+
+ ########################################################################
+
+ # Make the local version of the web directory:
+
+ local webdir_pre="$workuser/webdir.$test_name.$( date +%s )."
+ local webdir="$workuser/webdir.$test_name.$( date +%s ).$$"
+ rm -rf "$webdir_pre"*
+ mkdir_p_workaround "$webdir"
+ cd "$webdir"
+
+ ########################################################################
+
+ # Generate regtest.txt:
+ (
+ set -xue
+ echo "===!REGTEST BEGIN +$START_TIME"
+ echo "===!REGTEST PLATFORM $human_name"
+ echo "===!REGTEST RESULT $result"
+ echo "===!REGTEST REPO BEGIN"
+ grep -vE '^===!REGTEST' "$repo_info_file"
+ echo "===!REGTEST REPO END"
+ echo "===!REGTEST LOG BEGIN"
+ grep -vE '^===!REGTEST' "$RTREPORT"
+ echo "===!REGTEST LOG END"
+ for buildfile in "$LOGDIR/build"*log ; do
+ build=$( basename $buildfile | sed 's,build_,,g' | sed 's,\.log,,g' )
+ echo "===!REGTEST COMPILE $build"
+ grep -vE '^===!REGTEST' "$buildfile"
+ echo "===!REGTEST COMPILE END"
+ done
+ echo "===!REGTEST END +$REPORT_TIME"
+ ) | perl -ne 's:[^ -~\t\r\n]:_:gms ; print' > "regtest.txt"
+
+########################################################################
+
+ # Generate index.html
+
+ cat<<EOF > index.html
+<html><head>
+ <title>$human_name Regression Tests</title>
+ <link rel="stylesheet" href="../../regtestview.css" type="text/css"/>
+ <script src="../../regtestview.js"></script>
+</head>
+<body>
+<div id="content">
+
+</div>
+<noscript>
+<h1>Turn on Javascript Support (3).</h1>
+
+<p>It appears you have Javascript blocked for this website or turned
+off entirely. In order to use the automatic regression test viewer,
+you must enable javascript. If you want to view the original
+regression test text files instead, they are embedded in the <a
+href="regtest.txt">regtest.txt</a> in this directory. You will find
+the Javascript-based viewer more user-friendly than viewing that file
+directly. Please turn on Javascript for this webpage.</p>
+</noscript>
+</body>
+</html>
+EOF
+
+ ########################################################################
+
+ # Copy to website
+
+ set +e
+ ssh $webuser mkdir -p "$webbase/$javascript_name"
+ set -e
+
+ sleep 2
+
+ rsync -arv -e ssh . "$webuser:$webbase/$javascript_name/."
+
+ sleep 2
+
+ if ( ! ssh $webuser chmod -R go=u-w "$webbase/$javascript_name/." ) ; then
+ sleep 2
+ ssh $webuser chmod -R go=u-w "$webbase/$javascript_name/."
+ fi
+}
+
+########################################################################
+
+copy_static_files_to_website() {
+ local platform app
+ set -xue
+ cd $( dirname "$0" )
+ cd web-top
+
+ local tempfile="temp-regtestlist.js.temp"
+
+ local test_name='NEMS Nightly Regression Tests'
+ if [[ "$nems_branch" != default ]] ; then
+ test_name="Test of NEMS $nems_branch"
+ fi
+
+ set +x
+ cat<<EOF >> "$tempfile"
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// THIS SCRIPT IS AUTOMATICALLY GENERATED. ALL EDITS WILL BE LOST!
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+// You need to edit the app list and regtestlist.js.in instead,
+// and rerun the multi-app-test.sh script.
+
+TEST_NAME="$test_name";
+
+// TEST_DIRS is automatically generated from the app list:
+TEST_DIRS=[
+EOF
+ local first=YES
+ for platform in $platforms ; do
+ for app in $( get_app_list_for_platform "$platform" ) ; do
+ if [[ "$first" == YES ]] ; then
+ first=NO
+ else
+ echo , >> "$tempfile"
+ fi
+ echo -n " '$app/$platform'" >> "$tempfile"
+ done
+ done
+ cat<<EOF >> "$tempfile"
+];
+
+// The rest of this file is copied from regtestlist.js.in:
+
+EOF
+ cat regtestlist.js.in >> "$tempfile"
+ set -x
+ mv -f "$tempfile" regtestlist.js
+
+ ssh $webuser mkdir -p $webbase
+ rsync --exclude 'temp*temp' -arv . $webuser:$webbase/.
+
+}
+
+########################################################################
+
+commit_if_needed() {
+ local commit_file="$1"
+ local result
+ set +e
+ git commit -F "$commit_file" 2>&1 | tee errfile.$$
+ result="$?"
+ set -e
+ if [[ "$result" != 0 ]] ; then
+ if ( grep -iE 'nothing.*commit' errfile.$$ ) ; then
+ return 0
+ fi
+ return 1
+ fi
+}
+
+########################################################################
+
+push_to_master() {
+ require_a_nems_branch
+ set -xue
+ local commit_file="$1"
+ local workspace="$workuser/push_${app_branch}_to_${master_branch}.$$.$RANDOM"
+ local app
+
+ mkdir -p "$workspace"
+ cd "$workspace"
+
+ # Make sure the commit file exists, is non-empty, and is readable:
+ test -s "$commit_file"
+ head "$commit_file"
+
+ # Make sure all apps have urls:
+ for app in $all_apps ; do
+ get_app_url $app
+ done
+
+ # Check out $master_branch and $app_branch of each app:
+ for app in $all_apps ; do
+ git clone $( get_app_url $app ) "$app"
+ cd "$app"
+ # Make sure the $master_branch exists:
+ git checkout "$master_branch"
+ # Now get the $app_branch, which is what we want to use next:
+ git checkout "$app_branch"
+ cd ..
+ done
+
+ # Check out $master_branch of NEMS:
+ git clone gerrit:NEMS NEMS
+ cd NEMS
+ git checkout "$master_branch"
+
+ # Merge, commit, and push the $nems_branch:
+ git merge --squash "origin/$nems_branch"
+ commit_if_needed "$commit_file"
+ repeatedly_try_to_push
+ cd ..
+
+ # Update each app to point to the nems $master_branch and push:
+ for app in $all_apps ; do
+ cd "$app"
+
+ # Update to NEMS $master_branch and push that change:
+ cd NEMS
+ rsync -arv ../../NEMS/. .
+ cd ..
+ git add NEMS
+ echo "Point to head of NEMS $master_branch." > point-to-head.txt
+ commit_if_needed point-to-head.txt
+ repeatedly_try_to_push
+
+ # Merge $app_branch to $master_branch and push:
+ git checkout "$master_branch"
+ git merge --squash "$app_branch"
+ commit_if_needed "$commit_file"
+ repeatedly_try_to_push
+
+ cd ..
+ done
+
+ echo "Rejoice! Commit has been successful!"
+}
+
+########################################################################
+
+parse_control_file
+get_platform_specific_variables
+
+case "$stage" in
+ dump)
+ dump_control_file
+ exit $?
+ ;;
+ make_branches)
+ forbid_terminals $stage
+ global_unique_id=$$.$RANDOM
+ run_in_background_for_each_app "$workuser" make_branches \
+ 'make_branch "$app" "$global_unique_id"' all_apps
+ ;;
+ delete_branches)
+ forbid_terminals $stage
+ global_unique_id=$$.$RANDOM
+ run_in_background_for_each_app "$workuser" delete_branches \
+ 'delete_branch "$app" "$global_unique_id"' all_apps
+ ;;
+ delete_and_make_branches)
+ forbid_terminals $stage
+ global_unique_id=$$.$RANDOM
+ run_in_background_for_each_app "$workuser" make_branches \
+ 'make_branch "$app" "$global_unique_id" DELETE' all_apps
+ ;;
+ resume_test)
+ app_argument="$3"
+ path_argument="$4"
+ resume_test "$path_argument" "$app_argument"
+ ;;
+ web_init)
+ copy_static_files_to_website
+ exit $?
+ ;;
+ checkout)
+ forbid_terminals $stage
+ global_unique_id=$$.$RANDOM
+ run_in_background_for_each_app "$workuser" checkout \
+ 'checkout_app "$app" "$global_unique_id"' platform_apps
+ ;;
+ test)
+ run_in_background_for_each_app "$worknems" test \
+ 'test_app "$app"' platform_apps
+ ;;
+ push)
+ forbid_terminals $stage
+ require_a_nems_branch
+ run_in_background_for_each_app "$workuser" push \
+ 'push_logs_to_branch "$app"' platform_apps
+ ;;
+ deliver)
+ forbid_terminals $stage
+ run_in_background_for_each_app "$workuser" deliver \
+ 'deliver_test_to_web_server "$app"' platform_apps
+ ;;
+ master)
+ #forbid_terminals $stage # do not need this because we are not backgrounding
+ require_a_nems_branch
+ set -x
+ push_to_master "$3"
+ ;;
+ *)
+ nonsense 1>&2
+ cat<<EOF 1>&2
+UNKNOWN STAGE $stage
+ make_branches - create a branch for this test in each app's repository
+ abort if the branch already exists
+ delete_and_make_branches - same as make_branches, but delete the branch first
+ web_init - copy static files to website
+ checkout - check out all apps that will run on this platform
+ test - run in the role account to execute the tests
+ push - push the logs to the branch made in the make_branches step
+ deliver - deliver results to website
+ master - push changes to the master of NEMS and all apps.
+ dump - print parsed contents of the definition files (stdin)
+
+ABORTING: unknown stage $stage
+EOF
+ exit 1
+esac
Property changes on: checkout/tests/multi-app-test.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: checkout/src/conf/module-setup.sh.inc
===================================================================
--- checkout/src/conf/module-setup.sh.inc (revision 99852)
+++ checkout/src/conf/module-setup.sh.inc (revision 100116)
@@ -31,7 +31,7 @@
elif [[ -d /gpfs/hps && -e /etc/SuSE-release ]] ; then
# We are on NOAA Luna or Surge
if ( ! eval module help > /dev/null 2>&1 ) ; then
- source /opt/modules/default/init/$__ms_shell
+ source /opt/modules/default/init/$__ms_shell
fi
module purge
module purge
@@ -51,6 +51,12 @@
source /usrx/local/Modules/default/init/$__ms_shell
fi
module purge
+elif [[ -L /usrx && "$( readlink /usrx 2> /dev/null )" =~ dell ]] ; then
+ # We are on NOAA Mars or Venus
+ if ( ! eval module help > /dev/null 2>&1 ) ; then
+ source /usrx/local/prod/lmod/lmod/init/$__ms_shell
+ fi
+ module purge
elif [[ -d /glade ]] ; then
# We are on NCAR Yellowstone
if ( ! eval module help > /dev/null 2>&1 ) ; then
@@ -66,8 +72,38 @@
# the module command fails. Hence we actually have to source
# /etc/profile here.
source /etc/profile
+ __ms_source_etc_profile=yes
+ else
+ __ms_source_etc_profile=no
fi
+ echo GAEA
module purge
+# clean up after purge
+ unset _LMFILES_
+ unset _LMFILES_000
+ unset _LMFILES_001
+ unset LOADEDMODULES
+ module load modules
+ if [[ -d /opt/cray/ari/modulefiles ]] ; then
+ module use -a /opt/cray/ari/modulefiles
+ fi
+ if [[ -d /opt/cray/pe/ari/modulefiles ]] ; then
+ module use -a /opt/cray/pe/ari/modulefiles
+ fi
+ if [[ -d /opt/cray/pe/craype/default/modulefiles ]] ; then
+ module use -a /opt/cray/pe/craype/default/modulefiles
+ fi
+ if [[ -s /etc/opt/cray/pe/admin-pe/site-config ]] ; then
+ source /etc/opt/cray/pe/admin-pe/site-config
+ fi
+ export NCEPLIBS=/lustre/f1/pdata/ncep_shared/NCEPLIBS/lib
+ if [[ -d "$NCEPLIBS" ]] ; then
+ module use $NCEPLIBS/modulefiles
+ fi
+ if [[ "$__ms_source_etc_profile" == yes ]] ; then
+ source /etc/profile
+ unset __ms_source_etc_profile
+ fi
else
echo WARNING: UNKNOWN PLATFORM 1>&2
fi
Index: checkout/src/conf/configure.nems.NUOPC
===================================================================
--- checkout/src/conf/configure.nems.NUOPC (revision 99852)
+++ checkout/src/conf/configure.nems.NUOPC (revision 100116)
@@ -38,6 +38,7 @@
xocn_mk = $(XOCN_DIR)/xocn.mk
hycom_mk = $(HYCOM_DIR)/hycom_nuopc.mk
mom5_mk = $(MOM5_DIR)/mom5.mk
+mom6_mk = $(MOM6_DIR)/mom6.mk
pom_mk = $(POM_DIR)/pom.mk
################################################################################
Index: checkout/src/conf/module-setup.csh.inc
===================================================================
--- checkout/src/conf/module-setup.csh.inc (revision 99852)
+++ checkout/src/conf/module-setup.csh.inc (revision 100116)
@@ -35,6 +35,12 @@
source /usrx/local/Modules/default/init/$__ms_shell
endif
module purge
+else if ( { test -L /usrx && sh -c "readlink /usrx 2> /dev/null | grep dell" } ) then
+ # We are on WCOSS Mars or Venus
+ if ( ! { module help >& /dev/null } ) then
+ source /usrx/local/prod/lmod/lmod/init/$__ms_shell
+ endif
+ module purge
else if ( { test -d /glade } ) then
# We are on NCAR Yellowstone
if ( ! { module help >& /dev/null } ) then
@@ -50,8 +56,33 @@
# the module command fails. Hence we actually have to source
# /etc/csh.login here.
source /etc/csh.login
+ set __ms_source_etc_csh_login=yes
+ else
+ set __ms_source_etc_csh_login=no
endif
module purge
+ unsetenv _LMFILES_
+ unsetenv _LMFILES_000
+ unsetenv _LMFILES_001
+ unsetenv LOADEDMODULES
+ module load modules
+ if ( { test -d /opt/cray/ari/modulefiles } ) then
+ module use -a /opt/cray/ari/modulefiles
+ endif
+ if ( { test -d /opt/cray/pe/ari/modulefiles } ) then
+ module use -a /opt/cray/pe/ari/modulefiles
+ endif
+ if ( { test -d /opt/cray/pe/craype/default/modulefiles } ) then
+ module use -a /opt/cray/pe/craype/default/modulefiles
+ endif
+ setenv NCEPLIBS /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib
+ if ( { test -d /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib } ) then
+ module use $NCEPLIBS/modulefiles
+ endif
+ if ( "$__ms_source_etc_csh_login" == yes ) then
+ source /etc/csh.login
+ unset __ms_source_etc_csh_login
+ endif
else
# Workaround for csh limitation. Use sh to print to stderr.
sh -c 'echo WARNING: UNKNOWN PLATFORM 1>&2'
Index: checkout/src/module_EARTH_GRID_COMP.F90
===================================================================
--- checkout/src/module_EARTH_GRID_COMP.F90 (revision 99852)
+++ checkout/src/module_EARTH_GRID_COMP.F90 (revision 100116)
@@ -33,7 +33,7 @@
! | | |
! | | (CICE, etc.)
! | |
-! | (MOM5, HYCOM, POM, etc.)
+! | (MOM5, MOM6, HYCOM, POM, etc.)
! |
! CORE component (GSM, NMM, FV3, etc.)
!
@@ -81,6 +81,9 @@
#ifdef FRONT_MOM5
use FRONT_MOM5, only: MOM5_SS => SetServices
#endif
+#ifdef FRONT_MOM6
+ use FRONT_MOM6, only: MOM6_SS => SetServices
+#endif
#ifdef FRONT_POM
use FRONT_POM, only: POM_SS => SetServices
#endif
@@ -2460,6 +2463,22 @@
file=__FILE__)) &
return ! bail out
+ !For MOM6 and WW3 variables to match:
+ call NUOPC_FieldDictionarySetSyno( &
+ standardNames = (/"surface_eastward_sea_water_velocity",&
+ "ocn_current_zonal"/), rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+ call NUOPC_FieldDictionarySetSyno( &
+ standardNames = (/"surface_northward_sea_water_velocity",&
+ "ocn_current_merid"/), rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
if (.not.NUOPC_FieldDictionaryHasEntry( &
"eastward_stokes_drift_current")) then
call NUOPC_FieldDictionaryAddEntry( &
@@ -3016,6 +3035,19 @@
file=__FILE__, rcToReturn=rc)
return ! bail out
#endif
+ elseif (trim(model) == "mom6") then
+#ifdef FRONT_MOM6
+ call NUOPC_DriverAddComp(driver, trim(prefix), MOM6_SS, &
+ petList=petList, comp=comp, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=trim(name)//":"//__FILE__)) return ! bail out
+#else
+ write (msg, *) "Model '", trim(model), "' was requested, "// &
+ "but is not available in the executable!"
+ call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msg, line=__LINE__, &
+ file=__FILE__, rcToReturn=rc)
+ return ! bail out
+#endif
elseif (trim(model) == "pom") then
#ifdef FRONT_POM
call NUOPC_DriverAddComp(driver, trim(prefix), POM_SS, &
Index: checkout/src/module_MEDIATOR.F90
===================================================================
--- checkout/src/module_MEDIATOR.F90 (revision 99852)
+++ checkout/src/module_MEDIATOR.F90 (revision 100116)
@@ -21,6 +21,25 @@
! LND <-> HYD: Regrid, HYD not connected to ATM, OCN, ICE
! * 2015-12-16 Added NEMS_GridCopyCoord - DCR
! ATM <-> LND: Changed from Redist to Regrid
+ ! * 2017-09-08 Regridding from GSM to CICE or ocean models is done using only
+ ! sea points from GSM - B Li
+ ! * 2017-09-19 Added Nearest neighbor regridding option - B Li
+ ! * 2017-09-26 Set land_mask to be 1 if the interpolated land_mask from
+ ! ocean model is >= 10**(-6) - B Li
+ ! * 2017-10-24 Regridding from GSM to ocean and ice models (OCN/ICE) by masking out
+ ! GSM's land points (i.e. ignoring values at GSM's land points).
+ ! If no interpolated values can be obtained over OCN/ICE models' sea points
+ ! using bilinear or conservative methods, the interpolated values
+ ! from the nearest neighbor method will be used. - B Li.
+ ! * 2017-12-01 Removed fld_list_add(fldsFrIce,"dummyfield","cannot provide","bilinear").
+ ! Add the nearest neighbor regridding option for regridding from
+ ! OCN and ICE to ATM grid (search "BL2017b" in the code to see
+ ! where changes are made.)
+ ! * 2017-12-15 The bilinear and patch interpolation methods are currently not used
+ ! for any export variables from ice model. If
+ ! bilinear or path interpolation method is used in the future for regridding
+ ! ice variables to other model components, changes in subroutine
+ ! "MedPhase_prep_atm" is required. -B Li.
!-----------------------------------------------------------------------------
use ESMF
@@ -56,7 +75,11 @@
type(ESMF_FieldBundle):: FBaccumHyd ! accumulator of lnd export data
type(ESMF_FieldBundle):: FBaccumAtmOcn ! accumulator of atm export data
type(ESMF_FieldBundle):: FBAtm_a ! Atm export data on atm grid
- type(ESMF_FieldBundle):: FBAtm_o ! Atm export data mapped to ocn grid
+ type(ESMF_FieldBundle):: FBAtm_o ! Atm export data mapped to ocn grid
+!BL2017
+ type(ESMF_FieldBundle):: FBAtm2_o ! Atm export data mapped to ocn grid
+ type(ESMF_FieldBundle):: FBAtm2_i ! Atm export data mapped to ice grid
+!BL2017
type(ESMF_FieldBundle):: FBAtm_i ! Atm export data mapped to ice grid
type(ESMF_FieldBundle):: FBAtm_l ! Atm export data mapped to lnd grid
type(ESMF_FieldBundle):: FBAtm_h ! Atm export data mapped to hyd grid
@@ -75,6 +98,11 @@
type(ESMF_FieldBundle):: FBHyd_h ! Hyd export on hyd grid
type(ESMF_FieldBundle):: FBAtmOcn_o ! Atm/Ocn flux fields on ocn grid
type(ESMF_FieldBundle):: FBAtmOcn_a ! Atm/Ocn flux fields on atm grid
+!BL2017b
+ type(ESMF_FieldBundle):: FBOcn2_a ! Ocn export data mapped to atm grid
+ type(ESMF_FieldBundle):: FBIce2_a ! Ice export data mapped to atm grid
+ type(ESMF_FieldBundle):: FBAtmOcn2_a ! Atm/Ocn flux fields on atm grid
+!BL2017b
type(ESMF_FieldBundle):: FBforAtm ! data storage for atm import
type(ESMF_FieldBundle):: FBforOcn ! data storage for ocn import
type(ESMF_FieldBundle):: FBforIce ! data storage for ice import
@@ -116,6 +144,14 @@
type(ESMF_RouteHandle):: RH_i2o_consd ! ice to ocn
type(ESMF_RouteHandle):: RH_l2h_consd ! lnd to hyd
type(ESMF_RouteHandle):: RH_h2l_consd ! hyd to lnd
+!BL2017
+ type(ESMF_RouteHandle):: RH_a2o_nearest ! atm to ocn nearest neighbor stod
+ type(ESMF_RouteHandle):: RH_a2i_nearest ! atm to ice nearest neighbor stod
+!BL2017
+!BL2017b
+ type(ESMF_RouteHandle):: RH_i2a_nearest ! ice to atm nearest neighbor stod
+ type(ESMF_RouteHandle):: RH_o2a_nearest ! ocn to atm nearest neighbor stod
+!BL2017b
type(ESMF_RouteHandle):: RH_a2o_patch ! atm to ocn patch
type(ESMF_RouteHandle):: RH_o2a_patch ! ocn to atm
type(ESMF_RouteHandle):: RH_a2i_patch ! atm to ice
@@ -224,6 +260,10 @@
real(ESMF_KIND_R8), parameter :: spval_init = 0.0_ESMF_KIND_R8 ! spval for initialization
real(ESMF_KIND_R8), parameter :: spval = 0.0_ESMF_KIND_R8 ! spval
real(ESMF_KIND_R8), parameter :: czero = 0.0_ESMF_KIND_R8 ! spval
+!BL2017b
+! real(ESMF_KIND_R8), parameter :: c9999 = 9999.0_ESMF_KIND_R8 ! spval
+! real(ESMF_KIND_R8), parameter :: c9999 = 0.0_ESMF_KIND_R8 ! spval
+!BL2017b
integer , parameter :: ispval_mask = -987987 ! spval for RH mask values
type fld_list_type
@@ -525,7 +565,7 @@
call fld_list_add(fldsFrAtm,"mean_sensi_heat_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"mean_laten_heat_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"mean_down_lw_flx" , "will provide","conservefrac")
- call fld_list_add(fldsFrAtm,"mean_up_lw_flx" , "will provide","conservefrac")
+! call fld_list_add(fldsFrAtm,"mean_up_lw_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"mean_down_sw_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"mean_prec_rate" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"mean_fprec_rate" , "will provide","conservefrac")
@@ -534,7 +574,7 @@
call fld_list_add(fldsFrAtm,"inst_sensi_heat_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"inst_laten_heat_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"inst_down_lw_flx" , "will provide","conservefrac")
- call fld_list_add(fldsFrAtm,"inst_up_lw_flx" , "will provide","conservefrac")
+! call fld_list_add(fldsFrAtm,"inst_up_lw_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"inst_down_sw_flx" , "will provide","conservefrac")
call fld_list_add(fldsFrAtm,"inst_temp_height2m" , "will provide","bilinear")
call fld_list_add(fldsFrAtm,"inst_spec_humid_height2m", "will provide","bilinear")
@@ -621,13 +661,13 @@
call fld_list_add(fldsToOcn,"mean_down_sw_flx" , "will provide")
call fld_list_add(fldsToOcn,"mean_net_sw_flx" , "will provide")
call fld_list_add(fldsToOcn,"mean_net_lw_flx" , "will provide")
- call fld_list_add(fldsToOcn,"mean_up_lw_flx" , "will provide")
+! call fld_list_add(fldsToOcn,"mean_up_lw_flx" , "will provide")
call fld_list_add(fldsToOcn,"inst_temp_height2m" , "will provide")
call fld_list_add(fldsToOcn,"inst_spec_humid_height2m", "will provide")
call fld_list_add(fldsToOcn,"net_heat_flx_to_ocn" , "will provide")
call fld_list_add(fldsToOcn,"mean_fresh_water_to_ocean_rate", "will provide")
call fld_list_add(fldsToOcn,"mean_salt_rate" , "will provide")
- call fld_list_add(fldsToOcn,"ice_fraction" , "will provide")
+ call fld_list_add(fldsToOcn,"ice_fraction" , "will provide")
! Fields from OCN
call fld_list_add(fldsFrOcn,"ocean_mask" , "cannot provide","conservedst")
@@ -689,9 +729,8 @@
call fld_list_add(fldsToIce,"air_density_height_lowest" , "will provide")
! Fields from ICE
- call fld_list_add(fldsFrIce,"dummyfield" , "cannot provide","bilinear")
+! call fld_list_add(fldsFrIce,"dummyfield" , "cannot provide","bilinear")
call fld_list_add(fldsFrIce,"ice_mask" , "cannot provide","conservedst")
-! call fld_list_add(fldsFrIce,"sea_ice_temperature" , "will provide","bilinear")
call fld_list_add(fldsFrIce,"sea_ice_temperature" , "will provide","conservefrac")
call fld_list_add(fldsFrIce,"inst_ice_ir_dir_albedo" , "will provide","conservefrac")
call fld_list_add(fldsFrIce,"inst_ice_ir_dif_albedo" , "will provide","conservefrac")
@@ -1481,11 +1520,9 @@
type(ESMF_DistGrid) :: distgrid
type(ESMF_DistGridConnection), allocatable :: connectionList(:)
- integer :: dimCount, tileCount, petCount
+ integer :: dimCount, tileCount
integer :: connectionCount
- integer :: deCountPTile, extraDEs
integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:)
- integer, allocatable :: regDecompPTile(:,:)
integer :: i, j, n, n1, fieldCount, nxg
character(ESMF_MAXSTR),allocatable :: fieldNameList(:)
character(ESMF_MAXSTR) :: transferAction
@@ -1529,17 +1566,19 @@
if (dbug_flag > 1) then
call ESMF_LogWrite(trim(subname)//trim(string)//": accept grid for "//trim(fieldNameList(n)), ESMF_LOGMSG_INFO, rc=dbrc)
endif
- ! while this is still an empty field, it does now hold a Grid with DistGrid
+
+ ! this is still an empty field, but holds a Grid with DistGrid
call ESMF_FieldGet(field, grid=grid, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+ ! diagnostic print
call Grid_Print(grid,trim(fieldNameList(n))//'_orig',rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- ! access localDeCount to show this is a real Grid
- call ESMF_GridGet(grid, localDeCount=localDeCount, distgrid=distgrid, rc=rc)
+ ! access the DistGrid inside the Grid
+ call ESMF_GridGet(grid, distgrid=distgrid, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -1563,86 +1602,39 @@
maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
-
- ! construct a default regDecompPTile -> TODO: move this into ESMF as default
- call ESMF_GridCompGet(gcomp, petCount=petCount, rc=rc)
+
+ ! create the new DistGrid with the same minIndexPTile and
+ ! maxIndexPTile, but with default multi-tile regDecomp: 1DE/PET
+ distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, &
+ maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
-
- allocate(regDecompPTile(dimCount, tileCount))
- deCountPTile = petCount/tileCount
- extraDEs = max(0, petCount-deCountPTile)
- do i=1, tileCount
- if (i<=extraDEs) then
- regDecompPTile(1, i) = deCountPTile + 1
- else
- regDecompPTile(1, i) = deCountPTile
- endif
- do j=2, dimCount
- regDecompPTile(j, i) = 1
- enddo
- enddo
-
-!--- tcraig, hardwire i direction wraparound, temporary
-!--- tcraig, now getting info from model distgrid, see above
-! allocate(connectionList(1))
-! nxg = maxIndexPTile(1,1) - minIndexPTile(1,1) + 1
-! write(msgstring,*) trim(subname)//trim(string),': connlist nxg = ',nxg
-! call ESMF_LogWrite(trim(msgstring), ESMF_LOGMSG_INFO, rc=rc)
-! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
-! line=__LINE__, file=__FILE__)) return ! bail out
-! call ESMF_DistGridConnectionSet(connectionList(1), tileIndexA=1, &
-! tileIndexB=1, positionVector=(/nxg, 0/), rc=rc)
-! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
-! line=__LINE__, file=__FILE__)) return ! bail out
-
- ! create the new DistGrid with the same minIndexPTile and maxIndexPTile,
- ! but with a default regDecompPTile
-! tcraig, force connectionlist and gridEdge arguments to fix wraparound
-! add XX to turn this off, remove XX to turn this on.
-! need ESMF fixes to implement properly.
-! if (trim(string) == 'XXOcnImp' .or. trim(string) == 'XXOcnExp' .or. &
-! trim(string) == 'XXIceImp' .or. trim(string) == 'XXIceExp') then
- if (trim(string) == 'OcnImp' .or. trim(string) == 'OcnExp' .or. &
- trim(string) == 'AtmImp' .or. trim(string) == 'AtmExp' .or. &
- trim(string) == 'IceImp' .or. trim(string) == 'IceExp' .or. &
- trim(string) == 'XXLndImp' .or. trim(string) == 'XXLndExp' .or. &
- trim(string) == 'XXHydImp' .or. trim(string) == 'XXHydExp' ) then
- distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, &
- maxIndexPTile=maxIndexPTile, regDecompPTile=regDecompPTile, &
- connectionList=connectionList, rc=rc)
+ if (dbug_flag > 1) then
+ call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with connlist', ESMF_LOGMSG_INFO, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- if (dbug_flag > 1) then
- call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with connlist', ESMF_LOGMSG_INFO, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
- endif
- ! Create a new Grid on the new DistGrid and swap it in the Field
- grid = ESMF_GridCreate(distgrid, &
- gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/0,1/), rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
- else
- distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, &
- maxIndexPTile=maxIndexPTile, regDecompPTile=regDecompPTile, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
- if (dbug_flag > 1) then
- call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid without connlist', ESMF_LOGMSG_INFO, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
- endif
- ! Create a new Grid on the new DistGrid and swap it in the Field
- grid = ESMF_GridCreate(distgrid, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
endif
-
+
! local clean-up
- deallocate(connectionList)
- deallocate(minIndexPTile, maxIndexPTile, regDecompPTile)
+ deallocate(minIndexPTile, maxIndexPTile, connectionList)
+ ! Create a new Grid on the new DistGrid and swap it in the Field
+ grid = ESMF_GridCreate(distgrid, &
+ gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/0,1/), rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ ! check to ensure 1DE/PET condition is satisfied
+ call ESMF_GridGet(grid, localDeCount=localDeCount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ if (localDeCount /= 1) then
+ call ESMF_LogSetError(ESMF_RC_INTNRL_BAD, &
+ msg=SUBNAME//": Violation of 1 DE/PET condition in the Mediator",&
+ line=__LINE__, file=__FILE__, rcToReturn=rc)
+ return ! bail out
+ endif
+
! Swap all the Grids in the State
!tcx do n1=1, fieldCount
@@ -1706,6 +1698,7 @@
type(ESMF_RouteHandle) :: RH_mapmask ! unmasked conservative remapping
type(ESMF_Grid) :: gridAtmCoord, gridOcnCoord
integer(ESMF_KIND_I4), pointer :: dataPtr_arrayOcn(:,:), dataPtr_arrayIce(:,:)
+ integer(ESMF_KIND_I4), pointer :: dataPtr_arrayAtm(:,:)
real(ESMF_KIND_R8), pointer :: dataPtr_fieldOcn(:,:), dataPtr_fieldAtm(:,:)
logical :: isPresentOcn, isPresentIce
character(len=*),parameter :: subname='(module_MEDIATOR:InitializeIPDv03p5)'
@@ -1826,6 +1819,13 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
deallocate(fieldNameList)
+
+!jwtest
+! call ESMF_LogWrite("MED: before get fv3grid vtk", ESMF_LOGMSG_INFO, rc=rc)
+! call ESMF_GridWriteVTK(gridAtm, staggerloc=ESMF_STAGGERLOC_CENTER, &
+! filename='mediator_fv3Grid', rc=rc)
+! call ESMF_LogWrite("MED: aft get fv3grid vtk", ESMF_LOGMSG_INFO, rc=rc)
+
else
gridAtm = gridMed
endif
@@ -1941,7 +1941,167 @@
else
gridHyd = gridMed
endif
+!BL2017
+ !--- land mask
+ if (generate_landmask) then
+
+ call ESMF_GridGetItem(gridOcn, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresentOcn, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_GridGetItem(gridIce, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresentIce, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ if (isPresentOcn .or. isPresentIce) then
+
+ if (isPresentOcn .and. isPresentIce) then
+
+ ! ocn mask from ocn grid
+
+ call ESMF_GridGetItem(gridOcn, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=arrayOcn, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_GridGetItem(gridOcn, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, farrayPtr=dataPtr_arrayOcn, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_ArraySet(arrayOcn, name="ocean_mask", rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ write (msgString,*) trim(subname)//"ocn_mask raw = ",minval(dataPtr_arrayOcn),maxval(dataPtr_arrayOcn)
+ call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
+ call ESMF_ArrayWrite(arrayOcn, 'field_med_ocn_a_ocean_mask.nc', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ ! ice mask from ice grid
+
+ call ESMF_GridGetItem(gridIce, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=arrayIce, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_GridGetItem(gridIce, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, farrayPtr=dataPtr_arrayIce, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_ArraySet(arrayIce, name="ice_mask", rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ write (msgString,*) trim(subname)//"ice_mask raw = ",minval(dataPtr_arrayIce),maxval(dataPtr_arrayIce)
+ call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
+ call ESMF_ArrayWrite(arrayIce, 'field_med_ocn_a_ice_mask.nc', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ ! generate ocn grid with just coords, no mask or area
+ ! create ocn/ice mask field on ocn grid, coords only
+
+ call Grid_CreateCoords(gridOcnCoord, gridOcn, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ fieldOcn = ESMF_FieldCreate(gridOcnCoord, ESMF_TYPEKIND_R8, name='ocnice_mask', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_FieldGet(fieldOcn, farrayPtr=dataPtr_fieldOcn, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ ! generate atm grid with just coords, no mask or area
+ ! create land mask field on atm grid, coords only
+
+ call Grid_CreateCoords(gridAtmCoord, gridAtm, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ fieldAtm = ESMF_FieldCreate(gridAtmCoord, ESMF_TYPEKIND_R8, name='land_mask', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_FieldGet(fieldAtm, farrayPtr=dataPtr_FieldAtm, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ ! Here, the ocean/ice mask is the intersection of ocean and ice masks, which are integer fields of 0 or 1
+ ! Convert to real and make sure values are only 0 or 1.
+
+ do j = lbound(dataPtr_fieldOcn,2),ubound(dataPtr_fieldOcn,2)
+ do i = lbound(dataPtr_fieldOcn,1),ubound(dataPtr_fieldOcn,1)
+ dataPtr_fieldOcn(i,j) = min(dataPtr_arrayIce(i,j),dataPtr_arrayOcn(i,j))
+ if (dataPtr_fieldOcn(i,j) < 0.50_ESMF_KIND_R8) then
+ dataPtr_fieldOcn(i,j) = 0.0_ESMF_KIND_R8
+ else
+ dataPtr_fieldOcn(i,j) = 1.0_ESMF_KIND_R8
+ endif
+ enddo
+ enddo
+
+ ! generate a new RH from Atm and Ocn coords, no masks, no areas. Should not use o2a_consd mapping
+ ! because it has masks and area corrections.
+
+ call ESMF_FieldRegridStore(fieldOcn, fieldAtm, routehandle=RH_mapmask, &
+ regridmethod=ESMF_REGRIDMETHOD_CONSERVE, &
+ srcTermProcessing=srcTermProcessing_Value, &
+ ignoreDegenerate=.true., &
+ unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ ! regrid ocean mask from ocn to atm grid using unmasked conservative mapping
+
+ if (ESMF_RouteHandleIsCreated(RH_mapmask, rc=rc)) then
+ dataPtr_fieldAtm = 0.0_ESMF_KIND_R8
+ call ESMF_FieldRegrid(fieldOcn, fieldAtm, routehandle=RH_mapmask, &
+ termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_FieldRegridRelease(RH_mapmask, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ else
+ call ESMF_LogWrite(trim(subname)//": ERROR RH_mapmask not created", ESMF_LOGMSG_INFO, rc=rc)
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ endif
+
+ ! convert from ocean mask to land mask
+ ! check min/max
+ ! also fill "land_mask" array and save it for later
+
+ allocate(land_mask(lbound(dataPtr_fieldAtm,1):ubound(dataPtr_fieldAtm,1),lbound(dataPtr_fieldAtm,2):ubound(dataPtr_fieldAtm,2)))
+
+ do j = lbound(dataPtr_fieldAtm,2),ubound(dataPtr_fieldAtm,2)
+ do i = lbound(dataPtr_fieldAtm,1),ubound(dataPtr_fieldAtm,1)
+ dataPtr_fieldAtm(i,j) = 1.0_ESMF_KIND_R8 - dataPtr_fieldAtm(i,j)
+ if (dataPtr_fieldAtm(i,j) > 1.0_ESMF_KIND_R8) dataPtr_fieldAtm(i,j) = 1.0_ESMF_KIND_R8
+ if (dataPtr_fieldAtm(i,j) < 1.0e-6_ESMF_KIND_R8) dataPtr_fieldAtm(i,j) = 0.0_ESMF_KIND_R8
+ land_mask(i,j) = dataPtr_fieldAtm(i,j)
+ enddo
+ enddo
+
+ ! write out masks
+
+ call ESMF_FieldWrite(fieldOcn,'field_med_ocn_a_ocnice_mask.nc',overwrite=.true.,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+ write (msgString,*) trim(subname)//"ocean_mask = ",minval(dataPtr_fieldOcn),maxval(dataPtr_fieldOcn)
+ call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
+
+#ifndef FRONT_FV3
+ call ESMF_FieldWrite(fieldAtm,'field_med_atm_a_land_mask.nc',overwrite=.true.,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+ write (msgString,*) trim(subname)//"land_mask = ",minval(dataPtr_fieldAtm),maxval(dataPtr_fieldAtm)
+ call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
+#endif
+
+ ! clean up
+
+ call ESMF_GridDestroy(gridAtmCoord,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+ call ESMF_FieldDestroy(fieldAtm,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+ call ESMF_GridDestroy(gridOcnCoord,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+ call ESMF_FieldDestroy(fieldOcn,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
+
+ else ! isPresentOcn .and. isPresentIce
+ call ESMF_LogWrite(trim(subname)//": ABORT more support needed for Ocn or Ice mask", ESMF_LOGMSG_INFO, rc=rc)
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ endif
+
+ endif ! isPresentOcn .or. isPresentIce
+
+!BL2017b
+! call ESMF_GridGetItem(gridAtm, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, farrayPtr=dataPtr_arrayAtm, rc=rc)
+! do j = lbound(dataPtr_arrayAtm,2),ubound(dataPtr_arrayAtm,2)
+! do i = lbound(dataPtr_arrayAtm,1),ubound(dataPtr_arrayAtm,1)
+! dataPtr_arrayAtm(i,j) = 0 ! over ocean
+!! if (land_mask(i,j) >= 0.01_ESMF_KIND_R8) dataPtr_arrayAtm(i,j) =1_ESMF_KIND_I4
+! if (land_mask(i,j) >= 1.0e-6_ESMF_KIND_R8) dataPtr_arrayAtm(i,j) =1_ESMF_KIND_I4
+! enddo
+! enddo
+!BL2017
+ endif ! generate_landmask
+
+ if (dbug_flag > 5) then
+ call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
!----------------------------------------------------------
!--- Diagnose Grid Info
!----------------------------------------------------------
@@ -1975,9 +2135,11 @@
! dump the Grid coordinate arrays for reference
!----------------------------------------------------------
+#ifndef FRONT_FV3
call Grid_Write(gridAtm, 'array_med_atm', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
call Grid_Write(gridOcn, 'array_med_ocn', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -2027,11 +2189,21 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+ call fieldBundle_init(is_local%wrap%FBAtm2_o, grid=gridOcn, &
+ state=NState_AtmImp, name='FBAtm2_o', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
call fieldBundle_init(is_local%wrap%FBAtm_i, grid=gridIce, &
state=NState_AtmImp, name='FBAtm_i', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+ call fieldBundle_init(is_local%wrap%FBAtm2_i, grid=gridIce, &
+ state=NState_AtmImp, name='FBAtm2_i', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
call fieldBundle_init(is_local%wrap%FBAtm_l, grid=gridLnd, &
state=NState_AtmImp, name='FBAtm_l', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -2046,6 +2218,10 @@
call fieldBundle_init(is_local%wrap%FBOcn_a, grid=gridAtm, &
state=NState_OcnImp, name='FBOcn_a', rc=rc)
+!BL2017b
+ call fieldBundle_init(is_local%wrap%FBOcn2_a, grid=gridAtm, &
+ state=NState_OcnImp, name='FBOcn2_a', rc=rc)
+!BL2017b
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -2063,6 +2239,10 @@
call fieldBundle_init(is_local%wrap%FBIce_a, grid=gridAtm, &
state=NState_IceImp, name='FBIce_a', rc=rc)
+!BL2017b
+ call fieldBundle_init(is_local%wrap%FBIce2_a, grid=gridAtm, &
+ state=NState_IceImp, name='FBIce2_a', rc=rc)
+!BL2017b
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -2155,6 +2335,10 @@
call fieldBundle_init(is_local%wrap%FBAtmOcn_a, grid=gridAtm, &
fieldnamelist=fldsAtmOcn%shortname(1:fldsAtmOcn%num), name='FBAtmOcn_a', rc=rc)
+!BL2017b
+ call fieldBundle_init(is_local%wrap%FBAtmOcn2_a, grid=gridAtm, &
+ fieldnamelist=fldsAtmOcn%shortname(1:fldsAtmOcn%num), name='FBAtmOcn2_a', rc=rc)
+!BL2017b
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -2362,6 +2546,9 @@
consdmap=is_local%wrap%RH_a2o_consd, &
patchmap=is_local%wrap%RH_a2o_patch, &
fcopymap=is_local%wrap%RH_a2o_fcopy, &
+ nearestmap=is_local%wrap%RH_a2o_nearest, &
+! srcMaskValue=1, &
+ srcMaskValue=0, &
dstMaskValue=0, &
fldlist1=FldsFrAtm, string='a2o_weights', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -2375,6 +2562,9 @@
consdmap=is_local%wrap%RH_a2i_consd, &
patchmap=is_local%wrap%RH_a2i_patch, &
fcopymap=is_local%wrap%RH_a2i_fcopy, &
+ nearestmap=is_local%wrap%RH_a2i_nearest, &
+! srcMaskValue=1, &
+ srcMaskValue=0, &
dstMaskValue=0, &
fldlist1=FldsFrAtm, string='a2i_weights', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -2412,7 +2602,10 @@
consdmap=is_local%wrap%RH_o2a_consd, &
patchmap=is_local%wrap%RH_o2a_patch, &
fcopymap=is_local%wrap%RH_o2a_fcopy, &
+ nearestmap=is_local%wrap%RH_o2a_nearest, &
srcMaskValue=0, &
+! dstMaskValue=1, &
+ dstMaskValue=0, &
fldlist1=FldsFrOcn, fldlist2=FldsAtmOcn, string='o2a_weights', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -2438,7 +2631,10 @@
consdmap=is_local%wrap%RH_i2a_consd, &
patchmap=is_local%wrap%RH_i2a_patch, &
fcopymap=is_local%wrap%RH_i2a_fcopy, &
+ nearestmap=is_local%wrap%RH_i2a_nearest, &
srcMaskValue=0, &
+! dstMaskValue=1, &
+ dstMaskValue=0, &
fldlist1=FldsFrIce, string='i2a_weights', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -2505,149 +2701,6 @@
line=__LINE__, file=__FILE__)) return ! bail out
endif
- !--- land mask
-
- if (generate_landmask) then
-
- call ESMF_GridGetItem(gridOcn, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresentOcn, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_GridGetItem(gridIce, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresentIce, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- if (isPresentOcn .or. isPresentIce) then
-
- if (isPresentOcn .and. isPresentIce) then
-
- ! ocn mask from ocn grid
-
- call ESMF_GridGetItem(gridOcn, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=arrayOcn, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_GridGetItem(gridOcn, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, farrayPtr=dataPtr_arrayOcn, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_ArraySet(arrayOcn, name="ocean_mask", rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- write (msgString,*) trim(subname)//"ocn_mask raw = ",minval(dataPtr_arrayOcn),maxval(dataPtr_arrayOcn)
- call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
- call ESMF_ArrayWrite(arrayOcn, 'field_med_ocn_a_ocean_mask.nc', rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- ! ice mask from ice grid
-
- call ESMF_GridGetItem(gridIce, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=arrayIce, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_GridGetItem(gridIce, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, farrayPtr=dataPtr_arrayIce, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_ArraySet(arrayIce, name="ice_mask", rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- write (msgString,*) trim(subname)//"ice_mask raw = ",minval(dataPtr_arrayIce),maxval(dataPtr_arrayIce)
- call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
- call ESMF_ArrayWrite(arrayIce, 'field_med_ocn_a_ice_mask.nc', rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- ! generate ocn grid with just coords, no mask or area
- ! create ocn/ice mask field on ocn grid, coords only
-
- call Grid_CreateCoords(gridOcnCoord, gridOcn, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- fieldOcn = ESMF_FieldCreate(gridOcnCoord, ESMF_TYPEKIND_R8, name='ocnice_mask', rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_FieldGet(fieldOcn, farrayPtr=dataPtr_fieldOcn, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- ! generate atm grid with just coords, no mask or area
- ! create land mask field on atm grid, coords only
-
- call Grid_CreateCoords(gridAtmCoord, gridAtm, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- fieldAtm = ESMF_FieldCreate(gridAtmCoord, ESMF_TYPEKIND_R8, name='land_mask', rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_FieldGet(fieldAtm, farrayPtr=dataPtr_FieldAtm, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- ! Here, the ocean/ice mask is the intersection of ocean and ice masks, which are integer fields of 0 or 1
- ! Convert to real and make sure values are only 0 or 1.
-
- do j = lbound(dataPtr_fieldOcn,2),ubound(dataPtr_fieldOcn,2)
- do i = lbound(dataPtr_fieldOcn,1),ubound(dataPtr_fieldOcn,1)
- dataPtr_fieldOcn(i,j) = min(dataPtr_arrayIce(i,j),dataPtr_arrayOcn(i,j))
- if (dataPtr_fieldOcn(i,j) < 0.50_ESMF_KIND_R8) then
- dataPtr_fieldOcn(i,j) = 0.0_ESMF_KIND_R8
- else
- dataPtr_fieldOcn(i,j) = 1.0_ESMF_KIND_R8
- endif
- enddo
- enddo
-
- ! generate a new RH from Atm and Ocn coords, no masks, no areas. Should not use o2a_consd mapping
- ! because it has masks and area corrections.
-
- call ESMF_FieldRegridStore(fieldOcn, fieldAtm, routehandle=RH_mapmask, &
- regridmethod=ESMF_REGRIDMETHOD_CONSERVE, &
- srcTermProcessing=srcTermProcessing_Value, &
- ignoreDegenerate=.true., &
- unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
-
- ! regrid ocean mask from ocn to atm grid using unmasked conservative mapping
-
- if (ESMF_RouteHandleIsCreated(RH_mapmask, rc=rc)) then
- dataPtr_fieldAtm = 0.0_ESMF_KIND_R8
- call ESMF_FieldRegrid(fieldOcn, fieldAtm, routehandle=RH_mapmask, &
- termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- call ESMF_FieldRegridRelease(RH_mapmask, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- else
- call ESMF_LogWrite(trim(subname)//": ERROR RH_mapmask not created", ESMF_LOGMSG_INFO, rc=rc)
- call ESMF_Finalize(endflag=ESMF_END_ABORT)
- endif
-
- ! convert from ocean mask to land mask
- ! check min/max
- ! also fill "land_mask" array and save it for later
-
- allocate(land_mask(lbound(dataPtr_fieldAtm,1):ubound(dataPtr_fieldAtm,1),lbound(dataPtr_fieldAtm,2):ubound(dataPtr_fieldAtm,2)))
- do j = lbound(dataPtr_fieldAtm,2),ubound(dataPtr_fieldAtm,2)
- do i = lbound(dataPtr_fieldAtm,1),ubound(dataPtr_fieldAtm,1)
- dataPtr_fieldAtm(i,j) = 1.0_ESMF_KIND_R8 - dataPtr_fieldAtm(i,j)
- if (dataPtr_fieldAtm(i,j) > 1.0_ESMF_KIND_R8) dataPtr_fieldAtm(i,j) = 1.0_ESMF_KIND_R8
- if (dataPtr_fieldAtm(i,j) < 1.0e-6_ESMF_KIND_R8) dataPtr_fieldAtm(i,j) = 0.0_ESMF_KIND_R8
- land_mask(i,j) = dataPtr_fieldAtm(i,j)
- enddo
- enddo
-
- ! write out masks
-
- call ESMF_FieldWrite(fieldOcn,'field_med_ocn_a_ocnice_mask.nc',overwrite=.true.,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
- write (msgString,*) trim(subname)//"ocean_mask = ",minval(dataPtr_fieldOcn),maxval(dataPtr_fieldOcn)
- call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
-
- call ESMF_FieldWrite(fieldAtm,'field_med_atm_a_land_mask.nc',overwrite=.true.,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
- write (msgString,*) trim(subname)//"land_mask = ",minval(dataPtr_fieldAtm),maxval(dataPtr_fieldAtm)
- call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc)
-
- ! clean up
-
- call ESMF_GridDestroy(gridAtmCoord,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
- call ESMF_FieldDestroy(fieldAtm,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
- call ESMF_GridDestroy(gridOcnCoord,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
- call ESMF_FieldDestroy(fieldOcn,rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU,line=__LINE__, file=__FILE__)) return
-
- else ! isPresentOcn .and. isPresentIce
- call ESMF_LogWrite(trim(subname)//": ABORT more support needed for Ocn or Ice mask", ESMF_LOGMSG_INFO, rc=rc)
- call ESMF_Finalize(endflag=ESMF_END_ABORT)
- endif
-
- endif ! isPresentOcn .or. isPresentIce
-
- endif ! generate_landmask
-
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc)
endif
@@ -2661,7 +2714,8 @@
integer :: n, fieldCount
character(ESMF_MAXSTR),allocatable :: fieldNameList(:)
- character(ESMF_MAXSTR) :: transferAction
+ type(ESMF_FieldStatus_Flag) :: fieldStatus
+
character(len=*),parameter :: subname='(module_MEDIATOR:completeFieldInitialization)'
#ifndef NUOPC_DOES_SMART_GRID_TRANSFER
type(ESMF_Grid) :: grid
@@ -2687,12 +2741,12 @@
call ESMF_StateGet(State, field=field, itemName=fieldNameList(n), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- call NUOPC_GetAttribute(field, name="TransferActionGeomObject", &
- value=transferAction, rc=rc)
+
+ call ESMF_FieldGet(field, status=fieldStatus, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- if (trim(transferAction) == "accept") then
+ if (fieldStatus==ESMF_FIELDSTATUS_GRIDSET) then
if (dbug_flag > 1) then
call ESMF_LogWrite(subname//" is accepting grid for field "//trim(fieldNameList(n)), &
ESMF_LOGMSG_INFO, rc=rc)
@@ -2710,7 +2764,7 @@
call ESMF_FieldGet(field, grid=grid, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- elseif (trim(transferAction) == "accept-internal") then
+ else
if (dbug_flag > 1) then
call ESMF_LogWrite(subname//" is accepting INTERNAL grid for field "//trim(fieldNameList(n)), &
ESMF_LOGMSG_INFO, rc=rc)
@@ -3037,6 +3091,7 @@
type(ESMF_Field) :: field
type(InternalState) :: is_local
real(ESMF_KIND_R8), pointer :: dataPtr1(:,:),dataPtr2(:,:),dataPtr3(:,:),dataPtr4(:,:)
+ real(ESMF_KIND_R8), pointer :: dataPtr5(:,:)
real(ESMF_KIND_R8), pointer :: ifrac_i(:,:) ! ice fraction on ice grid
real(ESMF_KIND_R8), pointer :: ifrac_af(:,:), ifrac_afr(:,:) ! ice fraction on atm grid consf map
real(ESMF_KIND_R8), pointer :: ifrac_ad(:,:), ifrac_adr(:,:) ! ice fraction on atm grid consd map
@@ -3044,7 +3099,12 @@
real(ESMF_KIND_R8), pointer :: ifrac_ap(:,:), ifrac_apr(:,:) ! ice fraction on atm grid patch map
real(ESMF_KIND_R8), pointer :: ocnwgt(:,:),icewgt(:,:),customwgt(:,:)
integer :: i,j,n
+ integer :: regridwriteAtmExp_timeslice = 0
character(len=*),parameter :: subname='(module_MEDIATOR:MedPhase_prep_atm)'
+!BL2017b
+ character(ESMF_MAXSTR) ,pointer :: fieldNameList(:)
+ integer :: fieldCount
+!BL2017b
if(profile_memory) call ESMF_VMLogMemInfo("Entering "//trim(subname))
if (dbug_flag > 5) then
@@ -3125,6 +3185,11 @@
call fieldBundle_reset(is_local%wrap%FBLnd_a, value=czero, rc=rc)
call fieldBundle_reset(is_local%wrap%FBHyd_a, value=czero, rc=rc)
call fieldBundle_reset(is_local%wrap%FBAtmOcn_a, value=czero, rc=rc)
+!BL2017b
+ call fieldBundle_reset(is_local%wrap%FBOcn2_a, value=czero, rc=rc)
+ call fieldBundle_reset(is_local%wrap%FBIce2_a, value=czero, rc=rc)
+ call fieldBundle_reset(is_local%wrap%FBAtmOcn2_a, value=czero, rc=rc)
+!BL2017b
if (is_local%wrap%o2a_active) then
call Fieldbundle_Regrid(fldsFrOcn, is_local%wrap%FBOcn_o, is_local%wrap%FBOcn_a, &
@@ -3136,6 +3201,42 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+!BL2017b
+! use the nearest neighbor method
+ call Fieldbundle_Regrid2(fldsFrOcn, is_local%wrap%FBOcn_o, is_local%wrap%FBOcn2_a, &
+ nearestmap=is_local%wrap%RH_o2a_nearest, &
+ string='o2a_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldBundleGet(is_local%wrap%FBOcn_a, fieldCount=fieldCount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ allocate(fieldNameList(fieldCount))
+ call ESMF_FieldBundleGet(is_local%wrap%FBOcn_a, fieldNameList=fieldNameList, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n = 1, fieldCount
+ call FieldBundle_GetFldPtr(is_local%wrap%FBOcn_a, fieldNameList(n),dataPtr1,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBOcn2_a, fieldNameList(n), dataPtr2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do j=lbound(dataPtr1,2),ubound(dataPtr1,2)
+ do i=lbound(dataPtr1,1),ubound(dataPtr1,1)
+ if(dataPtr1(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr2(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr1(i,j)=dataPtr2(i,j)
+ endif
+ enddo
+ enddo
+ enddo
+ deallocate(fieldNameList)
+!BL2017b
+
call Fieldbundle_Regrid(fldsAtmOcn, is_local%wrap%FBAtmOcn_o, is_local%wrap%FBAtmOcn_a, &
consfmap=is_local%wrap%RH_o2a_consf, &
consdmap=is_local%wrap%RH_o2a_consd, &
@@ -3144,6 +3245,42 @@
string='o2aatmocn', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+
+!BL2017b
+! use the nearest neighbor method
+ call Fieldbundle_Regrid2(fldsAtmOcn, is_local%wrap%FBAtmOcn_o, is_local%wrap%FBAtmOcn2_a, &
+ nearestmap=is_local%wrap%RH_o2a_nearest, &
+ string='atmocn_o2a_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtmOcn_a, fieldCount=fieldCount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ allocate(fieldNameList(fieldCount))
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtmOcn_a, fieldNameList=fieldNameList, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n = 1, fieldCount
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtmOcn_a, fieldNameList(n),dataPtr1,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtmOcn2_a, fieldNameList(n), dataPtr2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do j=lbound(dataPtr1,2),ubound(dataPtr1,2)
+ do i=lbound(dataPtr1,1),ubound(dataPtr1,1)
+ if(dataPtr1(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr2(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr1(i,j)=dataPtr2(i,j)
+ endif
+ enddo
+ enddo
+ enddo
+ deallocate(fieldNameList)
+!BL2017b
endif
if (is_local%wrap%i2a_active) then
@@ -3153,11 +3290,30 @@
!--- need to compute weight by the frac mapped with the correct mapping
!--- first compute the ice fraction on the atm grid for all active mappings
+ !--- copy out the ifrac on ice grid
+
call FieldBundle_GetFldPtr(is_local%wrap%FBIce_i, 'ice_fraction', dataPtr1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
allocate(ifrac_i (lbound(dataPtr1,1):ubound(dataPtr1,1),lbound(dataPtr1,2):ubound(dataPtr1,2)))
+ do j=lbound(dataptr1,2),ubound(dataptr1,2)
+ do i=lbound(dataptr1,1),ubound(dataptr1,1)
+ ifrac_i(i,j) = dataPtr1(i,j)
+ enddo
+ enddo
+!BL2017b
+ !--- need to add the nearest neighbor regridding method here - B Li
+ call FieldBundle_FieldRegrid(is_local%wrap%FBIce_i,'ice_fraction', &
+ is_local%wrap%FBIce2_a,'ice_fraction', &
+ is_local%wrap%RH_i2a_nearest, rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce2_a,'ice_fraction', dataPtr5, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+!BL2017b
+
!--- conservative frac
if (ESMF_RouteHandleIsCreated(is_local%wrap%RH_i2a_consf, rc=rc)) then
call FieldBundle_FieldRegrid(is_local%wrap%FBIce_i,'ice_fraction', &
@@ -3166,20 +3322,23 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
- !--- copy out the ifrac on ice grid and ifrac on atm grid
+ !--- copy out the ifrac on atm grid
call FieldBundle_GetFldPtr(is_local%wrap%FBIce_a, 'ice_fraction', dataPtr2, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+ do j=lbound(dataPtr2,2),ubound(dataPtr2,2)
+ do i=lbound(dataPtr2,1),ubound(dataPtr2,1)
+ if(dataPtr2(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr5(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr2(i,j) = dataPtr5(i,j)
+ endif
+ enddo
+ enddo
+!BL2017b
+
allocate(ifrac_afr(lbound(dataptr2,1):ubound(dataptr2,1),lbound(dataptr2,2):ubound(dataptr2,2)))
allocate(ifrac_af (lbound(dataptr2,1):ubound(dataptr2,1),lbound(dataptr2,2):ubound(dataptr2,2)))
- do j=lbound(dataptr1,2),ubound(dataptr1,2)
- do i=lbound(dataptr1,1),ubound(dataptr1,1)
- ifrac_i(i,j) = dataPtr1(i,j)
- enddo
- enddo
-
do j=lbound(dataptr2,2),ubound(dataptr2,2)
do i=lbound(dataptr2,1),ubound(dataptr2,1)
!--- compute ice fraction on atm grid and reciprocal
@@ -3200,8 +3359,8 @@
is_local%wrap%RH_i2a_consd, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
-
- !--- copy out the ifrac on ice grid and ifrac on atm grid
+!BL2017b
+ !--- copy out the ifrac on atm grid
call FieldBundle_GetFldPtr(is_local%wrap%FBIce_a, 'ice_fraction', dataPtr2, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -3209,11 +3368,15 @@
allocate(ifrac_adr(lbound(dataptr2,1):ubound(dataptr2,1),lbound(dataptr2,2):ubound(dataptr2,2)))
allocate(ifrac_ad (lbound(dataptr2,1):ubound(dataptr2,1),lbound(dataptr2,2):ubound(dataptr2,2)))
- do j=lbound(dataptr1,2),ubound(dataptr1,2)
- do i=lbound(dataptr1,1),ubound(dataptr1,1)
- ifrac_i(i,j) = dataPtr1(i,j)
+!BL2017b
+ do j=lbound(dataptr2,2),ubound(dataptr2,2)
+ do i=lbound(dataptr2,1),ubound(dataptr2,1)
+ if(dataPtr2(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr5(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr2(i,j) = dataPtr5(i,j)
+ endif
enddo
enddo
+!BL2017b
do j=lbound(dataptr2,2),ubound(dataptr2,2)
do i=lbound(dataptr2,1),ubound(dataptr2,1)
@@ -3227,7 +3390,10 @@
enddo
enddo
endif
-
+!BL2017b
+ !--- the bilinear and patch interpolation methods are currently not used
+ !--- for any export variables from ice model - B Li
+
!--- bilinear
if (ESMF_RouteHandleIsCreated(is_local%wrap%RH_i2a_bilnr, rc=rc)) then
call FieldBundle_FieldRegrid(is_local%wrap%FBIce_i,'ice_fraction', &
@@ -3303,11 +3469,11 @@
do n = 1,fldsFrIce%num
if (FieldBundle_FldChk(is_local%wrap%FBIce_i, fldsFrIce%shortname(n), rc=rc) .and. &
FieldBundle_FldChk(is_local%wrap%FBIce_if,fldsFrIce%shortname(n), rc=rc)) then
- call FieldBundle_GetFldPtr(is_local%wrap%FBIce_i , fldsFrIce%shortname(n), dataPtr3, rc=rc)
- call FieldBundle_GetFldPtr(is_local%wrap%FBIce_if, fldsFrIce%shortname(n), dataPtr4, rc=rc)
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce_i , fldsFrIce%shortname(n), dataPtr4, rc=rc)
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce_if, fldsFrIce%shortname(n), dataPtr3, rc=rc)
do j=lbound(dataptr3,2),ubound(dataptr3,2)
do i=lbound(dataptr3,1),ubound(dataptr3,1)
- dataPtr4(i,j) = dataPtr3(i,j) * ifrac_i(i,j)
+ dataPtr3(i,j) = dataPtr4(i,j) * ifrac_i(i,j)
enddo
enddo
endif
@@ -3323,6 +3489,13 @@
string='i2a', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+!BL2017b
+ call Fieldbundle_Regrid2(fldsFrIce, is_local%wrap%FBIce_if, is_local%wrap%FBIce2_a, &
+ nearestmap=is_local%wrap%RH_i2a_nearest, &
+ string='i2a_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+!BL2017b
!--- divide FBIce_a by ifrac_a, interpolated ice fraction
!--- actually multiply by reciprocal of ifrac_a, ifrac_ar
@@ -3330,6 +3503,16 @@
do n = 1,fldsFrIce%num
if (FieldBundle_FldChk(is_local%wrap%FBIce_a, fldsFrIce%shortname(n), rc=rc)) then
call FieldBundle_GetFldPtr(is_local%wrap%FBIce_a, fldsFrIce%shortname(n), dataPtr3, rc=rc)
+!BL2017b
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce2_a, fldsFrIce%shortname(n), dataPtr4, rc=rc)
+ do j=lbound(dataptr3,2),ubound(dataptr3,2)
+ do i=lbound(dataptr3,1),ubound(dataptr3,1)
+ if(dataPtr3(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr4(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr3(i,j) = dataPtr4(i,j)
+ endif
+ enddo
+ enddo
+!BL2017b
if (fldsFrIce%mapping(n) == "conservefrac") then
do j=lbound(dataptr3,2),ubound(dataptr3,2)
do i=lbound(dataptr3,1),ubound(dataptr3,1)
@@ -3388,8 +3571,31 @@
string='i2a', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+
+ call Fieldbundle_Regrid2(fldsFrIce, is_local%wrap%FBIce_i, is_local%wrap%FBIce2_a, &
+ nearestmap=is_local%wrap%RH_i2a_nearest, &
+ string='i2a_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n = 1,fldsFrIce%num
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce_a, fldsFrIce%shortname(n), dataPtr3, rc=rc)
+ call FieldBundle_GetFldPtr(is_local%wrap%FBIce2_a, fldsFrIce%shortname(n), dataPtr4, rc=rc)
+ do j=lbound(dataPtr3,2),ubound(dataPtr3,2)
+ do i=lbound(dataPtr3,1),ubound(dataPtr3,1)
+ if(dataPtr3(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr4(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr3(i,j) = dataPtr4(i,j)
+ endif
+ enddo
+ enddo
+ enddo
endif
endif
+!BL2017b
+! call ESMF_FieldBundleWrite(is_local%wrap%FBIce2_a, 'fields_med_ice2.nc', &
+! singleFile=.true., overwrite=.true., timeslice=is_local%wrap%fastcntr, &
+! iofmt=ESMF_IOFMT_NETCDF, rc=rc)
+!BL2017b
if (is_local%wrap%l2a_active) then
call Fieldbundle_Regrid(fldsFrLnd, is_local%wrap%FBLnd_l, is_local%wrap%FBLnd_a, &
@@ -3433,6 +3639,7 @@
if (statewrite_flag) then
! write the fields imported from ocn to file
+#ifndef FRONT_FV3
call ESMF_FieldBundleWrite(is_local%wrap%FBOcn_a, 'fields_med_ocn_a.nc', &
singleFile=.true., overwrite=.true., timeslice=is_local%wrap%fastcntr, &
iofmt=ESMF_IOFMT_NETCDF, rc=rc)
@@ -3444,6 +3651,7 @@
iofmt=ESMF_IOFMT_NETCDF, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
endif
!---------------------------------------
@@ -3458,7 +3666,8 @@
allocate(ocnwgt(lbound(icewgt,1):ubound(icewgt,1),lbound(icewgt,2):ubound(icewgt,2)))
do j=lbound(icewgt,2),ubound(icewgt,2)
do i=lbound(icewgt,1),ubound(icewgt,1)
- ocnwgt = 1.0_ESMF_KIND_R8 - icewgt
+ ocnwgt(i,j) = 1.0_ESMF_KIND_R8 - icewgt(i,j)
+!BL2017 ocnwgt = 1.0_ESMF_KIND_R8 - icewgt
enddo
enddo
@@ -3470,9 +3679,11 @@
line=__LINE__, file=__FILE__)) return ! bail out
do j=lbound(dataPtr3,2),ubound(dataPtr3,2)
do i=lbound(dataPtr3,1),ubound(dataPtr3,1)
- dataPtr3(i,j) = land_mask(i,j)
+! dataPtr3(i,j) = land_mask(i,j)
+ dataPtr3(i,j) = 1.0_ESMF_KIND_R8
enddo
enddo
+!BL2017b
else
call ESMF_LogWrite(trim(subname)//": ERROR generate_landmask must be true ", ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__, rc=dbrc)
rc = ESMF_FAILURE
@@ -3545,6 +3756,15 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+ if (statewrite_flag) then
+ regridwriteAtmExp_timeslice = regridwriteAtmExp_timeslice + 1
+ call ESMFPP_RegridWriteFB(is_local%wrap%FBforAtm, "med_to_atm_export_", regridwriteAtmExp_timeslice, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+ endif
+
if (dbug_flag > 1) then
call state_diagnose(NState_AtmExp, trim(subname)//' AtmExp_final ', rc=rc)
endif
@@ -3551,6 +3771,7 @@
if (statewrite_flag) then
! write the fields exported to atm to file
+#ifndef FRONT_FV3
call NUOPC_Write(NState_AtmExp, &
fldsToAtm%shortname(1:fldsToAtm%num), &
"field_med_to_atm_", timeslice=is_local%wrap%fastcntr, &
@@ -3557,6 +3778,7 @@
relaxedFlag=.true., rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
endif
!---------------------------------------
@@ -3568,6 +3790,114 @@
endif
if(profile_memory) call ESMF_VMLogMemInfo("Leaving "//trim(subname))
+ contains !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ subroutine ESMFPP_RegridWriteFB(FieldBundle, fileName, timeslice, rc)
+ type(ESMF_FieldBundle), intent(in) :: fieldBundle
+ character(len=*), intent(in) :: fileName
+ integer, intent(in) :: timeslice
+ integer, intent(out) :: rc
+
+ ! local
+ type(ESMF_Field) :: field
+ type(ESMF_Grid) :: outGrid
+ integer :: icount
+ character(64), allocatable :: itemNameList(:)
+ !PT unused! type(ESMF_StateItem_Flag), allocatable :: typeList(:)
+
+ rc = ESMF_SUCCESS
+
+ outGrid = ESMF_GridCreate1PeriDimUfrm( &
+ maxIndex=(/180,360/), &
+ minCornerCoord=(/0.0_ESMF_KIND_R8,-90.0_ESMF_KIND_R8/), &
+ maxCornerCoord=(/360.0_ESMF_KIND_R8,90.0_ESMF_KIND_R8/), &
+ staggerLocList=(/ESMF_STAGGERLOC_CORNER, ESMF_STAGGERLOC_CENTER/), &
+ rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ call ESMF_FieldBundleGet(fieldBundle, fieldCount=icount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ allocate(itemNameList(icount))
+
+ call ESMF_FieldBundleGet(fieldBundle, fieldNameList=itemNameList, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ do i = 1, icount
+ call ESMF_LogWrite("RegridWrite Field Name Initiated: "//trim(itemNameList(i)), ESMF_LOGMSG_INFO)
+ call ESMF_FieldBundleGet(fieldBundle, fieldName=itemNameList(i), field=field, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+ call ESMFPP_RegridWrite(field, outGrid, ESMF_REGRIDMETHOD_BILINEAR, &
+ fileName//trim(itemNameList(i))//'.nc', timeslice, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+ call ESMF_LogWrite("RegridWrite Field Name done: "//trim(itemNameList(i)), ESMF_LOGMSG_INFO)
+ enddo
+
+ ! deallocate(typeList, itemNameList)
+ deallocate(itemNameList)
+
+ end subroutine ESMFPP_RegridWriteFB
+
+ subroutine ESMFPP_RegridWrite(inField, outGrid, regridMethod, fileName, timeslice, rc)
+
+ ! input arguments
+ type(ESMF_Field), intent(in) :: inField
+ type(ESMF_Grid), intent(in) :: outGrid
+ type(ESMF_RegridMethod_Flag), intent(in) :: regridMethod
+ character(len=*), intent(in) :: filename
+ integer, intent(in) :: timeslice
+ integer, intent(inout) :: rc
+
+ ! local arguments
+ type(ESMF_Routehandle) :: rh
+ type(ESMF_Field) :: outField
+
+ outField = ESMF_FieldCreate(outGrid, typekind=ESMF_TYPEKIND_R8, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ ! For other options for the regrid operation, please refer to:
+ ! http://www.earthsystemmodeling.org/esmf_releases/last_built/ESMF_refdoc/node5.html#SECTION050366000000000000000
+ call ESMF_FieldRegridStore(inField, outField, regridMethod=regridMethod, &
+ unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, &
+ Routehandle=rh, &
+ rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ call ESMF_FieldRegrid(inField, outField, Routehandle=rh, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ call ESMF_FieldWrite(outField, fileName, overwrite=.true., timeslice=timeslice, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, &
+ file=__FILE__)) &
+ return ! bail out
+
+ rc = ESMF_SUCCESS
+
+ end subroutine ESMFPP_RegridWrite
end subroutine MedPhase_prep_atm
!-----------------------------------------------------------------------------
@@ -3685,8 +4015,17 @@
real(ESMF_KIND_R8), pointer :: dataPtr1(:,:),dataPtr2(:,:),dataPtr3(:,:)
real(ESMF_KIND_R8), pointer :: temperature(:,:), humidity(:,:), pressure(:,:)
real(ESMF_KIND_R8), pointer :: air_density(:,:)
+ character(ESMF_MAXSTR) ,pointer :: fieldNameList(:)
+ integer :: fieldCount
integer :: i,j,n
character(len=*),parameter :: subname='(module_MEDIATOR:MedPhase_prep_ice)'
+!BL2018
+! real(ESMF_KIND_R8), pointer :: temp293(:,:)
+! type(ESMF_Grid) :: outGrid
+! type(ESMF_Field) :: outField
+! type(ESMF_Field) :: inField
+! type(ESMF_Routehandle) :: rh180
+!BL2018
if(profile_memory) call ESMF_VMLogMemInfo("Entering "//trim(subname))
if (dbug_flag > 5) then
@@ -3763,10 +4102,42 @@
call FieldBundle_diagnose(is_local%wrap%FBHyd_h, trim(subname)//' FBHyd_h ', rc=rc)
endif
+!BL2018
+! call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_a, 'inst_temp_height_lowest', temp293, rc=rc)
+! do j = lbound(temp293,2),ubound(temp293,2)
+! do i = lbound(temp293,1),ubound(temp293,1)
+! temp293(i,j) = 293.0_ESMF_KIND_R8
+! enddo
+! enddo
+ ! Regrid to lat-lon 180*360
+! call ESMF_FieldBundleGet(is_local%wrap%FBAtm_a,&
+! fieldName='inst_temp_height_lowest', &
+! field=inField,rc=rc)
+
+! outGrid = ESMF_GridCreate1PeriDimUfrm( &
+! maxIndex=(/180,360/), &
+! minCornerCoord=(/0.0_ESMF_KIND_R8,-90.0_ESMF_KIND_R8/), &
+! maxCornerCoord=(/360.0_ESMF_KIND_R8,90.0_ESMF_KIND_R8/), &
+! staggerLocList=(/ESMF_STAGGERLOC_CORNER, ESMF_STAGGERLOC_CENTER/), &
+! rc=rc)
+
+! outField = ESMF_FieldCreate(outGrid, typekind=ESMF_TYPEKIND_R8, rc=rc)
+! call ESMF_FieldRegridStore(inField, outField,&
+! regridMethod=ESMF_REGRIDMETHOD_BILINEAR,&
+! unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, &
+! Routehandle=rh180, &
+! rc=rc)
+! call ESMF_FieldRegrid(inField, outField, Routehandle=rh180, rc=rc)
+! call ESMF_FieldWrite(outField,'field_fv3_to_latlon.nc',overwrite=.true.,rc=rc)
+!BL2018
+
! Regrid Full Field Bundles conservatively
call fieldBundle_reset(is_local%wrap%FBAtm_i, value=czero, rc=rc)
call fieldBundle_reset(is_local%wrap%FBOcn_i, value=czero, rc=rc)
+!BL2017
+ call fieldBundle_reset(is_local%wrap%FBAtm2_i, value=czero, rc=rc)
+!BL2017
if (is_local%wrap%a2i_active) then
call Fieldbundle_Regrid(fldsFrAtm, is_local%wrap%FBAtm_a, is_local%wrap%FBAtm_i, &
@@ -3777,6 +4148,41 @@
string='a2i', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+
+!BL2017 use nearest neighbor method
+ call Fieldbundle_Regrid2(fldsFrAtm, is_local%wrap%FBAtm_a, is_local%wrap%FBAtm2_i, &
+ nearestmap=is_local%wrap%RH_a2i_nearest, &
+ string='a2i_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtm_i, fieldCount=fieldCount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ allocate(fieldNameList(fieldCount))
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtm_i, fieldNameList=fieldNameList, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n = 1, fieldCount
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_i, fieldNameList(n),dataPtr1,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_i, fieldNameList(n), dataPtr2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do j=lbound(dataPtr1,2),ubound(dataPtr1,2)
+ do i=lbound(dataPtr1,1),ubound(dataPtr1,1)
+ if(dataPtr1(i,j).eq.0._ESMF_KIND_R8.and.abs(dataPtr2(i,j)).gt.0._ESMF_KIND_R8) then
+ dataPtr1(i,j)=dataPtr2(i,j)
+ endif
+ enddo
+ enddo
+ enddo
+ deallocate(fieldNameList)
+!BL2017
endif
if (is_local%wrap%o2i_active) then
@@ -4344,6 +4750,7 @@
if (statewrite_flag) then
! write the fields imported from atm to file
+#ifndef FRONT_FV3
call NUOPC_Write(NState_AtmImp, &
fldsFrAtm%shortname(1:fldsFrAtm%num), &
"field_med_from_atm_", timeslice=is_local%wrap%fastcntr, &
@@ -4350,6 +4757,7 @@
relaxedFlag=.true., rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
! write the fields imported from ice to file
call NUOPC_Write(NState_IceImp, &
@@ -4454,6 +4862,7 @@
type(ESMF_State) :: importState, exportState
type(InternalState) :: is_local
integer :: i,j,n
+ character(ESMF_MAXSTR) ,pointer :: fieldNameList(:)
real(ESMF_KIND_R8), pointer :: zbot(:,:),ubot(:,:),vbot(:,:),thbot(:,:), &
qbot(:,:),rbot(:,:),tbot(:,:), pbot(:,:)
real(ESMF_KIND_R8), pointer :: us (:,:),vs (:,:),ts (:,:),mask(:,:)
@@ -4465,6 +4874,11 @@
real(ESMF_KIND_R8) :: us1 (1),vs1 (1),ts1 (1)
real(ESMF_KIND_R8) :: sen1 (1),lat1 (1),lwup1(1),evap1(1), &
taux1(1),tauy1(1),tref1(1),qref1(1),duu10n1(1)
+!BL2017
+ integer :: fieldCount
+ real(ESMF_KIND_R8), pointer :: zbot2(:,:),ubot2(:,:),vbot2(:,:)
+ real(ESMF_KIND_R8), pointer :: tbot2(:,:),pbot2(:,:),qbot2(:,:)
+!BL2017
character(len=*),parameter :: subname='(module_MEDIATOR:MedPhase_atm_ocn_flux)'
if (dbug_flag > 5) then
@@ -4510,6 +4924,10 @@
!---------------------------------------
call fieldBundle_reset(is_local%wrap%FBAtmOcn_o, value=czero, rc=rc)
+!BL2017
+ call fieldBundle_reset(is_local%wrap%FBAtm_o, value=czero, rc=rc)
+ call fieldBundle_reset(is_local%wrap%FBAtm2_o, value=czero, rc=rc)
+!BL2017
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
@@ -4524,12 +4942,90 @@
consfmap=is_local%wrap%RH_a2o_consf, &
consdmap=is_local%wrap%RH_a2o_consd, &
bilnrmap=is_local%wrap%RH_a2o_bilnr, &
- patchmap=is_local%wrap%RH_a2o_patch, &
+! patchmap=is_local%wrap%RH_a2o_patch, &
string='a2oflx', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+!BL2017 use nearest neighbor method
+ call FieldBundle_Regrid2(fldsFrAtm, is_local%wrap%FBAtm_a, is_local%wrap%FBAtm2_o, &
+ nearestmap=is_local%wrap%RH_a2o_nearest, &
+ string='a2oflx_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtm_o, fieldCount=fieldCount, rc=rc)
+
+ allocate(fieldNameList(fieldCount))
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_height_lowest', zbot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_height_lowest', zbot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+! write(msgString,'(A,3g14.7)') trim(subname)//':'//trim(fieldNameList(1)), &
+! minval(zbot2),maxval(zbot2),sum(zbot2)
+! call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO, rc=dbrc)
+
+! write(msgString,'(A,3g14.7)') trim(subname)//':'//trim(fieldNameList(1)), &
+! minval(zbot),maxval(zbot),sum(zbot)
+! call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO, rc=dbrc)
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_temp_height_lowest', tbot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_temp_height_lowest', tbot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_zonal_wind_height_lowest', ubot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_zonal_wind_height_lowest',ubot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_merid_wind_height_lowest', vbot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_merid_wind_height_lowest',vbot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_pres_height_lowest', pbot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_pres_height_lowest', pbot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_spec_humid_height_lowest', qbot, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, 'inst_spec_humid_height_lowest',qbot2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do j=lbound(zbot,2),ubound(zbot,2)
+ do i=lbound(zbot,1),ubound(zbot,1)
+ if(tbot(i,j).eq.0._ESMF_KIND_R8.and.abs(tbot2(i,j)).gt.0._ESMF_KIND_R8) then
+ zbot(i,j)=zbot2(i,j)
+ tbot(i,j)=tbot2(i,j)
+ ubot(i,j)=ubot2(i,j)
+ vbot(i,j)=vbot2(i,j)
+ qbot(i,j)=qbot2(i,j)
+ pbot(i,j)=pbot2(i,j)
endif
+ enddo
+ enddo
+ deallocate(fieldNameList)
+!BL2017
+ endif
call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, 'inst_height_lowest', zbot, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -4710,9 +5206,12 @@
type(InternalState) :: is_local
integer :: i,j,n
character(ESMF_MAXSTR) :: fieldname1(10),fieldname2(10),fieldname3(10)
- real(ESMF_KIND_R8), pointer :: dataPtr1(:,:),dataPtr2(:,:),dataPtr3(:,:)
+! real(ESMF_KIND_R8), pointer :: dataPtr1(:,:),dataPtr2(:,:),dataPtr3(:,:)
real(ESMF_KIND_R8), pointer :: atmwgt(:,:),icewgt(:,:),customwgt(:,:)
real(ESMF_KIND_R8), pointer :: atmwgt1(:,:),icewgt1(:,:),wgtp01(:,:),wgtm01(:,:)
+ real(ESMF_KIND_R8), pointer :: tmp_n1(:,:),tmp_n2(:,:)
+ character(ESMF_MAXSTR) ,pointer :: fieldNameList(:)
+ integer :: fieldCount
logical :: checkOK, checkOK1, checkOK2
character(len=*),parameter :: subname='(module_MEDIATOR:MedPhase_prep_ocn)'
@@ -4817,8 +5316,39 @@
bilnrmap=is_local%wrap%RH_a2o_bilnr, &
patchmap=is_local%wrap%RH_a2o_patch, &
string='a2o', rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
- line=__LINE__, file=__FILE__)) return ! bail out
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+!BL2017 use nearest neighbor method
+ call FieldBundle_Regrid2(fldsFrAtm, is_local%wrap%FBaccumAtm, is_local%wrap%FBAtm2_o, &
+ nearestmap=is_local%wrap%RH_a2o_nearest, &
+ string='a2o_nearest', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtm_o, fieldCount=fieldCount, rc=rc)
+ allocate(fieldNameList(fieldCount))
+ call ESMF_FieldBundleGet(is_local%wrap%FBAtm_o, fieldNameList=fieldNameList, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n = 1, fieldCount
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm_o, fieldNameList(n), tmp_n1,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call FieldBundle_GetFldPtr(is_local%wrap%FBAtm2_o, fieldNameList(n), tmp_n2, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ do j=lbound(tmp_n1,2),ubound(tmp_n1,2)
+ do i=lbound(tmp_n1,1),ubound(tmp_n1,1)
+ if(tmp_n1(i,j).eq.0._ESMF_KIND_R8.and.abs(tmp_n2(i,j)).gt.0._ESMF_KIND_R8) then
+ tmp_n1(i,j)=tmp_n2(i,j)
+ endif
+ enddo
+ enddo
+ enddo
+ deallocate(fieldNameList)
+!BL2017
endif
if (is_local%wrap%i2o_active) then
@@ -5132,6 +5662,9 @@
endif
if(profile_memory) call ESMF_VMLogMemInfo("Leaving "//trim(subname))
+! call ESMF_LogWrite(trim(subname)//": tcx aborting", ESMF_LOGMSG_INFO, rc=dbrc)
+! call ESMF_Finalize(endflag=ESMF_END_ABORT)
+
end subroutine MedPhase_prep_ocn
!-----------------------------------------------------------------------------
@@ -5320,11 +5853,17 @@
call ESMF_GridCompGetInternalState(gcomp, is_local, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
-
+#ifdef FV3_CPLD
fname = trim(bfname)//'_FBaccumAtm_restart.nc'
+ call FieldBundle_RWFields_tiles(mode,fname,is_local%wrap%FBaccumAtm,read_rest_FBaccumAtm,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+#else
+ fname = trim(bfname)//'_FBaccumAtm_restart.nc'
call FieldBundle_RWFields(mode,fname,is_local%wrap%FBaccumAtm,read_rest_FBaccumAtm,rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
fname = trim(bfname)//'_FBaccumOcn_restart.nc'
call FieldBundle_RWFields(mode,fname,is_local%wrap%FBaccumOcn,read_rest_FBaccumOcn,rc=rc)
@@ -5351,10 +5890,17 @@
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#ifdef FV3_CPLD
fname = trim(bfname)//'_FBAtm_a_restart.nc'
+ call FieldBundle_RWFields_tiles(mode,fname,is_local%wrap%FBAtm_a,read_rest_FBAtm_a,rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+#else
+ fname = trim(bfname)//'_FBAtm_a_restart.nc'
call FieldBundle_RWFields(mode,fname,is_local%wrap%FBAtm_a,read_rest_FBAtm_a,rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
+#endif
if (mode == 'read') then
call fieldBundle_copy(NState_AtmImp, is_local%wrap%FBAtm_a, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
@@ -5522,10 +6068,109 @@
end subroutine FieldBundle_RWFields
+
+! This subroutine requires ESMFv8 - for coupled FV3
+#ifdef FV3_CPLD
+ subroutine FieldBundle_RWFields_tiles(mode,fname,FB,flag,rc)
+ character(len=*) :: mode
+ character(len=*) :: fname
+ type(ESMF_FieldBundle) :: FB
+ logical,optional :: flag
+ integer,optional :: rc
+
+ ! local variables
+ type(ESMF_Field) :: f(47)
+ type(ESMF_GridComp) :: IOComp
+ type(ESMF_Grid) :: gridFv3
+ character(len=ESMF_MAXSTR) :: name
+ character(len=ESMF_MAXSTR) :: fname_tile1
+ integer :: fieldcount, n
+ logical :: fexists
+ character(len=*),parameter :: subname='(module_MEDIATOR:FieldBundle_RWFields_tiles)'
+
+ rc = ESMF_SUCCESS
+ if (dbug_flag > 5) then
+ call ESMF_LogWrite(trim(subname)//trim(fname)//": called", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
+ if (mode == 'write') then
+ call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ write(msgString,*) trim(subname)//' fieldCount = ',fieldCount
+ call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO, rc=dbrc)
+
+ call fieldBundle_getFieldN(FB, 1, f(1), rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldGet(f(1), grid=gridFv3, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ IOComp = ESMFIO_Create(gridFv3, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call ESMF_LogWrite(trim(subname)//": write "//trim(fname), ESMF_LOGMSG_INFO, rc=dbrc)
+
+ do n=2, 47
+ call fieldBundle_getFieldN(FB, n, f(n), rc)
+ enddo
+
+ call ESMFIO_Write(IOComp, fname, f, filePath='./', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ elseif (mode == 'read') then
+ fname_tile1='mediator_FBAtm_a_restart.tile1.nc'
+ inquire(file=fname_tile1,exist=fexists)
+ if (fexists) then
+
+ call ESMF_LogWrite(trim(subname)//": read "//trim(fname)// &
+ "tile1-tile6", ESMF_LOGMSG_INFO, rc=dbrc)
+
+ call fieldBundle_getFieldN(FB, 1, f(1), rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ call ESMF_FieldGet(f(1), grid=gridFv3, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ IOComp = ESMFIO_Create(gridFv3, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ do n=2, 47
+ call fieldBundle_getFieldN(FB, n, f(n), rc)
+ enddo
+
+ call ESMFIO_Read(IOComp, fname, f, filePath='./', rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+
+ if (present(flag)) flag = .true.
+ endif
+ else
+ call ESMF_LogWrite(trim(subname)//": mode WARNING "//trim(fname)//" mode="//trim(mode), ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+! -- Finalize ESMFIO
+ call ESMFIO_Destroy(IOComp, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) call ESMF_Finalize()
+
+ if (dbug_flag > 5) then
+ call ESMF_LogWrite(trim(subname)//trim(fname)//": done", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
+ end subroutine FieldBundle_RWFields_tiles
+#endif
+
!-----------------------------------------------------------------------------
subroutine Compute_RHs(FBsrc, FBdst, bilnrmap, consfmap, consdmap, patchmap, fcopymap, &
- srcMaskValue, dstMaskValue, &
+ nearestmap, srcMaskValue, dstMaskValue, &
fldlist1, fldlist2, fldlist3, fldlist4, string, rc)
type(ESMF_FieldBundle) :: FBsrc
type(ESMF_FieldBundle) :: FBdst
@@ -5534,6 +6179,7 @@
type(ESMF_Routehandle),optional :: consdmap
type(ESMF_Routehandle),optional :: patchmap
type(ESMF_Routehandle),optional :: fcopymap
+ type(ESMF_Routehandle),optional :: nearestmap
integer ,optional :: srcMaskValue
integer ,optional :: dstMaskValue
type(fld_list_type) ,optional :: fldlist1
@@ -5547,16 +6193,14 @@
integer :: n
character(len=128) :: lstring
logical :: do_consf, do_consd, do_bilnr, do_patch, do_fcopy
+ logical :: do_nearest
integer :: lsrcMaskValue, ldstMaskValue
type(ESMF_Field) :: fldsrc, flddst
real(ESMF_KIND_R8), pointer :: factorList(:)
character(len=*),parameter :: subname='(module_MEDIATOR:Compute_RHs)'
-type(ESMF_VM):: vm
+ type(ESMF_VM):: vm
rc = ESMF_SUCCESS
- if (dbug_flag > 5) then
- call ESMF_LogWrite(trim(subname)//trim(lstring)//": called", ESMF_LOGMSG_INFO, rc=dbrc)
- endif
if (present(string)) then
lstring = trim(string)
@@ -5564,6 +6208,10 @@
lstring = " "
endif
+ if (dbug_flag > 5) then
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": called", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
if (present(srcMaskValue)) then
lsrcMaskValue = srcMaskValue
else
@@ -5595,6 +6243,7 @@
do_consd = .true.
do_patch = .true.
do_fcopy = .true.
+ do_nearest = .true.
else
do_bilnr = .false.
do_consf = .false.
@@ -5601,8 +6250,8 @@
do_consd = .false.
do_patch = .false.
do_fcopy = .false.
+ do_nearest = .false.
endif
-
if (present(fldlist1)) then
do n = 1,fldlist1%num
if (fldlist1%mapping(n) == 'bilinear' ) do_bilnr = .true.
@@ -5648,6 +6297,7 @@
if (.not.present(consdmap)) do_consd = .false.
if (.not.present(patchmap)) do_patch = .false.
if (.not.present(fcopymap)) do_fcopy = .false.
+ if (present(nearestmap)) do_nearest = .true.
!---------------------------------------------------
!--- get single fields from bundles
@@ -5762,6 +6412,34 @@
call ESMF_LogWrite(trim(subname)//trim(lstring)//": failed RH consd", ESMF_LOGMSG_INFO, rc=dbrc)
endif
endif
+
+ !---------------------------------------------------
+ !--- nearest stod
+ !---------------------------------------------------
+
+ if (do_nearest) then
+ call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=nearestmap, &
+ srcMaskValues=(/lsrcMaskValue/), dstMaskValues=(/ldstMaskValue/), &
+ regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, &
+ srcTermProcessing=srcTermProcessing_Value, &
+ factorList=factorList, ignoreDegenerate=.true., &
+ unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ if (rhprint_flag) then
+ call NUOPC_Write(factorList, "array_med_"//trim(lstring)//"_nearest.nc", rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ call ESMF_RouteHandlePrint(nearestmap, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ endif
+ if (ESMF_RouteHandleIsCreated(nearestmap, rc=rc)) then
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": computed RH nearest", ESMF_LOGMSG_INFO, rc=dbrc)
+ else
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": failed RH nearest", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+ endif
!---------------------------------------------------
!--- patch
@@ -5876,7 +6554,6 @@
gridnew = ESMF_GridCreate(distgrid=distgrid, coordSys=coordSys, indexflag=indexflag, &
gridEdgeLWidth=gridEdgeLWidth, gridEdgeUWidth=gridEdgeUWidth, rc=rc)
-! rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
deallocate(gridEdgeLWidth, gridEdgeUWidth)
@@ -6383,7 +7060,7 @@
!-----------------------------------------------------------------------------
subroutine Fieldbundle_Regrid(fldlist, FBin, FBout, consfmap, consdmap, bilnrmap, patchmap, &
- fcopymap, string, rc)
+ fcopymap,string, rc)
type(fld_list_type) :: fldlist
type(ESMF_FieldBundle) :: FBin
type(ESMF_FieldBundle) :: FBout
@@ -6552,7 +7229,64 @@
end subroutine Fieldbundle_Regrid
!-----------------------------------------------------------------------------
+!BL2017
+ subroutine Fieldbundle_Regrid2(fldlist, FBin, FBout, &
+ nearestmap,string, rc)
+ type(fld_list_type) :: fldlist
+ type(ESMF_FieldBundle) :: FBin
+ type(ESMF_FieldBundle) :: FBout
+ type(ESMF_Routehandle),optional :: nearestmap
+ character(len=*) ,optional :: string
+ integer ,optional :: rc
+
+ ! local variables
+ integer :: n
+ character(len=64) :: lstring
+ logical :: oknearest
+ character(len=*),parameter :: subname='(module_MEDIATOR:Fieldbundle_Regrid2)'
+
+ rc = ESMF_SUCCESS
+ if (dbug_flag > 5) then
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": called", ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
+ if (present(string)) then
+ lstring = trim(string)
+ else
+ lstring = " "
+ endif
+
+ if (.not.present(rc)) then
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": ERROR rc expected", ESMF_LOGMSG_INFO, rc=rc)
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ endif
+
+ oknearest = .false.
+ if (present(nearestmap)) then
+ if (ESMF_RouteHandleIsCreated(nearestmap, rc=rc)) oknearest = .true.
+ endif
+
+ do n = 1,fldlist%num
+ if (FieldBundle_FldChk(FBin , fldlist%shortname(n), rc=rc) .and. &
+ FieldBundle_FldChk(FBout, fldlist%shortname(n), rc=rc)) then
+
+ if (dbug_flag > 1) then
+ call ESMF_LogWrite(trim(subname)//trim(lstring)//": map=neareststod"// &
+ ": fld="//trim(fldlist%shortname(n)), ESMF_LOGMSG_INFO, rc=dbrc)
+ endif
+
+ call FieldBundle_FieldRegrid(FBin ,fldlist%shortname(n), &
+ FBout,fldlist%shortname(n), &
+ nearestmap,rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
+ line=__LINE__, file=__FILE__)) return ! bail out
+ endif
+ enddo
+ end subroutine Fieldbundle_Regrid2
+!BL2017
+ !-----------------------------------------------------------------------------
+
subroutine FieldBundle_FieldRegrid(FBin,fldin,FBout,fldout,RH,rc)
! ----------------------------------------------
! Regrid a field in a field bundle to another field in a field bundle
@@ -7953,6 +8687,7 @@
if (present(mapping)) then
if (trim(mapping) /= "conservefrac" .and. trim(mapping) /= 'bilinear' .and. &
trim(mapping) /= 'conservedst' .and. &
+ trim(mapping) /= 'nearest' .and. &
trim(mapping) /= 'patch' .and. trim(mapping) /= 'copy') then
call ESMF_LogWrite(trim(subname)//": ERROR mapping not allowed "//trim(mapping), ESMF_LOGMSG_ERROR, rc=rc)
call ESMF_Finalize(endflag=ESMF_END_ABORT)
Index: checkout/src/makefile
===================================================================
--- checkout/src/makefile (revision 99852)
+++ checkout/src/makefile (revision 100116)
@@ -125,6 +125,15 @@
DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH))
DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS))
endif
+ifneq (,$(findstring $(COMMA)mom6$(COMMA),$(COMP)))
+ include $(mom6_mk)
+ DEP_FRONTS := $(DEP_FRONTS) -DFRONT_MOM6=$(ESMF_DEP_FRONT)
+ DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH))
+ DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS)
+ DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS)
+ DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH))
+ DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS))
+endif
ifneq (,$(findstring $(COMMA)pom$(COMMA),$(COMP)))
include $(pom_mk)
DEP_FRONTS := $(DEP_FRONTS) -DFRONT_POM=$(ESMF_DEP_FRONT)
Index: checkout/NEMSAppBuilder
===================================================================
--- checkout/NEMSAppBuilder (revision 99852)
+++ checkout/NEMSAppBuilder (revision 100116)
@@ -14,7 +14,7 @@
global_name='NEMSAppBuilder'
global_version='version 1.1.0'
-global_capabilities='autobuild dialog whiptail FV3 HYCOM MOM5 CICE IPE WRFHYDRO WW3 LIS IMP GSM NMMB KISS NOAH NOAHMP LegacyGSM LegacyNMM'
+global_capabilities='autobuild dialog whiptail FV3 HYCOM MOM5 MOM6 CICE IPE WRFHYDRO WW3 LIS IMP GSM NMMB KISS NOAH NOAHMP LegacyGSM LegacyNMM'
# determine whether dialog or whiptail is available
read dialog <<< "$(which dialog 2> /dev/null)"
@@ -905,6 +905,37 @@
fi
}
+build_mom6(){
+ #TODO: This component has a very non-standard way of building!!!!
+ #TODO: MOM6 and MOM_CAP should be merged into a single source tree,
+ #TODO: and building the CICE component in NUOPC mode should be done
+ #TODO: with standard target "nuopc". See HYCOM for an example.
+ #
+ # in: COMP, COMP_SRCDIR, COMP_BINDIR
+ if [[ $1"" == "clean" ]] ; then
+ echo "Cleaning $COMP..."
+ echo "Only partially implemented!!!"
+ cd $COMP_SRCDIR
+ rm -rf exec src/path_names_shared
+ find . -name '*.o' -o -name '*.mod' -o -name '*.a' | xargs rm -f
+ rm -f src/MOM6/config_src/nems_cap/mom5.mk.install
+ cd ..
+ echo "...done cleaning $COMP."
+ else
+ echo "Building $COMP..."
+ cd $COMP_SRCDIR
+ ./compile.sh --platform $MACHINE_ID
+ cd $COMP_SRCDIR/src/MOM6/config_src/nems_cap
+ echo "make -f makefile.nuopc VERSION=mom6 USER_CFLAGS=-DMOM6_CAP NEMSMOMDIR=$COMP_SRCDIR/exec/$MACHINE_ID INSTALLDIR=$COMP_BINDIR install"
+ make -f makefile.nuopc VERSION=mom6 USER_CFLAGS=-DMOM6_CAP NEMSMOMDIR=$COMP_SRCDIR/exec/$MACHINE_ID INSTALLDIR=$COMP_BINDIR install
+ if ([ ! -d "$COMP_BINDIR" ]); then
+ echo "...failed building $COMP."
+ else
+ echo "...done building $COMP."
+ fi
+ fi
+}
+
build_hycom(){
# in: COMP, COMP_SRCDIR, COMP_BINDIR
if [ "$MACHINE_ID" = linux_gnu ]; then
@@ -992,7 +1023,7 @@
local WW3_COMP=$FULL_MACHINE_ID
if ([ ! -f "$COMP_SRCDIR/bin/comp.$WW3_COMP" ]); then
local WW3_COMP='Intel'
- fi
+ fi
if [[ "$1" == "clean" ]] ; then
echo "Cleaning $COMP..."
cd "$COMP_SRCDIR/esmf"
@@ -1204,6 +1235,7 @@
SOCN="OCN: Stub Model" \
XOCN="OCN: Dead Model" \
MOM5="OCN: NOAA Modular Ocean Model 5" \
+ MOM6="OCN: NOAA Modular Ocean Model 6" \
HYCOM="OCN: HYbrid Coordinate Ocean Model" \
POM="OCN: Princeton Ocean Model" \
SWAV="WAV: Stub Model" \
@@ -1236,7 +1268,7 @@
# Need to find the associated appBuilder file
FOUNDAPP=false
for i in "${appbuilderlist[@]}" ; do
- if [[ $( basename $i ) =~ "$APP" ]] ; then
+ if [[ $( basename $i ) == "$APP.appBuilder" ]] ; then
source "$i"
echo "${COMPONENTS[@]}" >> $LOGFILE
FOUNDAPP=true
@@ -1416,6 +1448,8 @@
BUILD_FUNC=build_hycom
elif [[ ${COMPOS[0]} == "MOM5" ]] ; then
BUILD_FUNC=build_mom5
+ elif [[ ${COMPOS[0]} == "MOM6" ]] ; then
+ BUILD_FUNC=build_mom6
elif [[ ${COMPOS[0]} == "CICE" ]] ; then
BUILD_FUNC=build_cice
elif [[ ${COMPOS[0]} == "IPE" ]] ; then
@@ -1535,6 +1569,9 @@
elif [[ ${COMPOS[0]} == "MOM5" ]] ; then
COMP=$COMP",mom5"
COMPDIRS="$COMPDIRS MOM5_DIR=$MOM5_BINDIR"
+ elif [[ ${COMPOS[0]} == "MOM6" ]] ; then
+ COMP=$COMP",mom6"
+ COMPDIRS="$COMPDIRS MOM6_DIR=$MOM6_BINDIR"
# - actual wave model components
elif [[ ${COMPOS[0]} == "WW3" ]] ; then
COMP=$COMP",ww3"
--=_5ae0ef63.oomzj71SPlVTIonTUnBZLTfFZl0l/En67elrZg420g1Y82e8--
More information about the Ncep.list.nems.announce
mailing list