[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,"&amp;").replace(/</g,"&lt;").
+              replace(/\s+/g,"&nbsp;");
+}
+
+function cleanTest(text) {
+  return text.replace(/&/g,"&amp;").replace(/</g,"&lt;").
+      replace(/\s+/g,"&nbsp;").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)+'&nbsp;(age '+niceAge(rtStartTime)+')</p>'
+      +'<p>End time: '+niceTime(rtEndTime)+'&nbsp;(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,"&amp;").replace(/</g,"&lt;").
+              replace(/\s+/g,"&nbsp;");
+}
+
+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